面向?qū)ο笤O(shè)計原則

第二章 面向?qū)ο蟮脑O(shè)計原則

在面向?qū)ο笾?,類是基本單位,各種設(shè)計都是圍繞著類來進行的。類與類之間的關(guān)系,構(gòu)成了設(shè)計模式的大部分內(nèi)容

2.1 面向?qū)ο笤O(shè)計的五大原則

1、單一職責原則(Single Pesponsibility Principle,SRP)

  • 含義
    1、避免相同的職責分散到不同的類中
    2、避免一個類承擔太多的職責
  • 作用
    1、減少類之間的耦合
    2、提高類的復(fù)用性
    數(shù)據(jù)庫操作,SNS網(wǎng)站的動態(tài)實現(xiàn)
    實例:餐館示例

    /**
    * 廚師類,命令接受者與執(zhí)行者
    */
    class cook {
        public function meal() {
            echo "番茄炒蛋","<br/>";
        }
        public function drink() {
            echo "紫菜蛋花湯","<br/>";
        }
        public function ok() {
            echo "完畢","<br/>";
        }
    }
    /**
    * 命令接口(服務(wù)員)
    */
    interface Waiter {
        public function execute();
    }
    
    /**
    * 模擬服務(wù)員與廚師的交互過程
    */
    class MealWaiter implements Waiter {
        private $cook;
        public function __construct(cook $cook) {//類型限定,下同
            $this->cook = $cook;
        }
        public function execute() {
            $this->cook->meal();
        }
    }
    class DrinkWaiter implements Waiter {
        private $cook;
        public function __construct(cook $cook) {
            $this->cook = $cook;
        }
        public function execute() {
            $this->cook->drink();
        }
    }
    /**
    * 顧客點菜
    */
    class Custommers {
        private $mealWaiter;
        private $drinkWaiter;
        public function addWaiter(Waiter $mealWaiter, Waiter $drinkWaiter) {//類型限定
            $this->mealWaiter = $mealWaiter;
            $this->drinkWaiter = $drinkWaiter;
        }
        public function callmeal() {
            $this->mealWaiter->execute();
        }
        public function calldrink() {
            $this->drinkWaiter->execute();
        }
    }
    /**
    * 實現(xiàn)命令模式
    */
    $custommer = new Custommers;//一個顧客
    $cook = new cook;//一個廚師
    $mealWaiter = new MealWaiter($cook);//一個點菜的服務(wù)員
    $drinkWaiter = new DrinkWaiter($cook);//一個點湯的服務(wù)員
    $custommer->addWaiter($mealWaiter, $drinkWaiter);//叫來這兩個服務(wù)員
    $custommer->callmeal();//點菜
    $custommer->calldrink();//點湯
  • 需要遵循的做法
    1、根據(jù)業(yè)務(wù)流程,把業(yè)務(wù)對象提煉出來
    標準化業(yè)務(wù)鏈后,對業(yè)務(wù)對象內(nèi)部進一步處理,把第一次標準化視為最高層抽象,第二次視為次高層抽象
    2、職責的分類需要注意
    規(guī)劃好各自的職責范圍

2、接口隔離原則(Interface Segregation Principle, ISP)

  • 接口隔離
    ~ 一個類對另外一個類的依賴性應(yīng)當是建立在最小的接口上
    ~ 接口使用方程序不應(yīng)該依賴它不需要的接口方法
  • 對接口的污染
    ~ 定制化服務(wù)設(shè)計,使用接口的多重繼承實現(xiàn)對不同的接口的組合,從而對外提供組合功能。
    ~ 高內(nèi)聚:接口應(yīng)該具備一些基本的功能,能獨一完成一個基本的任務(wù),而不能過于細化
    ~ 處理方法:* 利用委托分離接口 * 利用多繼承分離接口

3、開放-封閉原則 (Open-Close Principle, OCP)

  • 基本思想
    1、Open(Open for extension):模塊的行為必須是開放、支持擴展的,而不是僵化的。
    2、Closed (Closed for modification):在對模塊的功能進行擴展時,不應(yīng)該影響已有的程序模塊
  • 一個模塊在擴展性方面應(yīng)該是開放的而在更改性方面應(yīng)該是封閉的
  • 示例

    <?php
    //開放封閉原則的示例:播放器
    
    interface process {
        public function process();
    }
    //編碼
    class playerencode implements process {
        public function process() {
            echo "encode","<br/>";
        }
    }
    //輸出
    class playeroutput implements process {
        public function process() {
            echo "output","<br/>";
        }
    }
    
    //播放器的線程調(diào)度管理器
    class playprocess {
        private $message = NULL;
        public function __construct() {
    
        }
        public function callback(event $event) {
            $this->message = $event->click();
            if ($this->message instanceof process) {//instanceof:1、判斷一個對象是否是某個類的實例;2、判斷一個對象是否實現(xiàn)了某個接口
                $this->message->process();
            }
        }
    }
    
    //播放器的事件處理類,對事件進行分揀
    class event {
        private $m;
        public function __construct($me) {
            $this->m = $me;
        }
        public function click() {
            switch ($this->m) {
                case 'encode':
                    return new playerencode();
                    break;
                case 'output':
                    return new playeroutput();
                    break;
            }
        }
    }
    
    //播放器的事件處理邏輯
    class mp4 {
        public function work() {
            $playProcess = new playProcess();
            $playProcess->callback(new event('encode'));
            $playProcess->callback(new event('output'));
        }
    }
    
    //實現(xiàn)
    $mp4 = new mp4();
    $mp4->work();

  • 如何遵守OCP原則
    1、在設(shè)計方面充分應(yīng)用抽象和封裝思想
    ~ 找出各種可變因素,將之封裝
    ~ 一種可變因素封裝在一個對象中
    2、在系統(tǒng)功能編程實現(xiàn)方面應(yīng)用面向接口的編程
    ~ 當需求發(fā)生變化時,可以提供該接口新的實現(xiàn)類,以求適應(yīng)變化

4、替換原則/里氏替換原則(Liskov Substitution Principle, LSP)

  • 針對濫用繼承的問題提出的設(shè)計原則
  • 子類必須能夠替換掉它們的父類,并出現(xiàn)在父類的任何地方
  • 遵循方式
    1、父類的方法都要在子類中實現(xiàn)或者重寫,并且派生類只實現(xiàn)其抽象類中聲明的方法,而不應(yīng)給出多余的方法定義或?qū)崿F(xiàn)
    2、在客戶端程序中只應(yīng)該使用父類對象而不應(yīng)當直接使用子類對象,這樣可以實現(xiàn)運行期綁定(動態(tài)多態(tài))

5、依賴倒置原則(Dependence Inversion Principle, DIP)/IOC(Inversion of Control)

  • 上層模塊不應(yīng)該依賴于下層模塊,它們共同依賴于同一個對象(父類不能依賴子類,它們都要依賴抽象類)
  • 抽象不能依賴于具體,具體應(yīng)該依賴于抽象
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容