美文网首页
面向对象设计原则

面向对象设计原则

作者: 罟宁 | 来源:发表于2016-10-20 14:12 被阅读0次

    第二章 面向对象的设计原则

    在面向对象中,类是基本单位,各种设计都是围绕着类来进行的。类与类之间的关系,构成了设计模式的大部分内容

    2.1 面向对象设计的五大原则

    1、单一职责原则(Single Pesponsibility Principle,SRP)

    • 含义
      1、避免相同的职责分散到不同的类中
      2、避免一个类承担太多的职责
    • 作用
      1、减少类之间的耦合
      2、提高类的复用性
      数据库操作,SNS网站的动态实现
      实例:餐馆示例
    
        /**
        * 厨师类,命令接受者与执行者
        */
        class cook {
            public function meal() {
                echo "番茄炒蛋","<br/>";
            }
            public function drink() {
                echo "紫菜蛋花汤","<br/>";
            }
            public function ok() {
                echo "完毕","<br/>";
            }
        }
        /**
        * 命令接口(服务员)
        */
        interface Waiter {
            public function execute();
        }
        
        /**
        * 模拟服务员与厨师的交互过程
        */
        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();
            }
        }
        /**
        * 实现命令模式
        */
        $custommer = new Custommers;//一个顾客
        $cook = new cook;//一个厨师
        $mealWaiter = new MealWaiter($cook);//一个点菜的服务员
        $drinkWaiter = new DrinkWaiter($cook);//一个点汤的服务员
        $custommer->addWaiter($mealWaiter, $drinkWaiter);//叫来这两个服务员
        $custommer->callmeal();//点菜
        $custommer->calldrink();//点汤
    
    • 需要遵循的做法
      1、根据业务流程,把业务对象提炼出来
      标准化业务链后,对业务对象内部进一步处理,把第一次标准化视为最高层抽象,第二次视为次高层抽象
      2、职责的分类需要注意
      规划好各自的职责范围

    2、接口隔离原则(Interface Segregation Principle, ISP)

    • 接口隔离
      ~ 一个类对另外一个类的依赖性应当是建立在最小的接口上
      ~ 接口使用方程序不应该依赖它不需要的接口方法
    • 对接口的污染
      ~ 定制化服务设计,使用接口的多重继承实现对不同的接口的组合,从而对外提供组合功能。
      ~ 高内聚:接口应该具备一些基本的功能,能独一完成一个基本的任务,而不能过于细化
      ~ 处理方法:* 利用委托分离接口 * 利用多继承分离接口

    3、开放-封闭原则 (Open-Close Principle, OCP)

    • 基本思想
      1、Open(Open for extension):模块的行为必须是开放、支持扩展的,而不是僵化的。
      2、Closed (Closed for modification):在对模块的功能进行扩展时,不应该影响已有的程序模块
    • 一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的
    • 示例
    
        <?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/>";
            }
        }
        
        //播放器的线程调度管理器
        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、判断一个对象是否实现了某个接口
                    $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'));
            }
        }
        
        //实现
        $mp4 = new mp4();
        $mp4->work();
    
    
    • 如何遵守OCP原则
      1、在设计方面充分应用抽象和封装思想
      ~ 找出各种可变因素,将之封装
      ~ 一种可变因素封装在一个对象中
      2、在系统功能编程实现方面应用面向接口的编程
      ~ 当需求发生变化时,可以提供该接口新的实现类,以求适应变化

    4、替换原则/里氏替换原则(Liskov Substitution Principle, LSP)

    • 针对滥用继承的问题提出的设计原则
    • 子类必须能够替换掉它们的父类,并出现在父类的任何地方
    • 遵循方式
      1、父类的方法都要在子类中实现或者重写,并且派生类只实现其抽象类中声明的方法,而不应给出多余的方法定义或实现
      2、在客户端程序中只应该使用父类对象而不应当直接使用子类对象,这样可以实现运行期绑定(动态多态)

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

    • 上层模块不应该依赖于下层模块,它们共同依赖于同一个对象(父类不能依赖子类,它们都要依赖抽象类)
    • 抽象不能依赖于具体,具体应该依赖于抽象

    相关文章

      网友评论

          本文标题:面向对象设计原则

          本文链接:https://www.haomeiwen.com/subject/tjvfuttx.html