Open Close Principle
動(dòng)機(jī)
開明的應(yīng)用設(shè)計(jì)和代碼模塊應(yīng)當(dāng)關(guān)注應(yīng)用在發(fā)展和維護(hù)階段中頻繁發(fā)生的變化如捅。通常抢埋,給應(yīng)用添加一個(gè)新功能的時(shí)候會(huì)涉及到很多改動(dòng)。應(yīng)盡量少地在已有代碼中做改動(dòng)缓溅,因?yàn)橐延写a一般都已通過單元測(cè)試惠昔,在其中做的改動(dòng)可能莫名其妙地就影響到現(xiàn)有功能。
開放 - 封閉原則 強(qiáng)調(diào)設(shè)計(jì)和代碼編寫應(yīng)當(dāng)以在現(xiàn)有代碼上改動(dòng)最小的方式來完成新功能的添加豹绪。軟件設(shè)計(jì)應(yīng)盡可能在添加新功能類的時(shí)候不去改動(dòng)現(xiàn)有代碼价淌。
目的
軟件實(shí)體,如類瞒津、模塊和函數(shù)蝉衣,應(yīng)當(dāng)對(duì)擴(kuò)展開放,但對(duì)修改關(guān)閉巷蚪。
個(gè)人理解:對(duì)使用方的修改關(guān)閉病毡, 對(duì)提供方的功能擴(kuò)展開放
例子
以下是一個(gè)違背 OCP 的例子。 它實(shí)現(xiàn)了繪制各種圖形的 graph editor
屁柏。 顯然啦膜,GraphicEditor
沒有遵循 OCP 有送,因?yàn)槊看翁砑右粋€(gè) shape
子類,都要對(duì)其進(jìn)行修改功戚。這有以下幾個(gè)缺點(diǎn):
- 每次添加新的
shape
子類娶眷,GraphicEditor
的單元測(cè)試都要重新做 - 每次添加新的
shape
子類所需時(shí)間都比較多,因?yàn)殚_發(fā)人員需要理解GraphicEditor
的內(nèi)部邏輯 - 盡管新添加的
shape
能很好的工作啸臀,但它可能會(huì)意外地影響現(xiàn)有功能
// Open-Close Principle - Bad Example
class GraphicEditor{
public void drawShape(Shape s){
if(s.m_type == 1)
drawRectangle(s);
else if(s.m_type == 2)
drawCircle(s);
}
public void drawRectangle(Rectangle r){...}
public void drawCircle(Circle r){...}
}
class Shape{
int m_type;
}
class Rectangle extends Shape{
Rectangle(){
super.m_type = 1;
}
}
class Circle extends Shape{
Circle(){
super.m_type = 2;
}
}
以下是一個(gè)遵循 OCP 要求的例子届宠。 在新的設(shè)計(jì)中,我們?cè)?GraphicEditor
中使用抽象的 draw()
方法乘粒,而將具體實(shí)現(xiàn)移至派生類實(shí)例中豌注。通過使用 OCP ,我們就避免了上述例子中的問題灯萍,當(dāng)添加新 shape
子類的時(shí)候轧铁, 不需要對(duì)GraphicEditor
進(jìn)行修改。
- 不需要額外的單元測(cè)試
- 不需要知曉
GraphicEditor
的源碼 - 由于具體的繪圖代碼移到具體的
shape
實(shí)現(xiàn)子類中旦棉,新功能添加進(jìn)來的時(shí)候免除了影響有功能的風(fēng)險(xiǎn)
// Open-Close Principle - Good example
class GraphicEditor{
public void drawShape(Shape s){
s.draw();
}
}
class Shape{
abstract void draw();
}
class Rectangle extends Shape{
@Override
public void draw(){
// draw Rectangle
}
}
class Circle extends Shape{
@Override
public void draw(){
// draw Circle;
}
}
總結(jié)
和其他原則一樣 OCP , 也只是一個(gè)原則齿风。構(gòu)思一個(gè)靈活的設(shè)計(jì)需要耗費(fèi)額外的時(shí)間和精力,這會(huì)引入更高層次的抽象绑洛,而抽象則會(huì)提高代碼的復(fù)雜度救斑。所以此原則應(yīng)該應(yīng)用于最可能發(fā)生變化的地方。
有很多設(shè)計(jì)模式可以幫助我們?cè)诓桓膭?dòng)現(xiàn)有代碼的情況下進(jìn)行擴(kuò)展真屯。比如說裝飾者模式可以幫助我們遵循 OCP 原則脸候。工廠方法或觀察者模式也可以用于將應(yīng)用程序設(shè)計(jì)成易于調(diào)整,同時(shí)最小限度地對(duì)原有代碼進(jìn)行改動(dòng)绑蔫。
上一篇:軟件設(shè)計(jì)原則
下一篇:DIP 依賴倒置原則
目錄: http://www.reibang.com/p/af861220a6cc
jdk中的設(shè)計(jì)模式: http://www.reibang.com/p/734c62d1fb3d