面向对象设计(2)

面向对象设计原则

  • 单一职责原则 (SRP)
  • 开闭原则 (OCP)
  • Liskov 替换原则 (LSP)
  • 接口隔离原则 (ISP)
  • 依赖倒置原则 (DIP)

  • SOLID

OCP: 开闭原则

  • 软件模块对扩展是开放的
    • 当需求发生改变时,可以对模块进行扩展
  • 软件模块对修改是封闭的
    • 对模块进行扩展时, 无须改动模块的源代码。
  • 似乎是矛盾的 ?

面向对象设计的原则 (2) : 开闭原则

这里写图片描述

这里写图片描述

  • 缺点:

    • 对扩展开放: 可以添加新的水果类
    • 但是每次添加新的水果类,就需要修改ShopCart中的逻辑 !
  • 重构后

这里写图片描述

这里写图片描述

这里写图片描述

  • 对扩展开放
    • 可以任意的添加新的水果类:香蕉,西瓜…
  • 对修改是封闭的
    • 对于ShopCart中的计算逻辑不用修改。
  • 模块依赖于一个固定抽象体,所以对于更改是关闭的。同时通过这个抽象体派生,也可以扩展此模块的行为。所以关键是抽象 !

例子

这里写图片描述

这里写图片描述

这里写图片描述

重构后

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

  • 在许多方面,OCP都是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处(也就是 灵活性,可重用性,以及可维护性)。然而,并不是说只要使用一种面向对象语言遵循了这个原则。对于应用程序中的每个部分都肆意的进行抽象并不是一个好的主意。正确的做法是,开发人员应该仅仅对程序中频繁出现的变化的那部分做出抽象。拒接不成熟的抽象和抽象本身一样重要。

Liskov 替换原则 (LSP)

  • 子类型能够完全替换父类型,而不会让调用父类型的客户程序从行为上有任何改变
  • 难道多态不就是为了达到这个目标吗?

LSP: 正方形 is a 长方形?

这里写图片描述

这里写图片描述

这里写图片描述

LSP: 鸟都会飞吗

这里写图片描述

某个程序员创建了一个鸵鸟类

这里写图片描述

这里写图片描述

  • 继承的目的

    • 重用父类的代码
    • 更重要的是, 复用那些使用父类的代码(例如processAll)!!
  • LSP实际上是确保我们做的抽象不会被子类破坏

LSP和契约式设计

  • Bertrand Meyer 在 1988 年阐述了 LSP 原则与契约式设计之间的关系。使用契约式设计,类中的方法需要声明前置条件和后置条件。前置条件为真,则方法才能被执行。而在方法调用完成之前,方法本身将确保后置条件也成立。

  • Rectangle.setWidth的后置条件

    • Assert (( width==w ) && (height == old.height))
    • 很明显, Square 违反了这个后置条件
  • 当通过基类(父类)的接口使用对象时, 用户只知道基类的前置条件和后置条件

  • 派生类(子类) 只能使用相等或者更弱的前置条件类替换父类的前置条件

接口隔离原则(ISP)

  • 客户端不应该依赖它不需要的接口

  • 类间的依赖关系应该建立在最小的接口上

    • 使用多个专门的接口比使用单一的总接口要好。
  • 防止接口污染

ISP: ATM例子

这里写图片描述

ISP: 咖啡机例子

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

重构后

这里写图片描述

这里写图片描述

依赖倒置原则(DIP)

  • 高层模块不应该依赖于低层模块,二者都应该依赖于抽象
  • 抽象不应该依赖于细节。细节应该依赖于抽象。

这里写图片描述

这里写图片描述

DIP: 熔炉的例子

这里写图片描述

这里写图片描述

这里写图片描述

DIP: 打印机的例子

这里写图片描述

重构后

这里写图片描述

  • 使用传统的过程化程序设计所创建出来的依赖关系结构,策略是依赖于细节的。这样会导致策略受到细节改变的影响。面向对象的程序设计倒置了依赖关系结构,使得细节和策略都依赖于抽象,并且常常是客户拥有服务接口。

  • 依赖关系的倒置正好是面向对象设计的标志所在。如果程序的的依赖关系是倒置的,他就是面向对象的设计。如果程序的依赖关系不是倒置的它就是过程化的设计。

  • 依赖倒置原则对于创建可重用框架来说是必须的。同时对于构建在变化面前富有弹性的代码也是非常重要的。由于抽象和字节被彼此隔离,所以代码也非常容易维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值