PHP面向对象五大原则之里氏替换原则(LSP)详解


Posted in PHP onApril 08, 2018

本文实例讲述了PHP面向对象五大原则之里氏替换原则(LSP)。分享给大家供大家参考,具体如下:

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

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

1. LSP的内容

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

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

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

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

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

如何正确地进行继承方面的设计?

最佳的继承层次如何获得?

怎么样避免所设计的类层次陷入不符合OCP原则的状况?

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

1)父类的方法都要在子类中实现或者重写,并且派生类只实现其抽象类中声明的方法,而不应当给出多余的方法定义或实现

2)在客户端程序中只应该使用父类对象而不应当直接使用子类对象,这样可以实现运行期绑定(动态多态)。

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

不过PHP对LSP的支持并不好,缺乏向上转型等概念,只能通过一些曲折的方法实现。对于这个原则,这里就不细讲了。

下面给出一个缓存的实现接口,用抽象类做基类,遵循LSP实现其设计。

<?php
abstract class Cache
{
 /**
  * 设置一个缓存变量
  * @param $key 缓存key
  * @param $value 缓存内容
  * @param int $expire 缓存时间(秒)
  * @return boolean 是否缓存成功
  */
 public abstract function set($key, $value, $expire = 60);
 /**
  * 获取一个已经缓存的
  * @param $key 缓存key
  * @return mixed 缓存内容
  */
 public abstract function get($key);
 /**
  * 删除一个已经缓存的变量
  * @param $key 缓存key
  * @return boolean 是否删除成功
  */
 public abstract function del($key);
 /**
  * 删除全部缓存变量
  * @return boolean 是否删除成功
  */
 public abstract function delAll();
 /**
  * 检测是否存在对应的缓存
  * @param $key 缓存key
  * @return boolean 是否存在
  */
 public abstract function has($key);
}

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

LSP中代码的不仅仅是功能,还名手语意。试思考:白马可以代换马,而牛同样作为劳动力,可代换马否?高跟鞋也是鞋子,男人穿高跟鞋又是否能接受?

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP数据缓存技术
Feb 14 PHP
PHP 线程安全与非线程安全版本的区别深入解析
Aug 06 PHP
php获取网页标题和内容函数(不包含html标签)
Feb 03 PHP
ecshop实现smtp发送邮件
Feb 03 PHP
php类中的$this,static,final,const,self这几个关键字使用方法
Dec 14 PHP
PHP编程入门的基本语法知识点总结
Jan 26 PHP
[原创]php token使用与验证示例【测试可用】
Aug 30 PHP
PHP实现数据库统计时间戳按天分组输出数据的方法
Oct 10 PHP
PHP自定义递归函数实现数组转JSON功能【支持GBK编码】
Jul 17 PHP
对php 判断http还是https,以及获得当前url的方法详解
Jan 15 PHP
PHP抽象类与接口的区别详解
Mar 21 PHP
Laravel框架控制器,视图及模型操作图文详解
Dec 04 PHP
PHP实现微信红包金额拆分试玩的算法示例
Apr 07 #PHP
PHP面向对象五大原则之接口隔离原则(ISP)详解
Apr 04 #PHP
PHP面向对象五大原则之开放-封闭原则(OCP)详解
Apr 04 #PHP
PHP面向对象五大原则之单一职责原则(SRP)详解
Apr 04 #PHP
PHP基于面向对象实现的留言本功能实例
Apr 04 #PHP
PHP设计模式之工厂模式定义与用法详解
Apr 03 #PHP
PHP设计模式之原型模式定义与用法详解
Apr 03 #PHP
You might like
PHP 巧用数组降低程序的时间复杂度
2010/01/01 PHP
不支持fsockopen但支持culr环境下下ucenter与modoer通讯问题
2011/08/12 PHP
ThinkPHP写第一个模块应用
2012/02/20 PHP
php+mysql实现简单的增删改查功能
2015/07/13 PHP
实例讲解如何在PHP的Yii框架中进行错误和异常处理
2016/03/17 PHP
PHP如何使用array_unshift()在数组开头插入元素
2020/09/01 PHP
找到一点可怜的关于dojo资料,谢谢作者!
2006/12/06 Javascript
文本框的字数限制功能jquery插件
2009/11/24 Javascript
js 数组克隆方法 小结
2010/03/20 Javascript
简单的前端js+ajax 购物车框架(入门篇)
2011/10/29 Javascript
js原型链原理看图说明
2012/07/07 Javascript
Extjs 3.3切换tab隐藏相应工具栏出现空白解决
2013/04/02 Javascript
jquery mobile changepage的三种传参方法介绍
2013/09/13 Javascript
eclipse导入jquery包后报错的解决方法
2014/02/17 Javascript
jQuery中:visible选择器用法实例
2014/12/30 Javascript
jQuery使用each方法与for语句遍历数组示例
2016/06/16 Javascript
jQuery组件easyui基本布局实现代码
2016/08/25 Javascript
在微信小程序中渲染HTML内容的方法示例
2018/09/28 Javascript
微信小程序pinker组件使用实现自动相减日期
2020/05/07 Javascript
vue实现购物车列表
2020/06/30 Javascript
【Python】Python的urllib模块、urllib2模块批量进行网页下载文件
2016/11/19 Python
实例分析python3实现并发访问水平切分表
2018/09/29 Python
django 2.2和mysql使用的常见问题
2019/07/18 Python
Flask中endpoint的理解(小结)
2019/12/11 Python
Python 实现使用空值进行赋值 None
2020/03/12 Python
css3动画事件—webkitAnimationEnd与计时器time事件
2013/01/31 HTML / CSS
Melijoe美国官网:法国奢侈童装购物网站
2017/04/19 全球购物
一百多行代码实现react拖拽hooks
2021/03/23 Javascript
在校生钳工实习自我鉴定
2013/09/19 职场文书
英语文学专业学生的自我评价
2013/10/31 职场文书
关于环保的建议书
2014/05/12 职场文书
见习报告的格式
2014/10/31 职场文书
大学生求职简历自我评价
2015/03/02 职场文书
资产移交协议书
2016/03/24 职场文书
tensorflow中的数据类型dtype用法说明
2021/05/26 Python
Python利用机器学习算法实现垃圾邮件的识别
2021/06/28 Python