面向对象设计原则

面向对象设计原则

重新认识面向对象

  • 理解隔离变化:面向对象更能适应变化, 将变化带来的影响减为最小
  • 各司其职: 面向对象的方式更强调各个类的职责, 例如上节的demo, 各个图形的绘制由各个图形自己绘制, 而不是由画布来绘制
  • 什么是对象?
    • 从语言层面:对象封装了代码和数据
    • 从规格层面: 对象是一系列可被使用的公开接口
    • 从概念层面: 对象是某种拥有责任的抽象

依赖倒置原则(DIP)

  • 高层模块(稳定)不应该依赖于底层模块(变化), 二者都应该依赖于抽象(稳定)
  • 抽象(稳定)不应该依赖于细节(变化), 细节应该依赖于抽象(稳定)

上节的例子中:分解思想的demo里
MainForm依赖于Line和Rect
MainForm属于高层, 是稳定的
Line和Rect属于底层, 是变化的, 而此时MainForm依赖了低层, 违反了DIP原则

而采用另一个思想以后
MainForm依赖于Shape
而Line和Rect此时都依赖着Shape
Shape是抽象, 是稳定的, 而Line和Rect是细节, 是变化的, 符合DIP原则

至于抽象不应该依赖于实现细节, 这是什么意思呢?
Shape的抽象, 并没有依赖Line和Rect的细节, 仅有一个Draw接口, 如果此时Shape依赖于Line
有起点和终点, 那么Rect怎么办?
假如此时要引入其他的图形又怎么办, 岂不是又要更改许多内容?

记住:提出抽象类, 尽量减少细节的依赖

开闭原则(OCP)

  • 对扩展开放, 对修改关闭
  • 类模块应该是可拓展的, 但是不能被修改

修改的代价: 修改源代码, 重新编译, 重新测试
拓展: 增加到另一个文件中, 新增一个依赖抽象的细节

单一职责原则(SRP)

  • 一个类应该仅有一个引起它变化的原因
  • 变化的方向隐含着类的责任

Liskov原则(LSP)

继承:

  • 子类必须能够替换基类(IS-A:effective c++)
  • 继承表达类型抽象

如果你的子类不能替代基类, 那你可能需要组合关系, 而不是继承

接口隔离原则(ISP)

  • 不应该强迫客户程序依赖于它们不使用的接口
  • 接口应该小而完备

优先使用组合而不是继承

继承其实本质类似于:类属关系
动物和生物, 动物继承自生物, 人类继承自动物
汽车继承自交通工具, 摩托车继承自汽车

不要误用继承

  • 继承是“白箱复用”, 组合是“黑箱复用”, 因为继承暴露给子类的东西是比较多的, 或者说:子类和父类之间的耦合度比较高, 而组合只要求组合之间的对象有良好的接口, 就可以达到复用, 耦合度比较低

封装变化点

  • 使用封装来创建对象之间的分解层, 让设计者可以在分解层的一侧进行修改, 而不会对另一侧产生不良的影响, 达到解耦合的目的
    封装的本质其实是: 封装变化点: 一侧变化, 一侧稳定

针对接口编程, 而不是针对实现编程

  • 不将变量类型声明为某个具体的类, 而是声明为某个接口(非业务)
  • 客户程序无需获知对象的具体类型, 只需要知道对象所具有的接口
  • 减少系统中各个部分的依赖关系, 从而实现“高内聚, 松耦合”的设计
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值