设计模式:设计原则

1.单一职责(SRP)

单一职责原则(Single Responsibility Principle)定义

  应该有且仅有一个原因引起类的变更。

使用单一职责的优点:

  1. 类的复杂性降低,实现什么职责都有清晰明确的定义;

  2. 可读性提高,复杂性降低;

  3.可维护性提高,可读性提高;

  4.变更引起的风险降低,一个接口修改只对相应的实现类有影响,对其他的接口无影响

 

 

  

 

样例1:将用户管理拆分为两个接口,IUserBO负责用户的属性,简单地说,IUserBO的职责就是收集和反馈用户的属性信息;IUserBiz负责用户的行为,完成用户信息的维护和变更

<?php
    /**
     *Business Object(业务对象),负责用户收集和反馈用户的属性信息
     */
    interface IUserBo{
        function setUserId(/* String */ $userId);
        function getUserId();
        function setPassword(/* String */  $password);
        function setUserName(/* String */  $userName);
        function getUserName();
    }

    /**
     *Business Logic(业务逻辑),负责用户的行为,完成用户信息的维护和变更
    */
    interface IUserBiz{
        function changePassword(/* String */  $userId, /* String */ $password);
        function deleteUser(/* IUserBo */ $userBo);
        function mapUser(/* IUserBo */ $userBo);
        function addOrg(/* IUserBo */ $userBo, /* String */$orgId);
        function addRole(/* IUserBo */ $userBo, /* String */$roleId);
    }

    /**
     *Business Logic (业务逻辑),负责处理用户的行为 
    */
    interface IUserInfo extends IUserBo, IUserBiz{
    }

  class UserInfo implements IUserInfo(){
  }

  样例2:

    

    /**
     *Business Object(业务对象),负责用户收集和反馈用户的属性信息
     */
    interface IUserBo{
        function setUserId(/* String */ $userId);
        function getUserId();
        function setPassword(/* String */  $password);
        function setUserName(/* String */  $userName);
        function getUserName();
    }

    /**
     *Business Logic(业务逻辑),负责用户的行为,完成用户信息的维护和变更
    */
    interface IUserBiz extends IUserBo{
        function changePassword(/* String */  $userId, /* String */ $password);
        function deleteUser(/* IUserBo */ $userBo);
        function mapUser(/* IUserBo */ $userBo);
        function addOrg(/* IUserBo */ $userBo, /* String */$orgId);
        function addRole(/* IUserBo */ $userBo, /* String */$roleId);
    }

  class UserBo implements IUserBo {
  }
  
  class IUserBiz implements IUserBiz{
  }

 

2. 里氏替换原则(LSP)

 

  里氏替换原则(Liskov Substitution Principle)定义:

      (1)如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型S是类型T的子类型。

      (2)所有引用基类的地方必须能透明地使用其子类的对象。(子类可以扩展父类的功能,但不能改变父类原有的功能。)

 

里氏替换原则包含以下4层含义:

    • 子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法。
    • 子类中可以增加自己特有的方法。
    • 当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
    • 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

  使用继承优点:

    1.代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性;

    2. 提高代码的重用性;

    3.子类可以形似父类,但又异于父类;

    4.提高代码的可扩展性;

    5.提高产品或项目的开放性;

  继承缺点:

    1.继承是侵入性的。只要继承,就必须拥有父类的所有方法和属性;

    2.降低代码的灵活性。子类必须拥有父类的属性和方法;

    3.增强了耦合性。当父类的变量和方法被修改时,就需要考虑子类的修改;

 在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对。

 遵循里氏替换原则,尽量避免子类重写父类的方法,也尽量避免重载父类的方法,可以有效降低代码出错的可能性。

 

3. 依赖倒置原则(DIP)

  依赖倒置原则( Dependence Inversion Principle,DIP)定义: 

    1. 高层不应该依赖低层模块,两者都应该依赖其抽象、

    2. 抽象不应该依赖细节

    3. 细节应该依赖抽象

  实现规则:

    1. 每个类尽量都有接口或抽象类,或者抽象类和接口两者都具备

    2. 变量的表面类型尽量是接口或抽象类

    3. 任何类都不应该从具体类派生

    4. 尽量不要复写基类的方法

    5. 结合里氏替换原则使用

  样例代码: 

<?php
    interface IDriver {        
        function drive(ICar $car);      
    }                          

    interface ICar {
        function run();        
    }

    class Benz implements ICar {    
        function run(){
            echo "奔驰开动了";
        }
    }

    class BMW implements ICar {
        function run(){
            echo "宝马开动了";
        }
    }

    class Driver implements IDriver {
        function drive(ICar $car){      
            $car->run();
        }
    }

    $car_1 = new BMW();
    (new Driver())->drive($car_1);  

 

4. 接口隔离原则

  接口隔离原则定义:

    1. 客户端不应该依赖它不需要的接口。

    2. 类间的依赖关系应该监理在最小接口上

  实现规范:

    1. 接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性   是不挣的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。

      2. 为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。

      3. 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。

 

5. 迪米特法则/最少知识原则

  迪米特法则( Law of Demeter, LoD)/最少知识原则( Least Knowledge Principle, LKP)定义:

    一个对象应该对其他对象有最少的了解,即一个类应该对自己需要耦合或调用的类知道的最少。

 

6. 开闭原则

  开闭原则 定义:

    一个软件实体如类、模块、和函数应该对扩展开发,对修改关闭。

 

 

设计模式

1. 创建设计模式(Creational Patterns)

用于创建对象时的设计模式。更具体一点,初始化对象流程的设计模式。当程序日益复杂时,需要更加灵活地创建对象,同时减少创建时的依赖。而创建设计模式就是解决此问题的一类设计模式。

单例模式(Singletion)

工厂模式(Factory)

posted @ 2018-03-02 11:53  ony-z  阅读(157)  评论(0编辑  收藏  举报