開放-封閉的原則

一、OCP簡介(OCP--Open-Closed Principle):
    Software entities(classes,modules,functions,etc.) should be open for extension, but closed for modification。
    軟件實體應當對擴展開放,對修改關閉,即軟件實體應當在不修改(在.Net當中可能通過代理模式來達到這個目的)的前提下擴展。
    Open for extension:當新需求出現的時候,可以通過擴展現有模型達到目的。   
    Close for modification:對已有的二進制代碼,如dll,jar等,則不允許做任何修改。
二、OCP舉例:
1、例子一
    下面這個例子就是既不開放也不封閉的,因爲Client和Server都是具體類,如果我要Client使用不同的一個Server類那就要修改Client類中所有使用Server類的地方爲新的Server類。 
------------------------------------------------------------------------------------------------------
class Client
{
   Server server;
   void GetMessage()
   {
      server.Message();
   }
}
 
class Server
{
   void Message();
}

 ------------------------------------------------------------------------------------------------------

    下面爲修改後符合OCP原則的實現,我們看到Server類是從ClientInterface繼承的,不過ClientInterface卻不叫ServerInterface,原因是我們希望對Client來說ClientInterface是固定下來的,變化的只是Server。這實際上就變成了一種策略模式(Gof Strategy)

 ------------------------------------------------------------------------------------------------------

interface ClientInterface
{
    public void Message();
    //Other functions
}
 
class Server:ClientInterface
{
    public void Message();
}
 
class Client
{
   ClientInterface ci;
   public void GetMessage()
   {
       ci.Message();
   }
   public void Client(ClientInterface paramCi)
   {
       ci=paramCi;
   }
}
 
//那麼在主函數(或主控端)則
public static void Main()
{
   ClientInterface ci = new Server();
   //在上面如果有新的Server類只要替換Server()就行了.
   Client client = new Client(ci);
   client.GetMessage();
}

 ------------------------------------------------------------------------------------------------------

3、例子三
使用Template Method實現OCP
 ------------------------------------------------------------------------------------------------------
public abstract class Policy
{
    private int[] i ={ 1, 1234, 1234, 1234, 132 };
    public bool Sort()
    {
        SortImp();
    }
    protected virtual bool SortImp()
    {
 
    }
}
 
class Bubbleimp : Policy
{
    protected override bool SortImp()
    {
        //冒泡排序
    }
}
class Bintreeimp : Policy
{
    protected override bool SortImp()
    {
        //二分法排序
    }
}
 
//主函數中實現
static void Main(string[] args)
{
    //如果要使用冒泡排序,只要把下面的Bintreeimp改爲Bubbleimp
    Policy sort = new Bintreeimp();
    sort.Sort();
}
 ------------------------------------------------------------------------------------------------------
三、OCP優點:
1、降低程序各部分之間的耦合性,使程序模塊互換成爲可能;
2、使軟件各部分便於單元測試,通過編制與接口一致的模擬類(Mock),可以很容易地實現軟件各部分的單元測試;
3、利於實現軟件的模塊的呼喚,軟件升級時可以只部署發生變化的部分,而不會影響其它部分;
 
四、使用OCP注意點:
1、實現OCP原則的關鍵是抽象;
2、兩種安全的實現開閉原則的設計模式是:Strategy pattern(策略模式),Template Methord(模版方法模式)
3、依據開閉原則,我們儘量不要修改類,只擴展類,但在有些情況下會出現一些比較怪異的狀況,這時可以採用幾個類進行組合來完成;
4、將可能發生變化的部分封裝成一個對象,如: 狀態, 消息,,算法,數據結構等等 , 封裝變化是實現"開閉原則"的一個重要手段,如經常發生變化的狀態值,如溫度,氣壓,顏色,積分,排名等等,可以將這些作爲獨立的屬性,如果參數之間有關係,有必要進行抽象。對於行爲,如果是基本不變的,則可以直接作爲對象的方法,否則考慮抽象或者封裝這些行爲;
5、在許多方面,OCP是面向對象設計的核心所在。遵循這個原則可帶來面向對象技術所聲稱的巨大好處(靈活性、可重用性以及可維護性)。然而,對於應用程序的每個部分都肆意地進行抽象並不是一個好主意。應該僅僅對程序中呈現出頻繁變化的那部分作出抽象。拒絕不成熟的抽象和抽象本身一樣重要;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章