Open Close Principle
動(dòng)機(jī)
開(kāi)明的應(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一般都已通過(guò)單元測(cè)試,在其中做的改動(dòng)可能莫名其妙地就影響到現(xiàn)有功能。
開(kāi)放 - 封閉原則 強(qiáng)調(diào)設(shè)計(jì)和代碼編寫應(yīng)當(dāng)以在現(xiàn)有代碼上改動(dòng)最小的方式來(lái)完成新功能的添加。軟件設(shè)計(jì)應(yīng)盡可能在添加新功能類的時(shí)候不去改動(dòng)現(xiàn)有代碼。
目的
軟件實(shí)體,如類、模塊和函數(shù),應(yīng)當(dāng)對(duì)擴(kuò)展開(kāi)放,但對(duì)修改關(guān)閉。
個(gè)人理解:對(duì)使用方的修改關(guān)閉, 對(duì)提供方的功能擴(kuò)展開(kāi)放
例子
以下是一個(gè)違背 OCP 的例子。 它實(shí)現(xiàn)了繪制各種圖形的 graph editor
。 顯然,GraphicEditor
沒(méi)有遵循 OCP ,因?yàn)槊看翁砑右粋€(gè) shape
子類,都要對(duì)其進(jìn)行修改。這有以下幾個(gè)缺點(diǎn):
- 每次添加新的
shape
子類,GraphicEditor
的單元測(cè)試都要重新做 - 每次添加新的
shape
子類所需時(shí)間都比較多,因?yàn)殚_(kāi)發(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í)例中。通過(guò)使用 OCP ,我們就避免了上述例子中的問(wèn)題,當(dāng)添加新 shape
子類的時(shí)候, 不需要對(duì)GraphicEditor
進(jìn)行修改。
- 不需要額外的單元測(cè)試
- 不需要知曉
GraphicEditor
的源碼 - 由于具體的繪圖代碼移到具體的
shape
實(shí)現(xiàn)子類中,新功能添加進(jìn)來(lái)的時(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ò)展。比如說(shuō)裝飾者模式可以幫助我們遵循 OCP 原則。工廠方法或觀察者模式也可以用于將應(yīng)用程序設(shè)計(jì)成易于調(diào)整,同時(shí)最小限度地對(duì)原有代碼進(jìn)行改動(dòng)。
上一篇:軟件設(shè)計(jì)原則
下一篇:DIP 依賴倒置原則
目錄: http://www.lxweimin.com/p/af861220a6cc
jdk中的設(shè)計(jì)模式: http://www.lxweimin.com/p/734c62d1fb3d