不懂对象设计原则,都不好意思自称php大师
PHP    2021-06-16 15:34:17    46    0    0
admin   PHP

在面向对象的设计中,如何通过很少的设计改变就可以应对设计需求变化,这是设计者极为要关注的问题。为此,我们需要掌握面向对象设计的5大设计原则。
面向对象设计的5大设计原则分别是:

  1. 单一职责原则
  2. 接口隔离原则
  3. 开放-封闭原则
  4. 里氏替换原则
  5. 依赖倒置原则
    这5大原则也是23种类设计模式的基础

单一职责原则

单一职责原则(Single Responsibility Principle,SRP)
一个类被改变的原因不能超过一个,也就是说,一个类只有一个职责,如果职责过多,代码就会臃肿,可读性更差,也更难以维护。

为什么要遵守单一职责原则

1、提高类的可维护性和可读写性
一个类的职责少了,复杂度降低了,代码就少了,可读性也就好了,可维护性自然就高了
2、提高系统的可维护性
系统是由类组成的,每个类的可维护性高,相对来讲整个系统的可维护性就高。当然,前提是系统的架构没有问题。
3、降低变更的风险
一个类的职责越多,变更的可能性就更大,变更带来的风险也就越大

如何遵守单一职责原则

合理的职责分解相同的职责放到一起,不同的职责分解到不同的接口和实现中去

单一职责原则最佳实践

在实际工作中,有一个经常会用到的设计模式,DAO模式,又叫数据访问对象,里面定义了数据库中表的增、删、改、查操作.
按照单一职责原则,为什么不把增、删、改、查分别定义成四种接口?这是因为数据库的表操作,基本上就是这四种类型,不可能变化,所以没有必要分开定义。
反而经常变化的是数据库的表结构,表结构一变,这四种操作都要跟着变。所以通常我们会针对一张表实现一个DAO,一张表就代表一种类型的职责。

遵循单一职责原则代码实例

代码源码

接口隔离原则

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

1.客户端不应该依赖它不需要的接口
2.类间的依赖关系应该建立在最小的接口上

通俗来讲:使用多个专门的接口比使用单一的总接口要好。

接口如果能够保持粒度够小,就能保证它足够稳定
换而言之,从一个客户类的角度来讲:一个类对另外一个类的依赖性应当是建立在最小接口上的。
过于臃肿的接口是对接口的污染。不应该强迫客户依赖于它们不用的方法。

接口隔离原则与单一职责原则对比

接口隔离原则和单一职责原则非常类似。

单一职责原则要求接口的职责是单一的,而接口隔离原则要求接口尽量细化,它们有异曲同工之妙,都是要让我们的接口功能尽量单一,尽量小。
但是,单一职责原则的着重点是在“职责”,而接口隔离原则只单纯地要求接口最小化。
那么,如果已经满足单一职责原则的接口,在当前的需求下还可以继续细化,那么还需要细化吗?答案是不要再细化了。
在实践中,接口设计的粒度越小,系统就越灵活,这是事实。
但是灵活的同时也带来了系统的复杂化,导致开发难度增加。
所以接口并不是越小越好,必须要有一个度。
当单一职责原则和接口隔离原则存在矛盾时,以满足单一职责原则为底线。

开放-封闭原则

开放-封闭原则(Open-Close Principle,OCP)
对于扩展是开放的

这意味着模块的行为是可以扩展的。
当应用程序的需求改变时,我们可以对其模块进行扩展,使其具有满足那些需求变更的新行为。
换句话说,我们可以改变模块的功能。

对于修改是封闭的

对模块行为进行扩展时,不应该影响或大规模地影响已有的程序模块。
换句话说,要求开发人员在不修改系统现有的代码(源码或二进制代码)的前提下,实现对系统的扩展。

比如生活中的电脑,满足开放封闭原则。向电脑USB接口插入鼠标,就可以使用鼠标功能,这是开放的(扩展了鼠标功能)。我们不需要对电脑内部部件重新编排,这是封闭的(扩展了鼠标功能,但我们不需要修改电脑配置)。
但这也是相对的,对于一台电脑不可能完全开放,有些设备和功能必须保持稳定才能减少维护上的困难。要实现一项新的功能,你就必须升级硬件,或者换一台更高性能的电脑。

里氏替换原则

里氏替换原则(Liskov Substitution Principle,LSP)
1.子类必须完全实现父类的方法

在类中调用其它类时务必要使用父类或接口,如果不能使用父类或接口,则说明类的设计以及违背了LSP原则

2.子类可以拥有自己的“个性”

子类可以拥有自己的方法和属性,
也可以重写(Override)或重载(Overload)父类的方法。从而拥有自己的“个性”。
但这里提起是为了再次说明一个问题——里氏替换原则可以正着用,但不能反过来使用,即子类出现的地方,父类未必可以胜任。

依赖导致原则

依赖导致原则(Dependence Inversion Principle,DIP)

  • 高层模块不应该依赖低层模块,两者都应该依赖其抽象;
  • 抽象不应该依赖细节;
  • 细节应该依赖抽象。

以上3点,通俗的讲

  • 模块间的依赖是通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;
  • 接口或抽象类不依赖于实现类;
  • 实现类依赖接口或抽象类。

简言之就是“面向接口编程”

上一篇: php5与php7的区别是什么

下一篇: 一致性哈希算法是什么?怎么判定哈希算法的好坏?

46
登录 后评论.
没有帐号? 现在注册.
0 评论
Table of content