Laravel深入学习10 - 里氏替换原则
声明:本文并非博主原创,而是来自对《Laravel 4 From Apprentice to Artisan》阅读的翻译和理解,当然也不是原汁原味的翻译,能保证90%的原汁性,另外因为是理解翻译,肯定会有错误的地方,欢迎指正。
欢迎转载,转载请注明出处,谢谢!
里氏替换原则
简介
别担心,里氏替换原则实际上比他的名字好理解。他是指任何在任何接受抽象化类的地方其实现也被接受。通俗的讲,类中使用接口实现的地方,不需要修改代码对于任意的接口实现类都将能使用。
里氏替换原则
该原则表示,程序中对于实例化对象的子类型,不需要修改代码,可以直接进行替换。
实探
我们继续拿OrderProcessor
举例来阐述该原则,看下这个方法:
public function process(Order $order)
{// Validate order...$this->orders->logOrder($order);
}
在Order
验证之后,我们使用OrderRepositoryInterface
接口实现类来记录订单日志。我们假定,当订单处理未成熟时,我们将所有的订单以CSV格式记录到系统中。我们的额OrderRepositoryInterface
接口实现类为CsvOrderRepository
。当业务继续发展,我们想使用关系型数据库记录订单。下面,我们看下一种可能的接口实现:
class DatabaseOrderRepository implements OrderRepositoryInterface {protected $connection;public function connect($username, $password){$this->connection = new DatabaseConnection($username, $password);}public function logOrder(Order $order){$this->connection->run('insert into orders values (?, ?)', array($order->id, $order->amount,));}}
现在,让我们检验下如何将不得不去使用此实现:
public function process(Order $order)
{// Validate order...if ($this->repository instanceof DatabaseOrderRepository){$this->repository->connect('root', 'password');}$this->repository->logOrder($order);
}
注意,在订单处理类中,我们强制检测了OrderRepositoryInterface
是否为一个数据库的实现方式。如果是,继续数据库的连接。在小型应用中还算是小问题,但是,如果在很多其他类中OrderRepositoryInterface
被使用到时怎么办?我们就只能在所有地方去添加这段“引导”代码。这样的代码维护让人头痛,还会代码潜在的bug,如果有一个地方忘记修改,就瞎了。
上述实例已违背里氏替换原则。在不修改connect
方法的情况下我们无法注入接口的实现类。既然发现了问题,那就去修复他们吧。这里是一个新的DatabaseOrderRepository
实现类:
class DatabaseOrderRepository implements OrderRepositoryInterface {protected $connector;public function __construct(DatabaseConnector $connector){$this->connector = $connector;}public function connect(){return $this->connector->bootConnection();}public function logOrder(Order $order){$connection = $this->connect();$connection->run('insert into orders values (?, ?)', array($order->id, $order->amount,));}}
现在在DatabaseOrderRepository
中实现了数据库连接的管理,我们就可以从OrderProcessor
中移除那段“引导”代码了:
public function process(Order $order)
{// Validate order...$this->repository->logOrder($order);
}
如此改变,我们就可以在OrderProcessor
中随意使用CsvOrderRepository
或者DatabaseOrderRepository
了。我们的代码遵循了里氏替换原则。很多建筑学上的概念都被讨论成一种“认知”。特别的,对于每一个类,都有其自己的“语境”,他周边的代码在其依赖环境下帮助类来完成特定的工作。当你让架构朝着健壮方向发展的时候,这种类的设计“认知”将是一种持久重要的主题。
小心漏洞
你也许注意到了本原则和上章中提到的回避“抽象漏洞”类似。我们的数据库获取部分就是破坏里氏替换的点,在你以后的编码中一定要对这种编码留心!
Laravel深入学习10 - 里氏替换原则相关推荐
- java里氏替换原则例子_java设计模式学习笔记——里氏替换原则
oo中的继承性的思考和说明 1.继承包含这样一层含义:父类中凡是已经实现好的方法,实际上是在设定规范和契约,虽然它不强制要求所有的子类必须遵循这些七月,但是如果子类对这些已经实现的方法任意修改,就会对 ...
- 软件架构设计原则--里氏替换原则
本专栏内容参考自:咕泡学院Tom老师的<Spring5核心原理与30个类手写实战>,仅作个人学习记录使用,如有侵权,联系速删 里氏替换原则(Liskov Substitution Pr ...
- 北风设计模式课程---里氏替换原则(Liskov Substitution Principle)
北风设计模式课程---里氏替换原则(Liskov Substitution Principle) 一.总结 一句话总结: 当衍生类能够完全替代它们的基类时:(Liskov Substitution P ...
- 《设计模式》杂记之里氏替换原则
在这篇博文中,我想把自己学习过的里氏替换原则一些好知识点分享给大家.首先我想把继承的一下优缺点给大家分享一下,然后再引出里氏替换原则吧!<?xml:namespace prefix = o ns ...
- php 单一职责原则,Laravel深入学习8 - 单一责任原则
声明:本文并非博主原创,而是来自对<Laravel 4 From Apprentice to Artisan>阅读的翻译和理解,当然也不是原汁原味的翻译,能保证90%的原汁性,另外因为是理 ...
- Java里氏转换_详解Java设计模式编程中的里氏替换原则
定义1:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 ...
- 软件架构-里氏替换原则
里氏替换原则(Liskov Substitution Principle,LSP)是面向对象设计的基本原则之一. 里氏替换原则认为: 任何基类(父类或接口)可以出现的地方,子类(实现类)一定可以出现. ...
- java里氏替换原则例子_java 设计原则(六)里氏替换原则
定义:如果对每一个类型T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都替换成o2时,程序P的行为没有发生变化,那么类型T2是类型T1的子类型. 定义扩展:一个软件 ...
- 软件架构设计原则-里氏替换原则
前言 里氏替换原则简单的理解可以是父类用到的地方可以用子类替换并且不改变逻辑,这就要求子类可以扩展父类的功能,但不能改变父类原有的功能.里氏替换原则要求 (1) 子类可以实现父类的抽象方法,但不能覆盖 ...
最新文章
- api 微信小程序组件库colorui_2020最全微信小程序UI组件库合集
- 初次使用 Elasticsearch 遇多种分词难题?那是你没掌握这些原理
- 操作系统多线程实现_操作系统中的线程实现
- oracle安装向导卡住了_JDK 8 的安装与配置
- 牛的旅行(信息学奥赛一本通-T1343)
- java uml eclipse_eclipse uml 工具
- Mysql删除数据时出现执行很慢并且删除失败--线程堵塞
- 活在迷茫中,不是活在当下
- 文件被后台程序占用无法删除_Windows系统中,教你彻底删除C盘的顽固文件,瞬间多出10个G...
- 面向对象 重写和重载
- 梦幻西游手游经验任务链计算机,梦幻西游手游任务链技巧攻略详解
- 盗贼之海显示无法连接服务器,盗贼之海网络连接不上怎么解决
- 【转载】Unity3D导入图片属性信息和默认shader介绍
- 线性代数——线性组合、线性空间、基底
- 案例3-数据驱动测试-从excel导入数据
- Java实现SHA-1、SHA-256和SHA-512加密(原生摘要)
- 计算当前日期是本年的第几周
- 双系统安装 win7
- 华为 AISC 研究型实习生招聘~北京 or 深圳
- 差异表达基因热图怎么看_为什么我代码里面选择top1000的sd基因绘制热图呢