软件构造LSP原则

概念

复习到了LSP原则,也叫里氏替换原则,是软件构造当中,java的23中设计模式的6个设计原则之一,一句话来说就是在所有基类可以出现的地方,都必须可以使用子类进行替换。

这个原则的提出者是Barbara Liskov,是面向对象最重要的几大原则之一;

LSP原则与子类型多态(Behavioral subtyping)

子类型多态和LSP一个意思,Java当中,在编译的时候会进行以下规则的静态类型检查:

这里提到了协变和反协变:

协变co-variance:返回值或者参数、异常的类型只能一样或者是原来类型的子类,可以简单理解为更加具体;

反协变contra-variance:和协变相反,可以简单理解为更加宽泛;

LSP具体一些就是:

即子类必须比父类有更强的不变量,更弱的前置条件,更强的后置条件;

更强的不变量意味着,表示空间的合法子集范围更小;

更弱的前置条件意味着能够处理更多种的参数,使用者对参数的使用更加随意,开发者需要思考更多来处理不同的参数;

例子:

在编程语言中,LSP原则依赖于以下限制:

和前面所述一个性质。

集合类的子类问题

先来看一个问题:

我们知道ArrayList数组是List数组的子类型,前提是二者的元素是同一个类型的对象实例,但是如果同样是List数组,其中包含的元素是父子类关系的话,这两个list还是父子关系吗?

答案:不是

实际上,集合类型的父子关系,和集合内的元素类型的关系是完全没有关系的,那么如果我们想要实现集合类型的LSP替换应该如何做呢?

这时候就需要用到通配符   ?  了,符号 ?就是通配符;

List<?>表示一个包含元素为未知类型对象实例的List;

因此List<?>也就是所有List<Object>的一个父类(Obeject是具体的对象),可以使用List<?>来实现LSP替换:

如果想要更加具体一点,防止List<?>被不想出现的对象所替换,通配符还提供了上确界和下确界的方法:

<? super A>表示集合的元素是未知的,但是必须是A的父类或者A本身;

<? extends A>表示集合的元素是未知的,但是必须是A的子类或者A本身;

三种写法的范围关系如上;

6大设计原则

最后提一下Java当中的设计模式的6大设计原则,他们是23种设计模式的基础:

1、开闭原则(Open Close Principle)

开闭原则说的是对扩展开放,对修改关闭,在程序需要修改的时候不能修改原有的代码

2、里氏替换原则LSP

上面已经介绍过了。

3、依赖倒转原则(Dependence Inversion Principle)

抽象的模块不应该依赖于具体的模块,具体的模块应该依赖于抽象的模块;

例子:

4、接口隔离原则(Interface Segregation Principle)

客户端不应该依赖于他们不需要的方法,说人话就是你提供给客户端一个接口,这个接口可以实现若干种操作,但是每个客户端只需要用到其中的一个操作,那么这个接口的实现就是不好的,应该将其分解成多个接口,每个接口提供一种特定功能,不同的接口向不同的客户端提供服务,客户端只需要访问自己所需要的端口。

下面的接口实现是符合接口隔离原则的。

5、迪米特法原则(Demeter Principle

每个模块在系统当中应该是相对独立的,尽量做到一个类一个责任,一个功能,出了问题容易修正

6、合成复用原则(Composite Reuse Principle

尽量使用组合/聚合的方式,少用继承。

关于设计原则和设计模式的相关内容,参考了这篇文章:

Java中常用的设计模式_Superme-CSDN博客_java 设计模式

其中比较全面的介绍了23种设计模式。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值