搞定里式替换原则的设计模式一篇文章就够了!!!
Posted 南淮北安
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搞定里式替换原则的设计模式一篇文章就够了!!!相关的知识,希望对你有一定的参考价值。
一、定义
继承必须确保父类所拥有的性质在子类中仍然成立
子类可以扩展父类的功能,但不能改变父类原有的功能。也就是说:当子类继承父类时,除添加新的方法且完成新增功能外,尽量不要重写父类的方法。
是动作正确性的保证,即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性。
二、示例问题
我们会使用各种类型的银行卡,例如储蓄卡、信用卡,还有一些其他特性的银行卡。储蓄卡和信用卡都具备一定的消费功能,但又有一些不同。例如信用卡不宜提现,如果提现可能会产生高额的利息。
下面构建这样一个模拟场景,假设在构建银行系统时,储蓄卡是第一个类,信用卡是第二个类。为了让信用卡可以使用储蓄卡的一些方法,选择由信用卡类继承储蓄卡类,讨论是否满足里氏替换原则产生的一些要点。
储蓄卡和信用卡在使用功能上类似,都有支付、提现、还款、充值等功能,也有些许不同,例如支付,储蓄卡做的是账户扣款动作,信用卡做的是生成贷款单动作。
下面这里模拟先有储蓄卡的类,之后继承这个类的基本功能,以实现信用卡的功能。
public class CashCard {
public void withdrawal(String orderId, BigDecimal amount) {
System.out.println("模拟提现");
}
public void recharge(String orderId, BigDecimal amount) {
System.out.println("模拟储蓄");
}
public void tradeFlow(){
System.out.println("模拟流水查询");
}
}
储蓄卡的基本功能:提现,储蓄,流水查询
信用卡继承储蓄卡,重新提现和储蓄的功能,复用流水查询的功能
public class CreditCard extends CashCard{
@Override
public void withdrawal(String orderId, BigDecimal amount) {
System.out.println("模拟贷款");
}
@Override
public void recharge(String orderId, BigDecimal amount) {
System.out.println("模拟还款");
}
@Override
public void tradeFlow() {
super.tradeFlow();
}
}
这种继承父类方式的优点是复用了父类的核心功能逻辑,但是也破坏了原有的方法。
此时继承父类实现的信用卡类并不满足里氏替换原则,也就是说,此时的子类不能承担原父类的功能,直接给储蓄卡使用。
三、问题改进
储蓄卡和信用卡在功能使用上有些许类似,在实际的开发过程中也有很多共同可复用的属性及逻辑。
实现这样的类的最好方式是提取出一个抽象类,由抽象类定义所有卡的共用核心属性、逻辑
抽象银行卡类:
public abstract class BankCard {
// 卡号
private String cardNo;
// 开卡时间
private String cardDate;
public BankCard(String cardNo, String cardDate) {
this.cardNo = cardNo;
this.cardDate = cardDate;
}
public void tradeFlow() {
System.out.println("模拟流水查询");
}
}
储蓄卡类实现:
public class CashCard extends BankCard {
public CashCard(String cardNo, String cardDate) {
super(cardNo, cardDate);
}
public void withdrawal(String orderId, BigDecimal amount) {
System.out.println("模拟提现");
}
public void recharge(String orderId, BigDecimal amount) {
System.out.println("模拟储蓄");
}
}
储蓄卡类中继承抽象银行卡父类 BankCard,实现的核心功能提现withdrawal、储蓄recharge
这样的实现方式满足了里氏替换的基本原则,既实现抽象类的抽象方法,又没有破坏父类中的原有方法。
接下来实现信用卡的功能,信用卡的功能可以继承于储蓄卡,也可以继承抽象银行卡父类。但无论哪种实现方式,都需要遵从里氏替换原则,不可以破坏父类原有的方法。
信用卡类实现:
public class CreditCard extends CashCard {
public CreditCard(String cardNo, String cardDate) {
super(cardNo, cardDate);
}
public void loan(String orderId, BigDecimal amount) {
System.out.println("模拟贷款");
}
public void repayment(String orderId, BigDecimal amount) {
System.out.println("模拟还款");
}
}
信用卡类在继承父类后,使用了公用的属性,即卡号 cardNo、开卡时间cardDate,同时新增了符合信用卡功能的新方法,即贷款loan、还款repayment,并在两个方法中都使用了抽象类的核心功能。
以上的实现方式都是在遵循里氏替换原则下完成的,子类随时可以替代储蓄卡类。
以上是关于搞定里式替换原则的设计模式一篇文章就够了!!!的主要内容,如果未能解决你的问题,请参考以下文章