寂然解讀設計模式 - 開閉原則

I walk very slowly, but I never walk backwards 

設計模式原則 - 開閉原則


? 寂然

大家好,我是寂然~怔鳖,本節(jié)課呢杠河,我來給大家介紹設計模式原則之開閉原則,話不多說川背,我們直接進入正題,老規(guī)矩,首先帶大家了解一下開閉原則的官方定義,并作一個解釋次和,然后我們通過案例代碼來具體分析

官方定義

開閉原則( Open Close Principle ),又稱為OCP原則那伐,他的官方定義如下:

Software entities like classes,modules and functions should be open for extension but closed for modifications.

一個軟件實體如類踏施,模塊和函數(shù)應該對擴展開放,對修改關(guān)閉

基本介紹

對擴展開放指的是提供方罕邀,對修改關(guān)閉指的是調(diào)用方

一個軟件產(chǎn)品只要在生命周期內(nèi)畅形,都會發(fā)生變化,即然變化是一個事實诉探,我們就應該在設計時盡量適應這些變化日熬,以提高項目的穩(wěn)定性和靈活性,真正實現(xiàn)“擁抱變化”肾胯,開閉原則告訴我們應盡量通過擴展軟件實體的行為來實現(xiàn)變化竖席,而不是通過修改現(xiàn)有代碼來完成變化,它是針對軟件的未來事件而制定的對現(xiàn)行開發(fā)設計進行約束的一個原則

案例演示 - 繪圖工具

OK阳液,大家簡單了解過開閉原則后怕敬,我們來看如下一段代碼,幫助大家更深入的理解

有一個繪圖工具類帘皿,接收 Shape 對象东跪,然后根據(jù)不同的 type,來繪制不同的圖形鹰溜,具體代碼如下圖所示

//這是一個用于繪圖的類 [使用方]
class GraphicEditor {

    //接收 Shape 對象虽填,然后根據(jù)不同的 type,來繪制不同的圖形
    public void drawShape(Shape s) {
        if (s.m_type == 1) {
            drawRectangle(s);
        } else if (s.m_type == 2) {
            drawCircle(s);
        }
    }
    //繪制矩形
    public void drawRectangle(Shape r) {

        System.out.println(" 正在繪制矩形中---繪制成功 ");

    }
    //繪制圓形
    public void drawCircle(Shape r) {

        System.out.println(" 正在繪制圓形中---繪制成功");

    }
}

//Shape 類曹动,基類
class Shape {

    int m_type;
}

class Rectangle extends Shape {

    Rectangle() {
        super.m_type = 1;
    }
}
class Circle extends Shape {

    Circle() {
        super.m_type = 2;
    }

}

上面這段代碼首先是可以完成需求的斋日,OK,那現(xiàn)在我們新增繪制三角形的功能墓陈,大家想一下實現(xiàn)思路

首先我們要新增 Triangle 類恶守,然后新增繪制三角形的方法第献, drawShap()方法里添加判斷 并調(diào)用就Ok,新增代碼示例如下圖所示

//新增繪制三角形的子類
class Triangle extends Shape {
    Triangle() {
        super.m_type = 3;
    }
}
//類 GraphicEditor 中·添加判斷,type=3,繪制三角形
if (s.m_type == 1) {
    drawRectangle(s);
} else if (s.m_type == 2) {
    drawCircle(s);
} else if (s.m_type == 3) {
    drawTriangle(s); 
}

// 類 GraphicEditor 中新增繪制三角形的方法
public void drawTriangle(Shape r) {

    System.out.println(" 正在繪制三角形中---繪制成功 ");
}

案例分析

Ok兔港,上面的代碼是比較好理解的庸毫,但是大家想一下,針對上面的業(yè)務邏輯來說衫樊,類 GraphicEditor 扮演的其實是調(diào)用方的角色飒赃,但是出現(xiàn)了新增的需求后,我們對于 類 GraphicEditor 進行了一系列改動科侈,這顯然違背了ocp原則

因為我們上面提到载佳,ocp原則對調(diào)用方的修改是關(guān)閉的,那大家想一下臀栈,新增繪制三角形的功能蔫慧,我們還可以怎么樣實現(xiàn)呢?下面我們在滿足ocp原則的情況下挂脑,對上面的代碼進行重構(gòu)

解決方案

這時有的小伙伴說了藕漱,可以把創(chuàng)建 Shape 類做成抽象類,并提供一個抽象的 draw 方法崭闲,讓子類去實現(xiàn)即可肋联,這樣我們有新的圖形種類時,只需要讓新的圖形類繼承 Shape刁俭,并實現(xiàn) draw 方法即可橄仍,使用方的代碼就不需要修 改了,這樣既滿足了業(yè)務邏輯牍戚,又符合開閉原則侮繁,具體代碼示例如下

//這是一個用于繪圖的類 [使用方]
class GraphicEditor {

    //接收 Shape 對象,然后根據(jù)不同的 type如孝,來繪制不同的圖形
    public void drawShape(Shape s) {
        s.draw();
    }
}

//Shape變?yōu)槌橄箢愊芰ǎ⑻峁┏橄骴raw方法
abstract class Shape {

    int m_type;

    public abstract void draw();//抽象方法

}

class Rectangle extends Shape {

    Rectangle() {
        super.m_type = 1;
    }

    @Override
    public void draw() {
        System.out.println(" 正在繪制矩形中---繪制成功 ");
    }
}

class Circle extends Shape {

    Circle() {
        super.m_type = 2;
    }

    @Override
    public void draw() {
        System.out.println(" 正在繪制圓形中---繪制成功 ");
    }
}

OK,那這樣的話第晰,同樣還是上面的需求锁孟,我們新增繪制三角形的功能,那我們只需要新建一個 類Shape 的子類茁瘦,實現(xiàn)draw() 方法即可品抽,具體代碼示例如下

class Triangle extends Shape {

    Triangle() {
        super.m_type = 3;
    }

    @Override
    public void draw() {
        System.out.println(" 正在繪制三角形中---繪制成功 ");
    }
}

案例總結(jié)

通過上面的重構(gòu),我們可以看到甜熔,當我們新增繪制三角形的功能圆恤,不需要修改調(diào)用方,即本案例中扮演調(diào)用方角色的類 GraphicEditor 不需要修改腔稀,而是擴展了提供方的類盆昙,來完成需求羽历,就遵守了開閉原則,換句話說淡喜,開閉原則要求我們這樣做窄陡,即 針對提供方,對擴展開放拆火,針對調(diào)用方,對修改關(guān)閉

注意事項

  • 開閉原則是編程中最基礎(chǔ)涂圆,最重要的設計原則们镜,只要是面向?qū)ο缶幊坛固常陂_發(fā)時都會強調(diào)開閉原則
  • 開閉原則是最基礎(chǔ)的設計原則兑燥,其它的五個設計原則都是開閉原則的具體形態(tài),也就是說其它的五個設計原則是指導設計的工具和方法叫乌,而開閉原則才是其精神領(lǐng)袖踩衩。依照java語言的稱謂嚼鹉,開閉原則是抽象類,而其它的五個原則是具體的實現(xiàn)類

  • 開閉原則可以提高復用性和維護性

下節(jié)預告

OK驱富,下一節(jié)锚赤,我們正式進入設計模式原則之迪 米特法則的學習,我會為大家用多個案例分析褐鸥,來解讀設計模式原則之迪米特法則线脚,以及它的注意事項和細節(jié),最后叫榕,希望大家在學習的過程中浑侥,能夠感覺到設計模式的有趣之處,高效而愉快的學習晰绎,那我們下期見~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末寓落,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子荞下,更是在濱河造成了極大的恐慌伶选,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锄弱,死亡現(xiàn)場離奇詭異考蕾,居然都是意外死亡,警方通過查閱死者的電腦和手機会宪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門肖卧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人掸鹅,你說我怎么就攤上這事塞帐±乖” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵葵姥,是天一觀的道長荷鼠。 經(jīng)常有香客問我,道長榔幸,這世上最難降的妖魔是什么允乐? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮削咆,結(jié)果婚禮上牍疏,老公的妹妹穿的比我還像新娘。我一直安慰自己拨齐,他們只是感情好鳞陨,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瞻惋,像睡著了一般厦滤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上歼狼,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天掏导,我揣著相機與錄音,去河邊找鬼蹂匹。 笑死碘菜,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的限寞。 我是一名探鬼主播忍啸,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼履植!你這毒婦竟也來了计雌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤玫霎,失蹤者是張志新(化名)和其女友劉穎凿滤,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體庶近,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡翁脆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鼻种。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片反番。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出罢缸,到底是詐尸還是另有隱情篙贸,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布枫疆,位于F島的核電站爵川,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏息楔。R本人自食惡果不足惜寝贡,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望值依。 院中可真熱鬧兔甘,春花似錦、人聲如沸鳞滨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拯啦。三九已至,卻和暖如春熔任,著一層夾襖步出監(jiān)牢的瞬間褒链,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工疑苔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留甫匹,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓惦费,卻偏偏與公主長得像兵迅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子薪贫,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354