六大設(shè)計(jì)原則之開(kāi)閉原則(Open Close Principle)

定義

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.

即:一個(gè)軟件實(shí)體如類(lèi)、模塊和函數(shù)應(yīng)該對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉蛮位。

定義的解讀

  • 用抽象構(gòu)建框架,用實(shí)現(xiàn)擴(kuò)展細(xì)節(jié)葛账。
  • 不以改動(dòng)原有類(lèi)的方式來(lái)實(shí)現(xiàn)新需求闷营,而是應(yīng)該以實(shí)現(xiàn)事先抽象出來(lái)的接口(或具體類(lèi)繼承抽象類(lèi))的方式來(lái)實(shí)現(xiàn)霞幅。

優(yōu)點(diǎn)

實(shí)踐開(kāi)閉原則的優(yōu)點(diǎn)在于可以在不改動(dòng)原有代碼的前提下給程序擴(kuò)展功能娩脾。增加了程序的可擴(kuò)展性争拐,同時(shí)也降低了程序的維護(hù)成本。

代碼講解

下面通過(guò)一個(gè)簡(jiǎn)單的關(guān)于在線(xiàn)課程的例子講解一下開(kāi)閉原則的實(shí)踐晦雨。

需求點(diǎn)

設(shè)計(jì)一個(gè)在線(xiàn)課程類(lèi):

由于教學(xué)資源有限,開(kāi)始的時(shí)候只有類(lèi)似于博客的隘冲,通過(guò)文字講解的課程闹瞧。 但是隨著教學(xué)資源的增多,后來(lái)增加了視頻課程展辞,音頻課程以及直播課程奥邮。

先來(lái)看一下不好的設(shè)計(jì):

不好的設(shè)計(jì)

最開(kāi)始的文字課程類(lèi):

//================== Course.h ==================

@interface Course : NSObject

@property (nonatomic, copy) NSString *courseTitle;         //課程名稱(chēng)
@property (nonatomic, copy) NSString *courseIntroduction;  //課程介紹
@property (nonatomic, copy) NSString *teacherName;         //講師姓名
@property (nonatomic, copy) NSString *content;             //課程內(nèi)容

@end

Course類(lèi)聲明了最初的在線(xiàn)課程所需要包含的數(shù)據(jù):

  • 課程名稱(chēng)
  • 課程介紹
  • 講師姓名
  • 文字內(nèi)容

接著按照上面所說(shuō)的需求變更:增加了視頻,音頻罗珍,直播課程:

//================== Course.h ==================

@interface Course : NSObject

@property (nonatomic, copy) NSString *courseTitle;         //課程名稱(chēng)
@property (nonatomic, copy) NSString *courseIntroduction;  //課程介紹
@property (nonatomic, copy) NSString *teacherName;         //講師姓名
@property (nonatomic, copy) NSString *content;             //文字內(nèi)容

//新需求:視頻課程
@property (nonatomic, copy) NSString *videoUrl;

//新需求:音頻課程
@property (nonatomic, copy) NSString *audioUrl;

//新需求:直播課程
@property (nonatomic, copy) NSString *liveUrl;

@end

三種新增的課程都在原Course類(lèi)中添加了對(duì)應(yīng)的url洽腺。也就是每次添加一個(gè)新的類(lèi)型的課程,都在原有Course類(lèi)里面修改:新增這種課程需要的數(shù)據(jù)覆旱。

這就導(dǎo)致:我們從Course類(lèi)實(shí)例化的視頻課程對(duì)象會(huì)包含并不屬于自己的數(shù)據(jù):audioUrlliveUrl:這樣就造成了冗余蘸朋,視頻課程對(duì)象并不是純粹的視頻課程對(duì)象,它包含了音頻地址扣唱,直播地址等成員藕坯。

很顯然,這個(gè)設(shè)計(jì)不是一個(gè)好的設(shè)計(jì)噪沙,因?yàn)椋▽?duì)應(yīng)上面兩段敘述):

  1. 隨著需求的增加炼彪,需要反復(fù)修改之前創(chuàng)建的類(lèi)。
  2. 給新增的類(lèi)造成了不必要的冗余正歼。

之所以會(huì)造成上述兩個(gè)缺陷辐马,是因?yàn)樵撛O(shè)計(jì)沒(méi)有遵循對(duì)修改關(guān)閉,對(duì)擴(kuò)展開(kāi)放的開(kāi)閉原則局义,而是反其道而行之:開(kāi)放修改喜爷,而且不給擴(kuò)展提供便利冗疮。

難么怎么做可以遵循開(kāi)閉原則呢?下面看一下遵循開(kāi)閉原則的較好的設(shè)計(jì):

較好的設(shè)計(jì)

首先在Course類(lèi)中僅僅保留所有課程都含有的數(shù)據(jù):

//================== Course.h ==================

@interface Course : NSObject

@property (nonatomic, copy) NSString *courseTitle;         //課程名稱(chēng)
@property (nonatomic, copy) NSString *courseIntroduction;  //課程介紹
@property (nonatomic, copy) NSString *teacherName;         //講師姓名

接著贞奋,針對(duì)文字課程赌厅,視頻課程,音頻課程轿塔,直播課程這三種新型的課程采用繼承Course類(lèi)的方式特愿。而且繼承后,添加自己獨(dú)有的數(shù)據(jù):

文字課程類(lèi):

//================== TextCourse.h ==================

@interface TextCourse : Course

@property (nonatomic, copy) NSString *content;             //文字內(nèi)容

@end

視頻課程類(lèi):

//================== VideoCourse.h ==================

@interface VideoCourse : Course

@property (nonatomic, copy) NSString *videoUrl;            //視頻地址

@end

音頻課程類(lèi):

//================== AudioCourse.h ==================

@interface AudioCourse : Course

@property (nonatomic, copy) NSString *audioUrl;            //音頻地址

@end

直播課程類(lèi):

//================== LiveCourse.h ==================

@interface LiveCourse : Course

@property (nonatomic, copy) NSString *liveUrl;             //直播地址

@end

這樣一來(lái)勾缭,上面的兩個(gè)問(wèn)題都得到了解決:

  1. 隨著課程類(lèi)型的增加揍障,不需要反復(fù)修改最初的父類(lèi)(Course),只需要新建一個(gè)繼承于它的子類(lèi)并在子類(lèi)中添加僅屬于該子類(lèi)的數(shù)據(jù)(或行為)即可俩由。
  2. 因?yàn)楦鞣N課程獨(dú)有的數(shù)據(jù)(或行為)都被分散到了不同的課程子類(lèi)里毒嫡,所以每個(gè)子類(lèi)的數(shù)據(jù)(或行為)沒(méi)有任何冗余。

而且對(duì)于第二點(diǎn):或許今后的視頻課程可以有高清地址幻梯,視頻加速功能兜畸。而這些功能只需要在VideoCourse類(lèi)里添加即可,因?yàn)樗鼈兌际且曨l課程所獨(dú)有的碘梢。同樣地咬摇,直播課程后面還可以支持在線(xiàn)問(wèn)答功能,也可以?xún)H加在LiveCourse里面煞躬。

我們可以看到肛鹏,正是由于最初程序設(shè)計(jì)合理,所以對(duì)后面需求的增加才會(huì)處理得很好恩沛。

下面來(lái)看一下這兩個(gè)設(shè)計(jì)的UML 類(lèi)圖在扰,可以更形象地看出兩種設(shè)計(jì)上的區(qū)別:

UML 類(lèi)圖對(duì)比

未實(shí)踐開(kāi)閉原則:

實(shí)踐了開(kāi)閉原則:

在實(shí)踐了開(kāi)閉原則的 UML 類(lèi)圖中,四個(gè)課程類(lèi)繼承了Course類(lèi)并添加了自己獨(dú)有的屬性雷客。(在 UML 類(lèi)圖中:實(shí)線(xiàn)空心三角箭頭代表繼承關(guān)系:由子類(lèi)指向其父類(lèi))

如何實(shí)踐

為了更好地實(shí)踐開(kāi)閉原則芒珠,在設(shè)計(jì)之初就要想清楚在該場(chǎng)景里哪些數(shù)據(jù)(或行為)是一定不變(或很難再改變)的,哪些是很容易變動(dòng)的佛纫。將后者抽象成接口或抽象方法妓局,以便于在將來(lái)通過(guò)創(chuàng)造具體的實(shí)現(xiàn)應(yīng)對(duì)不同的需求。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末呈宇,一起剝皮案震驚了整個(gè)濱河市好爬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌甥啄,老刑警劉巖存炮,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡穆桂,警方通過(guò)查閱死者的電腦和手機(jī)宫盔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)享完,“玉大人灼芭,你說(shuō)我怎么就攤上這事“阌郑” “怎么了彼绷?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)茴迁。 經(jīng)常有香客問(wèn)我寄悯,道長(zhǎng),這世上最難降的妖魔是什么堕义? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任猜旬,我火速辦了婚禮,結(jié)果婚禮上倦卖,老公的妹妹穿的比我還像新娘洒擦。我一直安慰自己,他們只是感情好怕膛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布秘遏。 她就那樣靜靜地躺著,像睡著了一般嘉竟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上洋侨,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天舍扰,我揣著相機(jī)與錄音,去河邊找鬼希坚。 笑死边苹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的裁僧。 我是一名探鬼主播个束,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼聊疲!你這毒婦竟也來(lái)了茬底?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤获洲,失蹤者是張志新(化名)和其女友劉穎阱表,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡最爬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年涉馁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片爱致。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡烤送,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出糠悯,到底是詐尸還是另有隱情帮坚,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布逢防,位于F島的核電站叶沛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏忘朝。R本人自食惡果不足惜灰署,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望局嘁。 院中可真熱鬧溉箕,春花似錦、人聲如沸悦昵。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)但指。三九已至寡痰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間棋凳,已是汗流浹背拦坠。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留剩岳,地道東北人贞滨。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像拍棕,于是被迫代替她去往敵國(guó)和親晓铆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

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