最新消息:

PHP 的替换原则

替换原则由 MIT 计算机科学实验室的 Liskov 女士在 1987 年的 OOPSLA 大会上的一篇文章《Data Abstraction and Hierar-chy》中提出,主要阐述有关继承的一些原则,故又称里氏替换原则。

2002 年,Robert C. Martin 出版了一本名为《Agile SoftwareDevelopment Principles Patterns and Practices》的书,在书中他把里氏代换原则最终简化为一句话:“Subtypes must be substi-tutable for their base types”。(子类必须能够替换成它们的基类。)

LSP 的内容

里氏替换原则(Liskov Substitution Principle, LSP)的定义和主要的思想如下:由于面向对象编程技术中的继承在具体的编程中过于简单,在许多系统的设计和编程实现中,我们并没有认真地、理性地思考应用系统中各个类之间的继承关系是否合适,派生类是否能正确地对其基类中的某些方法进行重写等问题。因此经常出现滥用继承或者错误地进行了继承等现象,给系统的后期维护带来不少麻烦。这就需要我们有一个设计原则来遵循,它就是替换原则。

LSP 指出:子类型必须能够替换掉它们的父类型、并出现在父类能够出现的任何地方。它指导我们如何正确地进行继承与派生,并合理地重用代码。此原则认为,一个软件实体如果使用一个基类的话,那么一定适用于其子类,而且这根本不能察觉出基类对象和子类对象的区别。想一想,是不是和第一章提到的多态的概念比较像?

LSP 主要是针对继承的设计原则

因为继承与派生是 OOP 的一个主要特性,能够减少代码的重复编程实现,从而实现系统中的代码复用,但如何正确地进行继承设计和合理地应用继承机制呢?

这就是 LSP 所要解决的问题:

  1. 如何正确地进行继承方面的设计?
  2. 最佳的继承层次如何获得?
  3. 怎样避免所设计的类层次陷入不符合 OCP 原则的状况?

那如何遵守该设计原则呢?

  1. 父类的方法都要在子类中实现或者重写,并且派生类只实现其抽象类中声明的方法,而不应当给出多余的方法定义或实现。
  2. 在客户端程序中只应该使用父类对象而不应当直接使用子类对象,这样可以实现运行期绑定(动态多态)。

如果A、B两个类违反了 LSP 的设计,通常的做法是创建一个新的抽象类 C,作为两个具体类的超类,将 A 和 B 的共同行为移动到 C 中,从而解决 A 和 B 行为不完全一致的问题。

在前面的多态,继承这几节的内容里,已经涉及 LSP,包括使用多态实现隐藏基类和派生类对象的区别,以及使用组合的方式解决继承中的基类与派生类(即子类)中的不符合语意的情况。PHP 对 LSP 的支持并不好,缺乏向上转型等概念,只能通过一些曲折的方法实现。对于这个原则,这里就不再细讲了。

在接口那节提到了一个缓存的实现接口,试试用抽象类做基类,遵循 LSP 实现其设计。

这里给出其抽象类代码,代码如下:

<? php
 abstract class Cache {
 /**
 * 设置一个缓存变量
 *
 * @param String $key 缓存Key
 * @param mixed $value 缓存内容
 * @param int $expire 缓存时间(秒)
 * @return boolean 是否缓存成功
 */
 public abstract function set($key, $value, $expire = 60);

 /**
 * 获取一个已经缓存的变量
 *
 * @param String $key 缓存Key
 * @return mixed 缓存内容
 */
 public abstract function get($key);

 /**
 * 删除一个已经缓存的变量
 *
 * @return boolean 是否删除成功
 */
 public abstract function del($key);

 /**
 * 删除全部缓存变量
 *
 * @return boolean 是否删除成功
 */
 public abstract function delAll();

 /**
 * 检测是否存在对应的缓存
 */
 public abstract function has($key);
}

如果现在要求实现文件、memcache、accelerator等各种机制下的缓存,只需要继承这个抽象类并实现其抽象方法即可。

注意:LSP 中代换的不仅仅是功能,还包括语意。

好了,PHP 的替换原则 就分享到这里,非常感谢你的来访。如果你喜欢本站,请不要忘记收藏本站,以便下次继续访问;也可以 关注站长微博 随时获取最新动态。你的支持就是我最大的动力!

转载请注明:爱维科斯 » PHP 的替换原则

支付宝打赏支付宝打赏 微信打赏微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者