资讯专栏INFORMATION COLUMN

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

lunaticf / 2312人阅读

摘要:面向对象基本原则单一职责原则与接口隔离原则面向对象基本原则单一职责原则与接口隔离原则面向对象基本原则里式代换原则与依赖倒置原则面向对象基本原则最少知道原则与开闭原则一单一职责原则单一职责原则简介单一职责原则的英文名称是,简称。

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

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


一、单一职责原则 1. 单一职责原则简介

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

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

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

2. 单一职责原则优点

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

可读性提高,复杂性降低,那当然可读性提高了。

可维护性提高,可读性提高,那当然更容易维护了。

变更引起的风险降低,变更是必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的实现类有影响,对其他的接口无影响,这对系统的扩展性、维护性都有非常大的帮助。

3. 最佳实践

接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。

注意 单一职责原则提出了一个编写程序的标准,用“职责”或“变化原因”来衡量接口或类设计得是否优良,但是“职责”和“变化原因”都是不可度量的,因项目而异,因环境而异。
4. Show me the code
代码使用PHP7.2语法编写
用户业务场景

IUserBo 接口负责用户属性

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);
二、接口隔离原则 1. 接口隔离原则简介

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

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.
类间的依赖关系应该建立在尽可能小的接口上。

我们可以把这两个定义概括为一句话:建立单一接口,不要建立臃肿庞大的接口。
再通俗一点讲:接口尽量细化,同时接口中的方法尽量少。

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

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

2. 接口隔离原则的规范 接口要尽量小

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

接口要高内聚

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

接口只提供访问者需要的方法 接口设计要适度

接口的设计粒度越小,系统越灵活,这是不争的事实。但是,灵活的同时也带来了结构的复杂化,开发难度增加,可维护性降低,这不是一个项目或产品所期望看到的,所以接口设计一定要注意适度。

3. 最佳实践

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

一个接口只服务于一个子模块或业务逻辑;

通过业务逻辑压缩接口中的public方法,接口时常去回顾,尽量让接口达到“满身筋骨肉”,而不是“肥嘟嘟”的一大堆方法;

已经被污染了的接口,尽量去修改,若变更的风险较大,则采用适配器模式进行转化处理;

每个项目或产品都有特定的环境因素,环境不同,接口拆分的标准就不同。深入了解业务逻辑,根据经验和常识决定接口的粒度大小。接口粒度太小,导致接口数据剧增,开发人员呛死在接口的海洋里;接口粒度太大,灵活性降低,无法提供定制服务,给整体项目带来无法预料的风险


参考文献:《设计模式之禅》

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/31574.html

相关文章

  • Java-001-面向对象

    摘要:单一职责原则可以看做是低耦合高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。抽象的稳定性决定了系统的稳定性,因为抽象是不变的,依赖于抽象是面向对象设计的精髓,也是依赖倒置原则的核心。 Java-面向对象 什么是面过程 把题分解成一个一个步骤,每个步骤用函数实现,依次调用即可。就是说,在进行面向过程 编程的时候,不需要考虑那么多,上来先定义一个...

    gekylin 评论0 收藏0
  • PHP面向对象设计五大原则(SOLID)梳理总结

    摘要:设计原则梳理,参考核心技术与最佳实践敏捷开发原则模式与实践,文章面向对象设计的五大原则设计模式原则单一职责原则定义特性仅有一个引起类变化的原因一个类只承担一项职责职责变化的原因避免相同的职责分散到不同的类,功能重复问题一个类承担的职责过多, PHP设计原则梳理,参考《PHP核心技术与最佳实践》、《敏捷开发原则、模式与实践》,文章PHP面向对象设计的五大原则、设计模式原则SOLID 单一...

    王晗 评论0 收藏0
  • 设计模式六大原则(PHP)

    摘要:常用的六大设计模式有单一职责原则,里氏替换原则,依赖倒转原则,接口隔离原则,迪米特法则,开闭原则。这六大原则是最虚,最抽象的,很难理解。这就是接口隔离原则。当我们遵循前面介绍的五大原则,以及使用种设计模式的目的就是遵循开闭原则。   设计模式的目的是为了更好的代码重用性,可读性,可靠性和可维护性。常用的六大设计模式有:单一职责原则(SRP),里氏替换原则(LSP),依赖倒转原则(DIP...

    bluesky 评论0 收藏0
  • PHP面向对象设计的五大原则

    摘要:面向对象设计的五大原则单一职责原则接口隔离原则开放封闭原则替换原则依赖倒置原则。主要是针对继承的设计原则,继承与派生多态是的主要特性。 面向对象设计的五大原则:单一职责原则、接口隔离原则、开放-封闭原则、替换原则、依赖倒置原则。这些原则主要是由Robert C.Martin在《敏捷软件开发——原则、方法、与实践》一书中总结出来,这五大原则也是23种设计模式的基础。 单一职责原则 Sin...

    adam1q84 评论0 收藏0
  • Java设计模式-六大原则

    摘要:依赖倒置原则是个设计原则中最难以实现的原则,它是实现开闭原则的重要途径,依赖倒置原则没有实现,就别想实现对扩展开放,对修改关闭。 1、单一职能原则(Single Responsibility Principle, SRP) 定义 There should never be more than one reason for a class to change.应该有且仅有一个原因引起类的...

    molyzzx 评论0 收藏0

发表评论

0条评论

lunaticf

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<