面向物件的五大設計原則之開放封閉原則
隨著我們軟體系統的規模不斷的增大,軟體系統的維護和修改的複雜性不斷地增加,在這種情況下,法國工程院院士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、在系統功能程式設計實現方面應用面向介面的程式設計
當需求發生變化時,可以提供該介面新的實現類,以求適應變化。
面向介面程式設計要求功能類實現介面中所有的方法,物件宣告為介面的型別,在設計模式中,裝飾模式明顯的應用了開放封閉原則。
好啦,本次記錄就到這裡了。
如果感覺不錯的話,請多多點贊支援哦。。。