設(shè)計原則與思想:設(shè)計原則

對于單一職責(zé)原則,如何判定某個類的職責(zé)是否夠“單一”拍冠?

如何理解單一職責(zé)原則(SRP)?

一個類只負責(zé)完成一個職責(zé)或者功能簇抵。

也就是說庆杜,不要設(shè)計大而全的類,要設(shè)計粒度小碟摆、功能單一的類晃财。換個角度來講就是,一個類包含了兩個或者兩個以上業(yè)務(wù)不相干的功能典蜕,那我們就說它職責(zé)不夠單一断盛,應(yīng)該將它拆分成多個功能更加單一、粒度更細的類愉舔。

如何判斷類的職責(zé)是否足夠單一钢猛?

  • 類中的代碼行數(shù)、函數(shù)或者屬性過多轩缤;
  • 類依賴的其他類過多命迈,或者依賴類的其他類過多;
  • 私有方法過多火的;
  • 比較難給類起一個合適的名字壶愤;
  • 類中大量的方法都是集中操作類中的某幾個屬性。

類的職責(zé)是否設(shè)計得越單一越好馏鹤?

單一職責(zé)原則通過避免設(shè)計大而全的類征椒,避免將不相關(guān)的功能耦合在一起,來提高類的內(nèi)聚性湃累。同時勃救,類職責(zé)單一碍讨,類依賴的和被依賴的其他類也會變少,減少了代碼的耦合性剪芥,以此來實現(xiàn)代碼的高內(nèi)聚垄开、低耦合琴许。但是税肪,如果拆分得過細,實際上會適得其反榜田,反倒會降低內(nèi)聚性益兄,也會影響代碼的可維護性。

如何做到“對擴展開放箭券、修改關(guān)閉”净捅?擴展和修改各指什么?

如何理解“對擴展開放辩块、修改關(guān)閉”蛔六?

添加一個新的功能應(yīng)該是,在已有代碼基礎(chǔ)上擴展代碼(新增模塊废亭、類国章、方法等),而非修改已有代碼(修改模塊豆村、類液兽、方法等)。

關(guān)于定義掌动,我們有兩點要注意四啰。第一點是,開閉原則并不是說完全杜絕修改粗恢,而是以最小的修改代碼的代價來完成新功能的開發(fā)柑晒。第二點是,同樣的代碼改動眷射,在粗代碼粒度下匙赞,可能被認定為“修改”;在細代碼粒度下凭迹,可能又被認定為“擴展”罚屋。

如何做到“對擴展開放、修改關(guān)閉”嗅绸?

我們要時刻具備擴展意識脾猛、抽象意識、封裝意識鱼鸠。在寫代碼的時候猛拴,我們要多花點時間思考一下羹铅,這段代碼未來可能有哪些需求變更,如何設(shè)計代碼結(jié)構(gòu)愉昆,事先留好擴展點职员,以便在未來需求變更的時候,在不改動代碼整體結(jié)構(gòu)跛溉、做到最小代碼改動的情況下焊切,將新的代碼靈活地插入到擴展點上。

很多設(shè)計原則芳室、設(shè)計思想专肪、設(shè)計模式,都是以提高代碼的擴展性為最終目的的堪侯。特別是 23 種經(jīng)典設(shè)計模式嚎尤,大部分都是為了解決代碼的擴展性問題而總結(jié)出來的,都是以開閉原則為指導(dǎo)原則的伍宦。最常用來提高代碼擴展性的方法有:多態(tài)芽死、依賴注入、基于接口而非實現(xiàn)編程次洼,以及大部分的設(shè)計模式(比如关贵,裝飾、策略滓玖、模板坪哄、職責(zé)鏈、狀態(tài))势篡。

里式替換(LSP)跟多態(tài)有何區(qū)別翩肌?哪些代碼違背了LSP?

如何理解“里式替換原則”禁悠?

子類對象(object of subtype/derived class)能夠替換程序(program)中父類對象(object of base/parent class)出現(xiàn)的任何地方念祭,并且保證原來程序的邏輯行為(behavior)不變及正確性不被破壞。

哪些代碼明顯違背了LSP碍侦?

  1. 子類違背父類聲明要實現(xiàn)的功能
  2. 子類違背父類對輸入粱坤、輸出、異常的約定
  3. 子類違背父類注釋中所羅列的任何特殊說明

接口隔離原則有哪三種應(yīng)用瓷产?原則中的“接口”該如何理解站玄?

如何理解“接口隔離原則”?

接口的調(diào)用者或者使用者不應(yīng)該被強迫依賴它不需要的接口濒旦。

如果把“接口”理解為一組接口集合株旷,可以是某個微服務(wù)的接口,也可以是某個類庫的接口等。如果部分接口只被部分調(diào)用者使用晾剖,我們就需要將這部分接口隔離出來锉矢,單獨給這部分調(diào)用者使用,而不強迫其他調(diào)用者也依賴這部分不會被用到的接口齿尽。

如果把“接口”理解為單個 API 接口或函數(shù)沽损,部分調(diào)用者只需要函數(shù)中的部分功能,那我們就需要把函數(shù)拆分成粒度更細的多個函數(shù)循头,讓調(diào)用者只依賴它需要的那個細粒度函數(shù)绵估。

如果把“接口”理解為 OOP 中的接口,也可以理解為面向?qū)ο缶幊陶Z言中的接口語法贷岸。那接口的設(shè)計要盡量單一壹士,不要讓接口的實現(xiàn)類和調(diào)用者磷雇,依賴不需要的接口函數(shù)偿警。

接口隔離原則與單一職責(zé)原則的區(qū)別

單一職責(zé)原則針對的是模塊、類唯笙、接口的設(shè)計螟蒸。接口隔離原則相對于單一職責(zé)原則,一方面更側(cè)重于接口的設(shè)計崩掘,另一方面它的思考角度也是不同的七嫌。接口隔離原則提供了一種判斷接口的職責(zé)是否單一的標準:通過調(diào)用者如何使用接口來間接地判定。如果調(diào)用者只使用部分接口或接口的部分功能苞慢,那接口的設(shè)計就不夠職責(zé)單一诵原。

控制反轉(zhuǎn)、依賴反轉(zhuǎn)挽放、依賴注入绍赛,這三者有何區(qū)別和聯(lián)系?

控制反轉(zhuǎn)(IOC)

“控制”指的是對程序執(zhí)行流程的控制辑畦,“反轉(zhuǎn)”指的是在沒有使用框架之前吗蚌,程序員自己控制整個程序的執(zhí)行。在使用框架之后纯出,整個程序的執(zhí)行流程可以通過框架來控制蚯妇。流程的控制權(quán)從程序員“反轉(zhuǎn)”到了框架。

依賴注入(DI)

不通過 new() 的方式在類內(nèi)部創(chuàng)建依賴類對象暂筝,而是將依賴的類對象在外部創(chuàng)建好之后箩言,通過構(gòu)造函數(shù)、函數(shù)參數(shù)等方式傳遞(或注入)給類使用焕襟。

依賴注入框架(DI Framework)

通過依賴注入框架提供的擴展點陨收,簡單配置一下所有需要的類及其類與類之間依賴關(guān)系,就可以實現(xiàn)由框架來自動創(chuàng)建對象胧洒、管理對象的生命周期畏吓、依賴注入等原本需要程序員來做的事情墨状。

依賴反轉(zhuǎn)原則(DIP)

依賴反轉(zhuǎn)原則也叫作依賴倒置原則。這條原則跟控制反轉(zhuǎn)有點類似菲饼,主要用來指導(dǎo)框架層面的設(shè)計肾砂。高層模塊不依賴低層模塊,它們共同依賴同一個抽象宏悦。抽象不要依賴具體實現(xiàn)細節(jié)镐确,具體實現(xiàn)細節(jié)依賴抽象。

為何說KISS饼煞、YAGNI原則看似簡單源葫,卻經(jīng)常被用錯?

如何理解“KISS 原則”砖瞧?

KISS 原則:盡量保持簡單息堂。

YAGNI 跟 KISS 說的是一回事嗎?

YAGNI 原則:不要去設(shè)計當前用不到的功能块促;不要去編寫當前用不到的代碼瘟仿。實際上渠旁,這條原則的核心思想就是:不要做過度設(shè)計炕柔。

重復(fù)的代碼就一定違背DRY嗎象缀?如何提高代碼的復(fù)用性?

DRY 原則(Don’t Repeat Yourself)

DRY 原則:不要寫重復(fù)的代碼斋扰。

  • 實現(xiàn)邏輯重復(fù)
  • 功能語義重復(fù)
  • 代碼執(zhí)行重復(fù)

怎么提高代碼復(fù)用性(Code Reusability)渡八?

  • 減少代碼耦合
  • 滿足單一職責(zé)原則
  • 模塊化
  • 業(yè)務(wù)與非業(yè)務(wù)邏輯分離
  • 通用代碼下沉
  • 繼承、多態(tài)传货、抽象屎鳍、封裝
  • 應(yīng)用模板等設(shè)計模式

如何用迪米特法則(LOD)實現(xiàn)“高內(nèi)聚、松耦合”损离?

何為“高內(nèi)聚哥艇、松耦合”?

所謂高內(nèi)聚僻澎,就是指相近的功能應(yīng)該放到同一個類中貌踏,不相近的功能不要放到同一個類中。相近的功能往往會被同時修改窟勃,放到同一個類中祖乳,修改會比較集中,代碼容易維護秉氧。

所謂松耦合是說眷昆,在代碼中,類與類之間的依賴關(guān)系簡單清晰。即使兩個類有依賴關(guān)系亚斋,一個類的代碼改動不會或者很少導(dǎo)致依賴類的代碼改動作媚。

“高內(nèi)聚、松耦合”是一個非常重要的設(shè)計思想帅刊,能夠有效提高代碼的可讀性和可維護性纸泡,縮小功能改動導(dǎo)致的代碼改動范圍±德鳎“高內(nèi)聚”用來指導(dǎo)類本身的設(shè)計女揭,“松耦合”用來指導(dǎo)類與類之間依賴關(guān)系的設(shè)計。

“迪米特法則”理論描述

不該有直接依賴關(guān)系的類之間栏饮,不要有依賴吧兔;有依賴關(guān)系的類之間,盡量只依賴必要的接口(也就是定義中的“有限知識”)袍嬉。

迪米特法則是希望減少類之間的耦合境蔼,讓類越獨立越好。每個類都應(yīng)該少了解系統(tǒng)的其他部分冬竟。一旦發(fā)生變化欧穴,需要了解這一變化的類就會比較少。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末泵殴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子拼苍,更是在濱河造成了極大的恐慌笑诅,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疮鲫,死亡現(xiàn)場離奇詭異吆你,居然都是意外死亡,警方通過查閱死者的電腦和手機俊犯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門妇多,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人燕侠,你說我怎么就攤上這事者祖。” “怎么了绢彤?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵七问,是天一觀的道長。 經(jīng)常有香客問我茫舶,道長械巡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮讥耗,結(jié)果婚禮上有勾,老公的妹妹穿的比我還像新娘。我一直安慰自己古程,他們只是感情好柠衅,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著籍琳,像睡著了一般菲宴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上趋急,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天喝峦,我揣著相機與錄音,去河邊找鬼呜达。 笑死谣蠢,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的查近。 我是一名探鬼主播眉踱,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼霜威!你這毒婦竟也來了谈喳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤戈泼,失蹤者是張志新(化名)和其女友劉穎婿禽,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體大猛,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡扭倾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了挽绩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片膛壹。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖唉堪,靈堂內(nèi)的尸體忽然破棺而出模聋,到底是詐尸還是另有隱情,我是刑警寧澤巨坊,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布撬槽,位于F島的核電站,受9級特大地震影響趾撵,放射性物質(zhì)發(fā)生泄漏侄柔。R本人自食惡果不足惜共啃,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望暂题。 院中可真熱鬧移剪,春花似錦、人聲如沸薪者。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽言津。三九已至攻人,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間悬槽,已是汗流浹背怀吻。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留初婆,地道東北人蓬坡。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像磅叛,于是被迫代替她去往敵國和親屑咳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355