閱讀849 返回首頁    go 阿裏雲 go 技術社區[雲棲]


設計模式六大原則——開放封閉原則(OCP)

      什麼是開閉原則?

      定義:是說軟件實體(類、模塊、函數等等)應該可以擴展,但是不可修改。

      開閉原則主要體現在兩個方麵:

      1、對擴展開放,意味著有新的需求或變化時,可以對現有代碼進行擴展,以適應新的情況。

    2、對修改封閉,意味著類一旦設計完成,就可以獨立其工作,而不要對類盡任何修改。

    

   怎麼使用開閉原則?

    實現開放封閉的核心思想就是對抽象編程,而不對具體編程,因為抽象相對穩定。讓類依賴於固定的抽象,所以對修改就是封閉的;而通過麵向對象的繼承和多態機製,可以實現對抽象體的繼承,通過覆寫其方法來改變固有行為,實現新的擴展方法,所以對於擴展就是開放的。 
   對於違反這一原則的類,必須通過重構來進行改善。常用於實現的設計模式主要有Template Method模式和Strategy 模式。而封裝變化,是實現這一原則的重要手段,將經常變化的狀態封裝為一個類。

      以銀行業務員為例 :

      沒有實現OCP設計的:  

public class BankProcess
    {
        public void Deposite(){}   //存款
        public void Withdraw(){}   //取款
        public void Transfer(){}   //轉賬
    }

    public class BankStaff
    {
        private BankProcess bankpro = new BankProcess();
        public void BankHandle(Client client)
        {
            switch (client .Type)
            {
                case "deposite":      //存款
                    bankpro.Deposite();
                    break;
                case "withdraw":      //取款
                    bankpro.Withdraw();
                    break;
                case "transfer":      //轉賬
                    bankpro.Transfer();
                    break;
            }
        }
    }
這種設計顯然是存在問題的,目前設計中就隻有存款,取款和轉賬三個功能,將來如果業務增加了,比如增加申購基金功能,理財功能等,就必須要修改BankProcess業務類。我們分析上述設計就能發現不能把業務封裝在一個類裏麵,違反單一職責原則,而有新的需求發生,必須修改現有代碼則違反了開放封閉原則。

    如何才能實現耦合度和靈活性兼得呢? 

    那就是抽象,將業務功能抽象為接口,當業務員依賴於固定的抽象時,對修改就是封閉的,而通過繼承和多態繼承,從抽象體中擴展出新的實現,就是對擴展的開放。

    一下是符合OCP的設計:  

//首先聲明一個業務處理接口
    public interface IBankProcess
    {
        void Process();
    }
    public class DeposiProcess:IBankProcess
    {
        public void Process()         //辦理存款業務
        {
            Console.WriteLine("Process Deposit");
        }
    }
    public class WithDrawProcess:IBankProcess
    {
        public void Process()        //辦理取款業務
        {
            Console.WriteLine("Process WithDraw");
        }
    }
    public class TransferProcess:IBankProcess
    {
        public void Process()        //辦理轉賬業務
        {
            Console .WriteLine ("Process Transfer");
        }
    }
    public class BankStaff
    {
        private IBankProcess  bankpro = null ;
        public void BankHandle(Client client)
        {
            switch (client .Type)
            {
                case "Deposite":      //存款
                    userProc =new WithDrawUser();
                    break;
                case "WithDraw":      //取款
                    userProc =new WithDrawUser();
                    break;
                case "Transfer":      //轉賬
                    userProc =new WithDrawUser();
                    break;
            }
            userProc.Process();
        }
    }

這樣當業務變更時,隻需要修改對應的業務實現類就可以,其他不相幹的業務就不必修改。當業務增加,隻需要增加業務的實現就可以了。  

最後更新:2017-04-03 12:56:27

  上一篇:go 揭秘小龍蝦11大傳言
  下一篇:go 揭秘小龍蝦11大傳言