里斯科夫替换_里斯科夫替代原则

里斯科夫替换

或如何创建漂亮的缩写

这是有关SOLID原则的第三篇文章-如果您错过了开放封闭原则 ,请查看。 在这里,我首先简要介绍一下此概念的形成方式,并演示一个描述性示例(我保证,不包括Square和Rectangle!)。

伯特兰·迈耶Bertrand Meyer) ,1986年

伯特兰·迈耶(Bertrand Meyer)首先介绍了合同的概念,并以他的埃菲尔语言将其实现。 合同由前提条件不变 条件后置条件确定 。 这是维基百科的一个不错的总结:

1. [例程可以]期望任何调用它的客户端模块在输入时都会保证一定的条件:例程的前提条件-对客户端的义务,以及对供应商的好处(例程本身),因为它释放了它不必在前提条件之外处理案件。
2.保证在退出时拥有一定的财产:例程的后置条件—供应商的义务,显然是客户的利益(调用例程的主要利益)。
3.维护一个确定的属性,该属性假定是在进入时假定的并且在退出时保证的: class invariant

我只知道一种语言,合同是一种内在的概念-它是Eiffel本身。 在其他语言中,合同可以通过方法的签名来强制执行:参数的类型,返回值的类型以及可以引发的异常。 但是由于发明一种可以用来执行所有现有业务规则的类型系统几乎是不可行的,因此这种方法非常有限。

芭芭拉·里斯科夫 (1994)

芭芭拉·李斯科夫(Barbara Liskov)提出其原则的方式代表了子类型化或亚型多态性的概念。 这种类型的多态性在面向对象的编程中最常见,通常简称为“多态性”。 Liskov正式采用了迈耶的方法,并且在学术上看起来更像是:

令φ(x)是关于类型T的对象x的一个可证明性质。那么,对于类型S的对象y,其中S是T的子类型,则φ(y)应该为true。

易于阅读的版本几乎重复了Bertrand Meyer已经说过的所有内容,但完全依赖于类型系统:

1.前提条件不能在子类型中得到加强。
2.子条件不能弱化后置条件。
3.超类型的不变量必须保留在子类型中。
罗伯特·马丁 (1996)

罗伯特·马丁(Robert Martin)使定义听起来更加流畅和简洁:

使用对基类的引用的指针的函数必须能够在不知道的情况下使用派生类的对象。

但是,他没有引入任何新内容。

违反利斯科夫换人原则

我经常发现,为了理解某些原则,重要的是要意识到何时被违反。 那就是我现在想做的。

违反这一原则意味着什么? 这意味着一个对象不满足由接口表示的抽象所施加的约束。 换句话说,这意味着您标识了错误的抽象

考虑以下示例:

 interface  Account
{
/**
* Withdraw $money amount from this account.
*
*
@param Money $money
*
@return mixed
*/
public function withdraw(Money $money);
}

class DefaultAccount implements Account
{
private $balance ;

public function withdraw(Money $money)
{
if (!$this->enoughMoney($money)) {
return ;
}

$this-> balance ->subtract($money);
}
}

这是否违反LSP? 是的,因为Account的合同告知您将提取一个帐户,但这并非总是如此。 那我该怎么做才能解决它? 我只是修改合同:

 interface  Account
{
/**
* Withdraw $money amount from this account if its balance is enough.
* Otherwise do nothing.
*
*
@param Money $money
*
@return mixed
*/
public function withdraw(Money $money);
}

Voilà,现在合同已履行。

这种细微的冲突常常使客户有能力分辨所采用的具体对象之间的差异。 例如,给定第一个帐户的合同,它可能如下所示:

 class  Client
{
public function go(Account $account, Money $money)
{
if ($account instanceof DefaultAccount && !$account->hasEnoughMoney($money)) {
return ;
}

$account->withdraw($money);
}
}

这自动违反了开放封闭原则

这一点也解决了我经常遇到的违反LSP的错误观念。 就像“如果父母的行为改变了孩子,则违反了LSP”。 只要孩子没有违反父母的合同,它就不会。

SOLID中的Liskov替代原理

我用这个缩写词的问题是,如果那里存在“多态性”,为什么没有“封装”和“可组合性”呢? 这些绝不重要。 可能是因为很难用“ e”和“ c”提出漂亮的缩写吗? 我敢打赌。

结语

不要误会我的意思,我喜欢SOLID及其提倡的方法。 但这只是其深层原则的基础。 上面的示例清楚地说明了该原理的作用: 松散耦合 。 换句话说,不要让您的客户关心所使用的具体类。 崇高的目标,但如何实现呢? 首先,首先分解问题空间 -域。 其次,在方法签名中用简明的英语表达您的合同。

翻译自: https://hackernoon.com/liskov-substitution-principle-a982551d584a

里斯科夫替换

下面是斯科夫替换原则、单一职责原则、开闭原则、德(迪)米特法则、依赖倒转原则、合成复用原则在博客系统中的具体应用: 1. 斯科夫替换原则:在博客系统中,可以定义一个基类或接口,所有的博客类都继承于该基类或实现该接口。这样,无论何时需要使用一个博客对象,都可以使用该基类或接口的引用来引用这个博客对象。 2. 单一职责原则:在博客系统中,每个类都应该只负责一种功能,并将这些功能尽可能地分离开来,避免一个类承担过多的职责。比如,博客文章类只负责文章的相关操作,而不涉及到其它不相关的功能。 3. 开闭原则:在博客系统中,可以使用接口或抽象类来定义可扩展的模块,从而避免对已有代码的修改。这样,当需要添加新的功能时,只需要实现这个接口或继承这个抽象类即可,而不会对已有代码造成影响。 4. 德(迪)米特法则:在博客系统中,可以使用中介者模式或观察者模式来减少对象之间的直接依赖关系,从而降低耦合度。比如,博客文章类可以通过中介者模式来实现与博客评论类之间的交互。 5. 依赖倒转原则:在博客系统中,可以使用依赖注入或反转控制等技术,来实现高层模块与底层模块之间的解耦。比如,博客文章类可以通过依赖注入来获取需要的服务对象,而不需要直接依赖于这些服务对象。 6. 合成复用原则:在博客系统中,可以使用组合模式或装饰器模式等技术来实现代码的复用,并避免继承带来的一些问题。比如,博客文章类可以通过组合模式来实现与博客评论类之间的交互,而不需要通过继承来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值