需要遵循的幾個(gè)開發(fā)原則

本文轉(zhuǎn)自博客園川蒙,點(diǎn)擊此處查看原文

在軟件開發(fā)中庙睡,前人對(duì)軟件系統(tǒng)的設(shè)計(jì)和開發(fā)總結(jié)了一些原則和模式, 不管用什么語(yǔ)言做開發(fā)揪漩,都將對(duì)我們系統(tǒng)設(shè)計(jì)和開發(fā)提供指導(dǎo)意義量窘。本文主要將總結(jié)這些常見的原則和具體闡述意義,常見的開發(fā)原則有如下幾種:

  • S:?jiǎn)我宦氊?zé)SRP
  • O:開放封閉原則OCP
  • L:里氏替換原則LSP
  • I:接口隔離法則
  • D:依賴倒置原則DIP
  • 合成/聚合復(fù)用原則
  • 迪米特法則

面向?qū)ο蟮幕驹瓌t(solid)是五個(gè)氢拥,但是在經(jīng)常被提到的除了這五個(gè)之外還有迪米特法則和合成復(fù)用原則等,所以在常見的文章中有表示寫六大或七大原則的锨侯; 除此之外我還將給出一些其它相關(guān)書籍和互聯(lián)網(wǎng)上出現(xiàn)的原則嫩海。

一、S單一職責(zé)SRP

Single-Responsibility Principle囚痴,一個(gè)類叁怪,最好只做一件事,只有一個(gè)引起它的變化深滚。單一職責(zé)原則可以看做是低耦合奕谭、高內(nèi)聚在面向?qū)ο笤瓌t的引申涣觉,將職責(zé)定義為引起變化的原因,以提高內(nèi)聚性減少引起變化的原因血柳。

1官册、定義

一個(gè)對(duì)象應(yīng)該只包含單一的職責(zé),并且該職責(zé)被完整地封裝在一個(gè)類中难捌。(Every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class.)膝宁,即又定義有且僅有一個(gè)原因使類變更。

2根吁、原則分析

一個(gè)類或者大到模塊员淫,小到方法,承擔(dān)的職責(zé)越多击敌,它被復(fù)用的可能性越小介返,而且如果一個(gè)類承擔(dān)的職責(zé)過多,就相當(dāng)于將這些職責(zé)耦合在一起沃斤,當(dāng)其中一個(gè)職責(zé)變化時(shí)圣蝎,可能會(huì)影響其他職責(zé)的運(yùn)作。

類的職責(zé)主要包括兩個(gè)方面:數(shù)據(jù)職責(zé)和行為職責(zé)轰枝,數(shù)據(jù)職責(zé)通過其屬性來(lái)體現(xiàn)捅彻,而行為職責(zé)通過其方法來(lái)體現(xiàn)。

單一職責(zé)原則是實(shí)現(xiàn)高內(nèi)聚鞍陨、低耦合的指導(dǎo)方針步淹,在很多代碼重構(gòu)手法中都能找到它的存在,它是最簡(jiǎn)單但又最難運(yùn)用的原則诚撵,需要設(shè)計(jì)人員發(fā)現(xiàn)類的不同職責(zé)并將其分離缭裆,而發(fā)現(xiàn)類的多重職責(zé)需要設(shè)計(jì)人員具有較強(qiáng)的分析設(shè)計(jì)能力和相關(guān)重構(gòu)經(jīng)驗(yàn)。

3寿烟、優(yōu)點(diǎn)

降低類的復(fù)雜性澈驼,類的職責(zé)清晰明確。比如數(shù)據(jù)職責(zé)和行為職責(zé)清晰明確筛武;

提高類的可讀性和維護(hù)性缝其;

變更引起的風(fēng)險(xiǎn)減低,變更是必不可少的徘六,如果接口的單一職責(zé)做得好内边,一個(gè)接口修改只對(duì)相應(yīng)的類有影響,對(duì)其他接口無(wú)影響待锈,這對(duì)系統(tǒng)的擴(kuò)展性漠其、維護(hù)性都有非常大的幫助。

注意:?jiǎn)我宦氊?zé)原則提出了一個(gè)編寫程序的標(biāo)準(zhǔn),用“職責(zé)”或“變化原因”來(lái)衡量接口或類設(shè)計(jì)得是否合理和屎,但是“職責(zé)”和“變化原因”都是沒有具體標(biāo)準(zhǔn)的拴驮,一個(gè)類到底要負(fù)責(zé)那些職責(zé)?這些職責(zé)怎么細(xì)化柴信?細(xì)化后是否都要有一個(gè)接口或類套啤?這些都需從實(shí)際的情況考慮。因項(xiàng)目而異颠印,因環(huán)境而異纲岭。

4、例子

SpringMVC中Entity线罕、DAO止潮、Service、Controller钞楼、Util等的分離喇闸。

二、O開放封閉原則OCP

Open - ClosedPrinciple询件,OCP對(duì)擴(kuò)展開放燃乍,對(duì)修改關(guān)閉(設(shè)計(jì)模式的核心原則)

1、定義

一個(gè)軟件實(shí)體(如類宛琅、模塊和函數(shù))應(yīng)該對(duì)擴(kuò)展開放刻蟹,對(duì)修改關(guān)閉。意思是在一個(gè)系統(tǒng)或者模塊中嘿辟,對(duì)于擴(kuò)展是開放的舆瘪,對(duì)于修改是關(guān)閉的。一個(gè) 好的系統(tǒng)是在不修改源代碼的情況下红伦,可以擴(kuò)展你的功能英古。而實(shí)現(xiàn)開閉原則的關(guān)鍵就是抽象化。

2昙读、原則分析

當(dāng)軟件實(shí)體因需求要變化時(shí), 盡量通過擴(kuò)展已有軟件實(shí)體召调,可以提供新的行為,以滿足對(duì)軟件的新的需求蛮浑,而不是修改已有的代碼唠叛,使變化中的軟件有一定的適應(yīng)性和靈活性 。已有軟件模塊沮稚,特別是最重要的抽象層模塊不能再修改玻墅,這使變化中的軟件系統(tǒng)有一定的穩(wěn)定性和延續(xù)性。

實(shí)現(xiàn)開閉原則的關(guān)鍵就是抽象化 :在"開-閉"原則中壮虫,不允許修改的是抽象的類或者接口,允許擴(kuò)展的是具體的實(shí)現(xiàn)類,抽象類和接口在"開-閉"原則中扮演著極其重要的角色..即要預(yù)知可能變化的需求.又預(yù)見所有可能已知的擴(kuò)展..所以在這里"抽象化"是關(guān)鍵!

可變性的封閉原則:找到系統(tǒng)的可變因素囚似,將它封裝起來(lái)剩拢。這是對(duì)"開-閉"原則最好的實(shí)現(xiàn)。不要把你的可變因素放在多個(gè)類中饶唤,或者散落在程序的各個(gè)角落徐伐。你應(yīng)該將可變的因素,封套起來(lái)..并且切忌不要把所用的可變因素封套在一起募狂。最好的解決辦法是办素,分塊封套你的可變因素!避免超大類祸穷、超長(zhǎng)類性穿、超長(zhǎng)方法的出現(xiàn)!!給你的程序增加藝術(shù)氣息,將程序藝術(shù)化是我們的目標(biāo)雷滚!

3需曾、例子

設(shè)計(jì)模式中模板方法模式和觀察者模式都是開閉原則的極好體現(xiàn)。

三祈远、L里氏替換原則LSP

Liskov Substitution Principle呆万,LSP:任何基類可以出現(xiàn)的地方,子類也可以出現(xiàn)车份;這一思想表現(xiàn)為對(duì)繼承機(jī)制的約束規(guī)范谋减,只有子類能夠替換其基類時(shí),才能夠保證系統(tǒng)在運(yùn)行期內(nèi)識(shí)別子類扫沼,這是保證繼承復(fù)用的基礎(chǔ)出爹。

1、定義

第一種定義方式相對(duì)嚴(yán)格:如果對(duì)每一個(gè)類型為S的對(duì)象o1充甚,都有類型為T的對(duì)象o2以政,使得以T定義的所有程序P在所有的對(duì)象o1都代換成o2時(shí),程序P的行為沒有變化伴找,那么類型S是類型T的子類型盈蛮。

第二種更容易理解的定義方式:所有引用基類(父類)的地方必須能透明地使用其子類的對(duì)象。即子類能夠必須能夠替換基類能夠從出現(xiàn)的地方技矮。子類也能在基類 的基礎(chǔ)上新增行為抖誉。
里氏代換原則由2008年圖靈獎(jiǎng)得主、美國(guó)第一位計(jì)算機(jī)科學(xué)女博士衰倦、麻省理工學(xué)院教授BarbaraLiskov和卡內(nèi)基.梅隆大學(xué)Jeannette Wing教授于1994年提出袒炉。其原文如下:Let q(x) be a property provableabout objects x of type T. Then q(y) should be true for objects y of type Swhere S is a subtype of T.

2、原則分析

講的是基類和子類的關(guān)系樊零,只有這種關(guān)系存在時(shí)我磁,里氏代換原則才存在孽文。正方形是長(zhǎng)方形是理解里氏代換原則的經(jīng)典例子。

里氏代換原則可以通俗表述為:在軟件中如果能夠使用基類對(duì)象夺艰,那么一定能夠使用其子類對(duì)象芋哭。把基類都替換成它的子類,程序?qū)⒉粫?huì)產(chǎn)生任何錯(cuò)誤和異常郁副,反過來(lái)則不成立减牺,如果一個(gè)軟件實(shí)體使用的是一個(gè)子類的話,那么它不一定能夠使用基類存谎。

里氏代換原則是實(shí)現(xiàn)開閉原則的重要方式之一拔疚,由于使用基類對(duì)象的地方都可以使用子類對(duì)象,因此在程序中盡量使用基類類型來(lái)對(duì)對(duì)象進(jìn)行定義既荚,而在運(yùn)行時(shí)再確定其子類類型稚失,用子類對(duì)象來(lái)替換父類對(duì)象。

四固以、I接口隔離法則

(Interface Segregation Principle墩虹,ISL):客戶端不應(yīng)該依賴那些它不需要的接口。(這個(gè)法則與迪米特法則是相通的)

1憨琳、定義

客戶端不應(yīng)該依賴那些它不需要的接口诫钓。

另一種定義方法:一旦一個(gè)接口太大,則需要將它分割成一些更細(xì)小的接口篙螟,使用該接口的客戶端僅需知道與之相關(guān)的方法即可菌湃。
注意,在該定義中的接口指的是所定義的方法遍略。例如外面調(diào)用某個(gè)類的public方法惧所。這個(gè)方法對(duì)外就是接口。

2绪杏、原則分析:

(1)接口隔離原則是指使用多個(gè)專門的接口下愈,而不使用單一的總接口。每一個(gè)接口應(yīng)該承擔(dān)一種相對(duì)獨(dú)立的角色蕾久,不多不少势似,不干不該干的事,該干的事都要干僧著。
? 一個(gè)接口就只代表一個(gè)角色履因,每個(gè)角色都有它特定的一個(gè)接口,此時(shí)這個(gè)原則可以叫做“角色隔離原則”盹愚。
? 接口僅僅提供客戶端需要的行為栅迄,即所需的方法,客戶端不需要的行為則隱藏起來(lái)皆怕,應(yīng)當(dāng)為客戶端提供盡可能小的單獨(dú)的接口毅舆,而不要提供大的總接口西篓。
(2)使用接口隔離原則拆分接口時(shí),首先必須滿足單一職責(zé)原則朗兵,將一組相關(guān)的操作定義在一個(gè)接口中污淋,且在滿足高內(nèi)聚的前提下,接口中的方法越少越好余掖。
(3)可以在進(jìn)行系統(tǒng)設(shè)計(jì)時(shí)采用定制服務(wù)的方式,即為不同的客戶端提供寬窄不同的接口礁鲁,只提供用戶需要的行為盐欺,而隱藏用戶不需要的行為。

五仅醇、D依賴倒置原則DIP

Dependency-Inversion Principle 要依賴抽象,而不要依賴具體的實(shí)現(xiàn), 具體而言就是高層模塊不依賴于底層模塊,二者共同依賴于抽象冗美。抽象不依賴于具體,具體依賴于抽象。

1析二、定義

高層模塊不應(yīng)該依賴低層模塊粉洼,它們都應(yīng)該依賴抽象。抽象不應(yīng)該依賴于細(xì)節(jié)叶摄,細(xì)節(jié)應(yīng)該依賴于抽象属韧。簡(jiǎn)單的說(shuō),依賴倒置原則要求客戶端依賴于抽象耦合蛤吓。原則表述:

(1)抽象不應(yīng)當(dāng)依賴于細(xì)節(jié)宵喂;細(xì)節(jié)應(yīng)當(dāng)依賴于抽象;

(2)要針對(duì)接口編程会傲,不針對(duì)實(shí)現(xiàn)編程锅棕。

2、原則分析

(1)如果說(shuō)開閉原則是面向?qū)ο笤O(shè)計(jì)的目標(biāo),依賴倒轉(zhuǎn)原則是到達(dá)面向設(shè)計(jì)"開閉"原則的手段..如果要達(dá)到最好的"開閉"原則,就要盡量的遵守依賴倒轉(zhuǎn)原則. 可以說(shuō)依賴倒轉(zhuǎn)原則是對(duì)"抽象化"的最好規(guī)范! 我個(gè)人感覺,依賴倒轉(zhuǎn)原則也是里氏代換原則的補(bǔ)充..你理解了里氏代換原則,再來(lái)理解依賴倒轉(zhuǎn)原則應(yīng)該是很容易的淌山。

(2)依賴倒轉(zhuǎn)原則的常用實(shí)現(xiàn)方式之一是在代碼中使用抽象類裸燎,而將具體類放在配置文件中。

(3)類之間的耦合:零耦合關(guān)系泼疑,具體耦合關(guān)系德绿,抽象耦合關(guān)系。依賴倒轉(zhuǎn)原則要求客戶端依賴于抽象耦合王浴,以抽象方式耦合是依賴倒轉(zhuǎn)原則的關(guān)鍵脆炎。

3、例子1

理解這個(gè)依賴倒置氓辣,首先我們需要明白依賴在面向?qū)ο笤O(shè)計(jì)的概念:
依賴關(guān)系(Dependency):是一種使用關(guān)系秒裕,特定事物的改變有可能會(huì)影響到使用該事物的其他事物抖部,在需要表示一個(gè)事物使用另一個(gè)事物時(shí)使用依賴關(guān)系酣栈。(假設(shè)A類的變化引起了B類的變化慢睡,則說(shuō)名B類依賴于A類。)大多數(shù)情況下兔乞,依賴關(guān)系體現(xiàn)在某個(gè)類的方法使用另一個(gè)類的對(duì)象作為參數(shù)。在UML中位隶,依賴關(guān)系用帶箭頭的虛線表示怨规,由依賴的一方指向被依賴的一方。

4弧烤、例子2

某系統(tǒng)提供一個(gè)數(shù)據(jù)轉(zhuǎn)換模塊忱屑,可以將來(lái)自不同數(shù)據(jù)源的數(shù)據(jù)轉(zhuǎn)換成多種格式,如可以轉(zhuǎn)換來(lái)自數(shù)據(jù)庫(kù)的數(shù)據(jù)(DatabaseSource)暇昂、也可以轉(zhuǎn)換來(lái)自文本文件的數(shù)據(jù)(TextSource)莺戒,轉(zhuǎn)換后的格式可以是XML文件(XMLTransformer)、也可以是XLS文件(XLSTransformer)等急波。

image

由于需求的變化从铲,該系統(tǒng)可能需要增加新的數(shù)據(jù)源或者新的文件格式,每增加一個(gè)新的類型的數(shù)據(jù)源或者新的類型的文件格式澄暮,客戶類MainClass都需要修改源代碼名段,以便使用新的類,但違背了開閉原則∑茫現(xiàn)使用依賴倒轉(zhuǎn)原則對(duì)其進(jìn)行重構(gòu)伸辟。

image

當(dāng)然根據(jù)具體的情況,也可以將AbstractSource注入到AbstractStransformer嗅定,依賴注入的方式有以下三種:

/**  * 依賴注入是依賴AbstractSource抽象注入的自娩,而不是具體  * DatabaseSource  *  */  abstract class AbstractStransformer {      private AbstractSource source;       /**      * 構(gòu)造注入(Constructor Injection):通過構(gòu)造函數(shù)注入實(shí)例變量。      */      public void AbstractStransformer(AbstractSource source){          this.source = source;               }      /**           * 設(shè)值注入(Setter Injection):通過Setter方法注入實(shí)例變量渠退。      * @param source : the sourceto set             */           public void setSource(AbstractSource source) {                    this.source = source;                 }      /**      * 接口注入(Interface Injection):通過接口方法注入實(shí)例變量忙迁。      * @param source      */      public void transform(AbstractSource source ) {            source.getSource();          System.out.println("Stransforming ...");        }      }

六、合成/聚合復(fù)用原則

(Composite/Aggregate ReusePrinciple 碎乃,CARP):要盡量使用對(duì)象組合姊扔,而不是繼承關(guān)系達(dá)到軟件復(fù)用的目的。

1梅誓、定義

經(jīng)常又叫做合成復(fù)用原則(Composite ReusePrinciple或CRP)恰梢,盡量使用對(duì)象組合,而不是繼承來(lái)達(dá)到復(fù)用的目的梗掰。

就是在一個(gè)新的對(duì)象里面使用一些已有的對(duì)象嵌言,使之成為新對(duì)象的一部分;新對(duì)象通過向這些對(duì)象的委派達(dá)到復(fù)用已有功能的目的及穗。簡(jiǎn)而言之摧茴,要盡量使用合成/聚合,盡量不要使用繼承埂陆。

2苛白、原則分析

(1)在面向?qū)ο笤O(shè)計(jì)中娃豹,可以通過兩種基本方法在不同的環(huán)境中復(fù)用已有的設(shè)計(jì)和實(shí)現(xiàn),即通過組合/聚合關(guān)系或通過繼承购裙。 繼承復(fù)用:實(shí)現(xiàn)簡(jiǎn)單懂版,易于擴(kuò)展。破壞系統(tǒng)的封裝性躏率;從基類繼承而來(lái)的實(shí)現(xiàn)是靜態(tài)的躯畴,不可能在運(yùn)行時(shí)發(fā)生改變,沒有足夠的靈活性薇芝;只能在有限的環(huán)境中使用私股。(“白箱”復(fù)用) 組合/聚合復(fù)用:耦合度相對(duì)較低,選擇性地調(diào)用成員對(duì)象的操作恩掷;可以在運(yùn)行時(shí)動(dòng)態(tài)進(jìn)行。(“黑箱”復(fù)用)
(2)組合/聚合可以使系統(tǒng)更加靈活供嚎,類與類之間的耦合度降低黄娘,一個(gè)類的變化對(duì)其他類造成的影響相對(duì)較少,因此一般首選使用組合/聚合來(lái)實(shí)現(xiàn)復(fù)用克滴;其次才考慮繼承逼争,在使用繼承時(shí),需要嚴(yán)格遵循里氏代換原則劝赔,有效使用繼承會(huì)有助于對(duì)問題的理解誓焦,降低復(fù)雜度,而濫用繼承反而會(huì)增加系統(tǒng)構(gòu)建和維護(hù)的難度以及系統(tǒng)的復(fù)雜度着帽,因此需要慎重使用繼承復(fù)用杂伟。
(3)此原則和里氏代換原則氏相輔相成的,兩者都是具體實(shí)現(xiàn)"開-閉"原則的規(guī)范。違反這一原則仍翰,就無(wú)法實(shí)現(xiàn)"開-閉"原則赫粥,首先我們要明白合成和聚合的概念:

注意:聚合和組合的區(qū)別是什么? 合成(組合):表示一個(gè)整體與部分的關(guān)系予借,指一個(gè)依托整體而存在的關(guān)系(整體與部分不可以分開)越平;比如眼睛和嘴對(duì)于頭來(lái)說(shuō)就是組合關(guān)系,沒有了頭就沒有眼睛和嘴灵迫,它們是不可分割的秦叛。在UML中,組合關(guān)系用帶實(shí)心菱形的直線表示瀑粥。 聚合:聚合是比合成關(guān)系的一種更強(qiáng)的依賴關(guān)系,也表示整體與部分的關(guān)系(整體與部分可以分開)挣跋;比如螺絲和汽車玩具的關(guān)系,螺絲脫離玩具依然可以用在其它設(shè)備之上利凑。在UML中浆劲,聚合關(guān)系用帶空心菱形的直線表示嫌术。

七、迪米特法則

(Law of Demeter牌借,LoD:系統(tǒng)中的類,盡量不要與其他類互相作用度气,減少類之間的耦合度。

1膨报、定義

又叫最少知識(shí)原則(Least Knowledge Principle或簡(jiǎn)寫為L(zhǎng)KP)幾種形式定義:

不要和“陌生人”說(shuō)話磷籍。英文定義為:Don't talk to strangers.

只與你的直接朋友通信。英文定義為:Talk only to your immediate friends.

每一個(gè)軟件單位對(duì)其他的單位都只有最少的知識(shí)现柠,而且局限于那些與本單位密切相關(guān)的軟件單位院领。

簡(jiǎn)單地說(shuō),也就是够吩,一個(gè)對(duì)象應(yīng)當(dāng)對(duì)其它對(duì)象有盡可能少的了解比然。一個(gè)類應(yīng)該對(duì)自己需要耦合或調(diào)用的類知道得最少,你(被耦合或調(diào)用的類)的內(nèi)部是如何復(fù)雜都和我沒關(guān)系周循,那是你的事情强法,我就知道你提供的public方法,我就調(diào)用這么多湾笛,其他的一概不關(guān)心饮怯。

2、法則分析

朋友類:在迪米特法則中嚎研,對(duì)于一個(gè)對(duì)象蓖墅,其朋友包括以下幾類:

(1) 當(dāng)前對(duì)象本身(this);

(2) 以參數(shù)形式傳入到當(dāng)前對(duì)象方法中的對(duì)象临扮;

(3) 當(dāng)前對(duì)象的成員對(duì)象论矾;

(4) 如果當(dāng)前對(duì)象的成員對(duì)象是一個(gè)集合,那么集合中的元素也都是朋友公条;

(5) 當(dāng)前對(duì)象所創(chuàng)建的對(duì)象拇囊。

任何一個(gè)對(duì)象,如果滿足上面的條件之一靶橱,就是當(dāng)前對(duì)象的“朋友”寥袭,否則就是“陌生人”。

3关霸、狹義法則和廣義法則: 在狹義的迪米特法則中传黄,如果兩個(gè)類之間不必彼此直接通信,那么這兩個(gè)類就不應(yīng)當(dāng)發(fā)生直接的相互作用队寇,如果其中的一個(gè)類需要調(diào)用另一個(gè)類的某一個(gè)方法的話膘掰,可以通過第三者轉(zhuǎn)發(fā)這個(gè)調(diào)用。

狹義的迪米特法則:可以降低類之間的耦合,但是會(huì)在系統(tǒng)中增加大量的小方法并散落在系統(tǒng)的各個(gè)角落识埋,它可以使一個(gè)系統(tǒng)的局部設(shè)計(jì)簡(jiǎn)化凡伊,因?yàn)槊恳粋€(gè)局部都不會(huì)和遠(yuǎn)距離的對(duì)象有直接的關(guān)聯(lián),但是也會(huì)造成系統(tǒng)的不同模塊之間的通信效率降低窒舟,使得系統(tǒng)的不同模塊之間不容易協(xié)調(diào)系忙。 廣義的迪米特法則:指對(duì)對(duì)象之間的信息流量、流向以及信息的影響的控制惠豺,主要是對(duì)信息隱藏的控制银还。信息的隱藏可以使各個(gè)子系統(tǒng)之間脫耦,從而允許它們獨(dú)立地被開發(fā)洁墙、優(yōu)化蛹疯、使用和修改,同時(shí)可以促進(jìn)軟件的復(fù)用热监,由于每一個(gè)模塊都不依賴于其他模塊而存在捺弦,因此每一個(gè)模塊都可以獨(dú)立地在其他的地方使用。一個(gè)系統(tǒng)的規(guī)模越大孝扛,信息的隱藏就越重要羹呵,而信息隱藏的重要性也就越明顯。

4疗琉、迪米特法則的主要用途:在于控制信息的過載。 在類的劃分上歉铝,應(yīng)當(dāng)盡量創(chuàng)建松耦合的類盈简,類之間的耦合度越低,就越有利于復(fù)用太示,一個(gè)處在松耦合中的類一旦被修改柠贤,不會(huì)對(duì)關(guān)聯(lián)的類造成太大波及;
在類的結(jié)構(gòu)設(shè)計(jì)上类缤,每一個(gè)類都應(yīng)當(dāng)盡量降低其成員變量和成員函數(shù)的訪問權(quán)限臼勉;
在類的設(shè)計(jì)上,只要有可能餐弱,一個(gè)類型應(yīng)當(dāng)設(shè)計(jì)成不變類宴霸;
在對(duì)其他類的引用上,一個(gè)對(duì)象對(duì)其他對(duì)象的引用應(yīng)當(dāng)降到最低膏蚓。

5瓢谢、例子

外觀模式Facade(結(jié)構(gòu)型)

迪米特法則與設(shè)計(jì)模式Facade模式、Mediator模式

系統(tǒng)中的類,盡量不要與其他類互相作用,減少類之間的耦合度,因?yàn)樵谀愕南到y(tǒng)中,擴(kuò)展的時(shí)候,你可能需要修改這些類,而類與類之間的關(guān)系,決定了修改的復(fù)雜度,相互作用越多,則修改難度就越大,反之,如果相互作用的越小,則修改起來(lái)的難度就越小..例如A類依賴B類,則B類依賴C類,當(dāng)你在修改A類的時(shí)候,你要考慮B類是否會(huì)受到影響,而B類的影響是否又會(huì)影響到C類. 如果此時(shí)C類再依賴D類的話,呵呵,我想這樣的修改有的受了驮瞧。

八氓扛、Q&A

1、面向?qū)ο笤O(shè)計(jì)其他原則论笔?

封裝變化采郎;

少用繼承多用組合千所;

針對(duì)接口編程、不針對(duì)實(shí)現(xiàn)編程蒜埋;

為交互對(duì)象之間的松耦合設(shè)計(jì)而努力淫痰;

類應(yīng)該對(duì)擴(kuò)展開發(fā)、對(duì)修改封閉(開閉OCP原則)理茎;

依賴抽象黑界,不要依賴于具體類(依賴倒置DIP原則);

密友原則:只和朋友交談(最少知識(shí)原則皂林,迪米特法則)朗鸠;

說(shuō)明:一個(gè)對(duì)象應(yīng)當(dāng)對(duì)其他對(duì)象有盡可能少的了解,將方法調(diào)用保持在界限內(nèi)础倍,只調(diào)用屬于以下范圍的方法: 該對(duì)象本身(本地方法)對(duì)象的組件 被當(dāng)作方法參數(shù)傳進(jìn)來(lái)的對(duì)象 此方法創(chuàng)建或?qū)嵗娜魏螌?duì)象烛占;

別找我(調(diào)用我) 我會(huì)找你(調(diào)用你)(好萊塢原則);

一個(gè)類只有一個(gè)引起它變化的原因(單一職責(zé)SRP原則)沟启;

2忆家、你能解釋一下里氏替換原則嗎?

嚴(yán)格定義:如果對(duì)每一個(gè)類型為S的對(duì)象o1,都有類型為T的對(duì)象o2德迹,使得以T定義的所有程序P在所有的對(duì)象用o1替換o2時(shí)芽卿,程序P的行為沒有變化,那么類型S是類型T的子類型胳搞。

通俗表述:所有引用基類(父類)的地方必須能透明地使用其子類的對(duì)象卸例。也就是說(shuō)子類可以擴(kuò)展父類的功能,但不能改變父類原有的功能肌毅。它包含以下4層含義:

  • 子類可以實(shí)現(xiàn)父類的抽象方法筷转,但不能覆蓋父類的非抽象方法。

  • 子類中可以增加自己特有的方法悬而。

  • 當(dāng)子類的方法重載父類的方法時(shí)呜舒,方法的前置條件(即方法的形參)要比父類方法的輸入?yún)?shù)更寬松。

  • 當(dāng)子類的方法實(shí)現(xiàn)父類的抽象方法時(shí)笨奠,方法的后置條件(即方法的返回值)要比父類更嚴(yán)格袭蝗。

3、什么情況下會(huì)違反迪米特法則般婆?為什么會(huì)有這個(gè)問題呻袭?

迪米特法則建議“只和朋友說(shuō)話,不要陌生人說(shuō)話”腺兴,以此來(lái)減少類之間的耦合左电。

4、給我一個(gè)符合開閉原則的設(shè)計(jì)模式的例子?

開閉原則要求你的代碼對(duì)擴(kuò)展開放篓足,對(duì)修改關(guān)閉段誊。這個(gè)意思就是說(shuō),如果你想增加一個(gè)新的功能栈拖,你可以很容易的在不改變已測(cè)試過的代碼的前提下增加新的代碼连舍。有好幾個(gè)設(shè)計(jì)模式是基于開閉原則的,如策略模式涩哟,如果你需要一個(gè)新的策略索赏,只需要實(shí)現(xiàn)接口,增加配置贴彼,不需要改變核心邏輯潜腻。一個(gè)正在工作的例子是 Collections.sort() 方法,這就是基于策略模式器仗,遵循開閉原則的融涣,你不需為新的對(duì)象修改 sort() 方法,你需要做的僅僅是實(shí)現(xiàn)你自己的 Comparator 接口精钮。

5威鹿、什么時(shí)候使用享元模式(蠅量模式)?

享元模式通過共享對(duì)象來(lái)避免創(chuàng)建太多的對(duì)象轨香。為了使用享元模式忽你,你需要確保你的對(duì)象是不可變的,這樣你才能安全的共享臂容。JDK 中 String 池檀夹、Integer 池以及 Long 池都是很好的使用了享元模式的例子。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末策橘,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子娜亿,更是在濱河造成了極大的恐慌丽已,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件买决,死亡現(xiàn)場(chǎng)離奇詭異沛婴,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)督赤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門嘁灯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人躲舌,你說(shuō)我怎么就攤上這事丑婿。” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵羹奉,是天一觀的道長(zhǎng)秒旋。 經(jīng)常有香客問我,道長(zhǎng)诀拭,這世上最難降的妖魔是什么迁筛? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮耕挨,結(jié)果婚禮上细卧,老公的妹妹穿的比我還像新娘。我一直安慰自己筒占,他們只是感情好贪庙,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著赋铝,像睡著了一般插勤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上革骨,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天农尖,我揣著相機(jī)與錄音,去河邊找鬼良哲。 笑死盛卡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的筑凫。 我是一名探鬼主播滑沧,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼巍实!你這毒婦竟也來(lái)了滓技?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤棚潦,失蹤者是張志新(化名)和其女友劉穎令漂,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丸边,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叠必,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了妹窖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纬朝。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖骄呼,靈堂內(nèi)的尸體忽然破棺而出共苛,到底是詐尸還是另有隱情判没,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布俄讹,位于F島的核電站哆致,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏患膛。R本人自食惡果不足惜摊阀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望踪蹬。 院中可真熱鬧胞此,春花似錦、人聲如沸跃捣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)疚漆。三九已至酣胀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間娶聘,已是汗流浹背闻镶。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留丸升,地道東北人铆农。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像狡耻,于是被迫代替她去往敵國(guó)和親墩剖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 設(shè)計(jì)模式概述 在學(xué)習(xí)面向?qū)ο笃叽笤O(shè)計(jì)原則時(shí)需要注意以下幾點(diǎn):a) 高內(nèi)聚夷狰、低耦合和單一職能的“沖突”實(shí)際上岭皂,這兩者...
    彥幀閱讀 3,752評(píng)論 0 14
  • 前言 關(guān)于設(shè)計(jì)模式六大設(shè)計(jì)原則的資料網(wǎng)上很多,但感覺很多地方解釋地都太過于籠統(tǒng)化沼头,特此再總結(jié)一波爷绘。 優(yōu)化第一步-單...
    ghroost閱讀 1,110評(píng)論 0 5
  • 單一職責(zé)原則 (SRP) 全稱 SRP , Single Responsibility Principle 單一職...
    米莉_L閱讀 1,769評(píng)論 2 5
  • 軟件開發(fā)是始于面向過程的 軟件開發(fā)是始于面向過程的,因?yàn)槊嫦蜻^程地解決問題更直接瘫证,軟件本身就是一個(gè)解決問題的過程;...
    侏羅紀(jì)猿閱讀 760評(píng)論 0 2
  • 早上八點(diǎn)半起床庄撮。昨天睡得很好背捌,很久沒睡這么好了。 因?yàn)榭戳撕?jiǎn)書推薦好文洞斯,像是找到了久違的好友毡庆,所以心情舒暢坑赡。 然后...
    敬哥閱讀 229評(píng)論 0 0