里斯科夫替代原则

或如何创建漂亮的缩写

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

From: https://hackernoon.com/liskov-substitution-principle-a982551d584a

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值