面向对象基本原则(1)- 单一职责原则与接口隔离原则

面向对象基本原则(1)- 单一职责原则与接口隔离原则

面向对象基本原则(1)- 单一职责原则与接口隔离原则
面向对象基本原则(2)- 里式代换原则与依赖倒置原则
面向对象基本原则(3)- 最少知道原则与开闭原则php


1、单一职责原则

1. 单一职责原则简介

单一职责原则的英文名称是 Single Responsibility Principle,简称SRP。
单一职责原则的原话解释是:segmentfault

There should never be more than one reason for a class to change.

意思是:应该有且仅有一个缘由引发类的变动。设计模式

2. 单一职责原则优势

  • 类的复杂性下降,实现什么职责都有清晰明确的定义。
  • 可读性提升,复杂性下降,那固然可读性提升了。
  • 可维护性提升,可读性提升,那固然更容易维护了。
  • 变动引发的风险下降,变动是必不可少的,若是接口的单一职责作得好,一个接口修改只对相应的实现类有影响,对其余的接口无影响,这对系统的扩展性、维护性都有很是大的帮助。

3. 最佳实践

接口必定要作到单一职责,类的设计尽可能作到只有一个缘由引发变化。设计

注意 单一职责原则提出了一个编写程序的标准,用“职责”或“变化缘由”来衡量接口或类设计得是否优良,可是“职责”和“变化缘由”都是不可度量的,因项目而异,因环境而异。

4. Show me the code

代码使用PHP7.2语法编写

用户业务场景

IUserBo 接口负责用户属性code

interface IUserBo
{
    public function setUserID(string $userID);

    public function getUserID() : string ;

    public function setPassword(string $password);

    public function getPassword() : string ;

    public function setUserName(string $userName);

    public function getUserName() : string ;
}

IUserBiz 接口负责用户行为对象

interface IUserBiz
{
    public function changePassword(string $password) : bool ;

    public function deleteUser(IUserBo $userBo) : bool ;

    public function mapUser(IUserBo $userBo);

    public function addOrg(IUserBo $userBo, int $orgID) : bool;

    /**
     * 给用户添加角色
     * @param IUserBo $userBo
     * @param int $roleID
     * @return bool
     */
    public function addRole(IUserBo $userBo, int $roleID) : bool ;
}

UserInfo 类实现 IUserBo, IUserBiz 两个接口接口

class UserInfo implements IUserBo, IUserBiz
{
    public function setUserID(string $userID)
    {
        // TODO: Implement setUserID() method.
    }

    public function getUserID(): string
    {
        // TODO: Implement getUserID() method.
    }

    public function setPassword(string $password)
    {
        // TODO: Implement setPassword() method.
    }

    public function getPassword(): string
    {
        // TODO: Implement getPassword() method.
    }

    public function setUserName(string $userName)
    {
        // TODO: Implement setUserName() method.
    }

    public function getUserName(): string
    {
        // TODO: Implement getUserName() method.
    }

    public function changePassword(string $password): bool
    {
        // TODO: Implement changePassword() method.
    }

    public function deleteUser(IUserBo $userBo): bool
    {
        // TODO: Implement deleteUser() method.
    }

    public function mapUser(IUserBo $userBo)
    {
        // TODO: Implement mapUser() method.
    }

    public function addOrg(IUserBo $userBo, int $orgID): bool
    {
        // TODO: Implement addOrg() method.
    }

    public function addRole(IUserBo $userBo, int $roleID): bool
    {
        // TODO: Implement addRole() method.
    }
}
$userInfo = new UserInfo();
// 赋值,就认为它是一个纯粹的属性
$userInfo->setPassword("abc");
// 执行动做,就认为是一个业务逻辑类
$userInfo->deleteUser($userInfo);

2、接口隔离原则

1. 接口隔离原则简介

接口隔离原则的英文名称是 Interface Segregation Principle,简称ISP。
接口隔离原则的英文定义有两种:ip

Clients should not be forced to depend upon interfaces that they don't use.
客户端不该该被迫依赖于他们不使用的接口。

The dependency of one class to another one should depend on the smallest possible interface.
类间的依赖关系应该创建在尽量小的接口上。

咱们能够把这两个定义归纳为一句话:创建单一接口,不要创建臃肿庞大的接口。
再通俗一点讲:接口尽可能细化,同时接口中的方法尽可能少。ci

接口隔离原则与单一职责的区别

接口隔离原则与单一职责的审视角度是不相同的。
单一职责要求的是类和接口职责单一,注重的是职责,这是业务逻辑上的划分,而接口隔离原则要求接口的方法尽可能少。
例如一个接口的职责可能包含10个方法,这10个方法都放在一个接口中,而且提供给多个模块访问,各个模块按照规定的权限来访问,在系统外经过文档约束“不使用的方法不要访问”,按照单一职责原则是容许的,按照接口隔离原则是不容许的,由于它要求“尽可能使用多个专门的接口”。专门的接口就是指提供给每一个模块的都应该是单一接口,而不是创建一个庞大的臃肿的接口,容纳全部的客户端访问。开发

2. 接口隔离原则的规范

接口要尽可能小

这是接口隔离原则的核心定义,不出现臃肿的接口(Fat Interface)。
可是“小”是有限度的,根据接口隔离原则拆分接口时,首先必须知足单一职责原则。

接口要高内聚

高内聚就是提升接口、类、模块的处理能力,减小对外的交互。
具体到接口隔离原则就是,要求在接口中尽可能少使用public方法,接口是对外的承诺,承诺越少对系统的开发越有利,变动的风险也就越少,同时也有利于下降成本。

接口只提供访问者须要的方法

接口设计要适度

接口的设计粒度越小,系统越灵活,这是不争的事实。可是,灵活的同时也带来告终构的复杂化,开发难度增长,可维护性下降,这不是一个项目或产品所指望看到的,因此接口设计必定要注意适度。

3. 最佳实践

接口隔离原则是对接口的定义,同时也是对类的定义,接口和类尽可能使用原子接口或原子类来组装。关于原子该怎么划分,在实践中能够根据如下几个规则来衡量:

  • 一个接口只服务于一个子模块或业务逻辑;
  • 经过业务逻辑压缩接口中的public方法,接口时常去回顾,尽可能让接口达到“满身筋骨肉”,而不是“肥嘟嘟”的一大堆方法;
  • 已经被污染了的接口,尽可能去修改,若变动的风险较大,则采用适配器模式进行转化处理;
  • 每一个项目或产品都有特定的环境因素,环境不一样,接口拆分的标准就不一样。深刻了解业务逻辑,根据经验和常识决定接口的粒度大小。接口粒度过小,致使接口数据剧增,开发人员呛死在接口的海洋里;接口粒度太大,灵活性下降,没法提供定制服务,给总体项目带来没法预料的风险

参考文献:《设计模式之禅》
相关文章
相关标签/搜索