[b]開-閉原則:[/b]
任何軟體在其生命週期內都會發生變化,如果我們期望開發出來的系統不會在第一版之後就被拋棄,就必須面對需求的變化而保持相對穩定.開-閉原則(the open-close principle)為我們提供了指引.
那什麼是開-閉原則呢?
軟體實體(模組,類,方法等)應該是可以擴充套件的,但是不可修改的.
這句話說出了軟體實體應該具備的兩個特徵:
1、對擴充套件式開放的(open for extension)
當需求變化時,我們可以對模組進行擴充套件,使其具有滿足新需求的新行為。
2、對於更改時封閉的(closed modification)
對模組進行擴充套件時,不能修改已有的源**或二進位制**。
這兩個方面似乎是矛盾的,我們怎麼才能無需對模組進行改動的情況下改變它的功能呢?
關鍵是抽象,我們可以把一組行為抽象出乙個介面/抽象類,而任意乙個可能的行為則表現為
可能的派生類。這個原則的直接結果產生了策略模式(strategy pattern),策略模式定義了
乙個演算法的介面,而其派生類則定義了不同的實現。當我們需要新的策略時,我們只需要重新
實現這個介面即可,而其他部分只依賴於這個介面,不依賴具體的實現。
下面我們看看乙個使用策略模式滿足開閉原則的例子:
[code]
public inte***ce sort
public class bubblesortimplements bubblesort
}[/code]
我們可能需要乙個效率更高的演算法,而bubblesort不能夠滿足我們的需求時,我們不需要修改原來的**,直接實現乙個新的演算法來擴充套件新的功能。
[code]
public class quicksortimplements bubblesort
}[/code]
而其他的**則只依賴於我們的sort介面:
[code]
class someclassusesort
[/code]
下面我們看看bob大叔舉的乙個違反ocp的例子:
繪製圖形的例子:
[code]
class shape{}
class circle extends shape{}
class square extends shape{}
class drawall }}
private void drawcircle()
private void drawsquare()
}[/code]
當我們需要繪製三角形時,我們需要在shapedraw中新增draw********方法
並且需要修改drawall方法,以便能夠繪製三角形。
這個例子違反了開閉原則,我們下面考慮如何重構這個例子:
[code]
class shape
class circle extends shape
}class square extends shape
}class drawall}}
[/code]
當我們怎加新的圖形時,我們只需要繼承shape並實現自己的draw方法即可,而無需
修改drawall類。這就是遵循開閉原則的威力。其實大部分違反開閉原則都是過程化
的思想所致,當你發現你的類中充斥著一連串的if語句時,基本上說它違反了開閉原則。
現在我們的**真的滿足開閉原則了麼?
那我們再看看吧,新的需求來了,要求我們按照形狀的順序來繪製圖形,我們現在的**
如果不作修改的話顯得無能為力了。
好的,那我們再抽象出drawall介面:
[code]
inte***ce drawall
class drawallbylistindex implements drawall}}
[/code]
這樣我們可以
[code]
class drawallbyshape implements drawall}}
[/code]
來擴充套件drawall就ok了。
就像我們開始抽象的那樣,我們根本沒有**到按照圖形順序繪製的需求,我們也不可能
每個東西都抽象出乙個介面,因為這樣會產生不必要的複雜性,有點過度設計的味道。所以
我們能做的只是去刺激需求,盡快地了解需求可能的變化,我們可以採用測試驅動的方法,首先構建乙個可測試的抽象,並且通常這個可測試的抽象會隔離以後可能要發生的其他種變化。
[b]結論[/b]
ocp可以說是物件導向設計的核心,遵循這個原則,可以使系統具有更好的靈活性、重用性和可維護性。但是如果肆無忌憚的使用這個原則,進行過度的抽象同樣不是好的做法。正確的做法是僅對頻繁發生變化的地方進行抽象,拒絕不成熟的抽象和抽象本身同樣重要。
物件導向 設計模式的四大原則
註明 下面都是我在學習 大話設計模式 做的筆記,為了傳播設計模式和自我提醒學習。1 單一職責原則 就乙個類而言,應該僅有乙個引起它變化的原因 如果乙個類承擔的職責過多,就等於把這些職責耦合在一起,乙個職責的變化可能會削弱或者抑制 這個類完成其他職責的能力。這種耦合會導致脆弱的設計,當變化發生時,設計...
設計模式(1) 物件導向的設計原則
hdis framework是乙個基於springboot kubernetes 阿里雲服務,編寫的乙個用於支撐微服務的極速開發框架。其文件詳盡,demo全面,設計合理,開箱即用,節省開發時間,提公升開發效率。配套的docker kubernetes教程已踩過各種坑,讓你的微服務無障礙的順暢執行起來...
遊戲設計模式 物件導向的設計原則
設計模式可以讓 結構更清晰,更嚴謹。面向的物件的設計原則 1.開閉原則 乙個軟體實體應該對外拓展開放,對內修改關閉。在不被修改的前提下被拓展。例如 在客戶端類中建立加法類,然後又想建立減法類可以一開始就建立運算類,可拓展性和可維護性很強。2.依賴倒轉原則 高層模組不應該依賴於低層模組,它們都應該依賴...