夯实设计原则之里氏替换原则
2021/5/14 18:26:40
本文主要是介绍夯实设计原则之里氏替换原则,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
All Rights Reserved © jackiegu.cn
理念:
所有引用基类(父类)的地方必须能透明的使用其子类的对象;
在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象;如:小明喜欢动物,那么他一定喜欢猫,因为猫是动物的子类;反过来,小明喜欢猫,不能据此断定出他喜欢动物,可能他并不喜欢狗,虽然狗也是动物;
里氏替换原则是实现开闭原则的重要方式之一,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,再在运行时确定其子类类型,用子类对象来替换父类对象;
案例:
小明在工作中接到一个需求,需要为项目中的普通用户和VIP用户发送短信;于是他先定义了两个用户类:NormalUser
普通用户、VipUser
VIP用户,如下:
/** * 普通用户 */ public class NormalUser { private String name; private String mobileNo; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMobileNo() { return mobileNo; } public void setMobileNo(String mobileNo) { this.mobileNo = mobileNo; } }
/** * VIP用户 */ public class VipUser { private String name; private String mobileNo; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMobileNo() { return mobileNo; } public void setMobileNo(String mobileNo) { this.mobileNo = mobileNo; } }
然后他再定义了一个短信发送器类SmsSender
,里面分别实现了对普通用户和VIP用户的短信发送功能,如下:
/** * 短信发送器 */ public class SmsSender { /** * 给普通用户发送短信 * * @param normalUser 普通用户 */ public void send(NormalUser normalUser) { System.out.println("发送短信给用户: " + normalUser.getMobileNo()); } /** * 给VIP用户发送短信 * * @param vipUser VIP用户 */ public void send(VipUser vipUser) { System.out.println("发送短信给用户: " + vipUser.getMobileNo()); } }
从上面的案例来看, SmsSender
类中给普通用户和VIP用户发送短信的逻辑是一样的,很明显的有代码重复;而且在项目中如果新增了一种超级用户
的用户类型,也需要发送短信时,那就不得不修改SmsSender
类的代码,也就违背了开闭原则;
同样是上面的案例,当懂得里氏替换原则的小红遇到时,会怎样来设计呢?接下来请看:
首先定义一个用户行为接口类IUser
,如下:
/** * 用户行为接口 */ public interface IUser { String getName(); void setName(String name); String getMobileNo(); void setMobileNo(String mobileNo); }
然后再重新定义普通用户NormalUser
和VIP用户VipUser
类,让这两个用户类都实现IUser
接口,如下:
/** * 普通用户 */ public class NormalUser implements IUser { private String name; private String mobileNo; @Override public String getName() { return name; } @Override public void setName(String name) { this.name = name; } @Override public String getMobileNo() { return mobileNo; } @Override public void setMobileNo(String mobileNo) { this.mobileNo = mobileNo; } }
/** * VIP用户 */ public class VipUser implements IUser { private String name; private String mobileNo; @Override public String getName() { return name; } @Override public void setName(String name) { this.name = name; } @Override public String getMobileNo() { return mobileNo; } @Override public void setMobileNo(String mobileNo) { this.mobileNo = mobileNo; } }
最后重新定义短信发送器类SmsSender
,如下:
/** * 短信发送器 */ public class SmsSender { /** * 给用户发送短信 * * @param user 用户 */ public void send(IUser user) { System.out.println("发送短信给用户: " + user.getMobileNo()); } }
从上面小红的代码来看, SmsSender
类中给不同用户发送短信的重载方法已不存在,同时新增了一个以IUser
为参数的发送短信的方法,以后不管为什么类型的用户类型发送短信,都可以采用这个方法;解决了小明版本的代码重复问题,同时在新增用户类型发送短信时也不用去修改SmsSender
类的代码,遵循了开闭原则,SmsSender
类的send
方法的IUser
参数也遵循了里氏替换原则;
这篇关于夯实设计原则之里氏替换原则的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-24Java中定时任务实现方式及源码剖析
- 2024-11-24Java中定时任务实现方式及源码剖析
- 2024-11-24鸿蒙原生开发手记:03-元服务开发全流程(开发元服务,只需要看这一篇文章)
- 2024-11-24细说敏捷:敏捷四会之每日站会
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解