1. 程式人生 > >面向物件的五大設計原則之開放封閉原則

面向物件的五大設計原則之開放封閉原則

隨著我們軟體系統的規模不斷的增大,軟體系統的維護和修改的複雜性不斷地增加,在這種情況下,法國工程院院士bertrand meyer在1998年提出了開放封閉原則(open close principle,簡稱OCP),它的基本思想就是,open(open for exception)模組的行為,必須是開放的,支援擴充套件的,而不是僵化的,close(close for modification)在對模組的功能進行擴充套件時,不能影響或者說不能大規模的影響已有的系統模組。

可以這麼來說,開發封閉原則要求程式人員在不修改系統中已有的功能程式碼(原始碼或者二進位制程式碼)的前提下,實現對應用系統的軟體功能的擴充套件,咱們用一句話概括就是,一個模組在擴充套件性方面應該是開放的,而在更改性方面,應該是封閉的。

我們生活中的例子可以拿電腦來比喻,我們可以輕鬆地擴充套件電腦的功能,只需要在介面插入不同的裝置就好。

開放封閉原則可以提高系統的可擴充套件性和可維護性,但這也是相對的,對於一臺電腦不可能完全開放,有些裝置和功能必須保持穩定才可以減少維護上的困難,要實現一項新的功能,你就必須升級硬體,或者更換一臺效能更高的電腦,咱們以電腦中多媒體播放軟體為例,作為一款播放器,應該具有一些基本的,通用的功能,例如開啟多媒體檔案,停止播放,快進,音量調節等功能,但不論是什麼播放器,在什麼平臺下,遵循這個原則設計的播放器都應該具有統一風格和操作習慣,這樣一來,無論使用者換那一款播放器都可以保證使用者可以快速上手,咱們來看段程式碼感受下:

//定義播放器的抽象介面
interface process
{
    public function process();
}

class decode implements process
{
    
    public function process()
    {
        echo "decode";
    }
}

class output implements process
{
    
    public function process()
    {
        echo "output";
    }
}

class use_process
{
    private $msg=null;

    function __construct()
    {
        # code...
    }

    public function callback(event $event)
    {
        $this->msg = $event->click();
        if($this->msg instanceof process) {
            $this->msg->process();
        }
    }
}

class mp4
{
    
    public function work()
    {
        $u_p = new use_process();
        $u_p->callback(new event("decode"));
        $u_p->callback(new event("output"));
    }
}

class event
{
    private $me;
    function __construct($me)
    {
        $this->me = $me;
    }

    public function click()
    {
        switch ($this->me) {
            case 'decode':
                return new decode();
                break;
            case 'output':
                return new output();
                break;
        }
    }
}

$mp4 = new mp4();
$mp4->work();

接下來,我們來分析下上述程式碼,首先我們是定義了一個播放器的抽象介面process,之後呢,我們就需要對這個介面進行擴充套件了,讓它有一個解碼decode和輸出output的功能,對於播放器的各種功能,在這裡是開放的,只要我們遵守約定實現process介面,我們就可以任意的給播放器新增功能,接下來我們就要定義播放器的執行緒排程管理器use_process了,當播放器接到通知(可以是外部的點選click也可以是內部的notify),將會回撥實際的執行緒來處理,之後呢,我們就要來定義個產品了mp4,這個類是相對封閉的,最後就是類似工廠模式的事件分揀處理類,這個類呢,負責對事務進行分揀,並且判斷使用者的內部行為,最後產生正確的執行緒,供播放器內建的縣城管理器排程。

通過上述程式碼,我們實現了一個最基本的播放器,這個播放器的功能模組對外部是開放的,但是內部處理是相對穩定和封閉的,但是呢,還是有一些小瑕疵,有時候為了降低系統的複雜性,我們也不會完全的遵守設計模式,我們會對其進行修改。

其實實現開放封閉原則的核心思想就是抽象程式設計,而不是具體程式設計,因為抽象相對穩定,我們讓類依賴於固定的抽象,這樣來說修改就是封閉的,之後通過面向物件的繼承和多型機制,我們可以實現對抽象體的繼承,通過複寫其方法來改變固有行為,實現新的擴充套件方法,所以對於擴充套件就是開放的。

來看下開放封閉原則的具體程式設計思想:

1、在設計方面充分應用抽象和封裝的思想

一方面是要在軟體系統中找出各種可能的可變因素,將之封裝起來,另一方面,一種可變因素不應該散落在多個不同的程式碼塊中,而應該被封裝到一個物件中。

2、在系統功能程式設計實現方面應用面向介面的程式設計

當需求發生變化時,可以提供該介面新的實現類,以求適應變化。

面向介面程式設計要求功能類實現介面中所有的方法,物件宣告為介面的型別,在設計模式中,裝飾模式明顯的應用了開放封閉原則。

好啦,本次記錄就到這裡了。

如果感覺不錯的話,請多多點贊支援哦。。。