设计模式专题-01-设计模式七大设计原则
个人github地址:HibisciDai
设计模式系列项目源码:HibisciDai/DesignPattern-LearningNotes-HibisciDai
processon在线UML类图:processon
[TOC]
设计模式-01-设计模式七大设计原则
知识储备
- 封装/继承/多态
- 抽象类
- 接口
- 静态类
- 重载(OverLoad)
- 重写/覆写(OverRide)
设计模式七大原则
单一职责原则(SRP | Single Responsibility Principle)
一个类只有一个职责
开闭原则(open for extension closed for modification)
面向对象的核心,对扩展开放对更改封闭
- eg:利用开闭原则计算A+B/A-B
pattern01.principle.demo1.ajiab
1 | public abstract class Operater { |
里氏代换原则(LSP | Liskow Substitution Princciple)
子类替换掉父类,后程序正常运行且结果跟预测相同才能允许继承,满足里氏代换原则才可以继承
如果父类的某些方法在子类中发生畸变,建议断开父子关系,拒绝子类有自己的个性
- eg1.
正方形长方形的判断
当长大于等于宽时,宽+1
这时不能继承 - eg2.
A依赖B,B改影响A的结果,依赖是单向的。
依赖倒转原则(Dependence Inversion Principle)
针对接口编程,不针对实现编
高层不依赖底层,依赖抽象
- eg1.
电灯和开关应该各自依赖接口(通电协议) - eg2.
司机和车
修改前类图:
修改后类图:
代码:
修改前
pattern01.principle.demo2.caranddriver.after
1 | public class Benz { |
修改后
pattern01.principle.demo2.caranddriver.before
1 | public class Benz implements ICar { |
接口隔离原则(ISP | Interface Segregation Principle)
客户端不应该依赖它不需要的方法,类间的依赖关系应建立在最小的接口上
接口功能太多,实现接口可能不会完成全部方法实现(胖接口造成了对接口的污染)即一个接口只做一件事情
- eg1
接口污染情况
1 | interface Iwork{ |
处理后的代码情况
1 | interface IWorkEat { void eat(); } |
合成/聚合复用原则(ARP | Composite/Aggregate Reuse Priciple)
构造函数中出现其他类/类使用调用其他类
合成
强烈的关联,部分(将)和整体(主)生命周期一样,整体(主)对部分(将)有支配权,,包括创建
和销毁
在构造函数参数或内部有其他类
聚合
部分和整体的普通关联
在类的内部使用或调用其它类
合成与聚合的区别
生命周期
合成:A死,B也死,且B必在A中使用
聚合:A死,B/C不一定结束
案例:
ARP原则
尽量使用合成/聚合,而不是使用即继承
- 继承的优点
新的实现较为容易,因基类的大部功能可以通过继承的关系自动进入子类,修改和扩展继承而来的实现较为容易。 - 继承的缺点
继承将基类的实现细节暴露给子类,称为”白箱”复用。如果其基类发生改变,那么子类的实现也不得不发生改变。多继承不利于维护。
- ARP优点
- 依赖少,条条框框的限制少
- 几乎可以用到任何环境中
- 容易实现
- 修改和扩展容易
- 缺点
- 对象多,需要管理
迪米特原则(LOR | The Law of Demeter)
不要和陌生人说话,最少知识原则,中介
优点
- 相当弱的类耦合
- 利于复用
- 只要有可能,类就可以设计
缺点
- 小范围散落
- 传递
- 引起困惑
- 应用实例
DOT(Date Trausfer Object)数据传输对象
主要类关系
继承
实现
依赖
类A的某个成员方法的返回值、形参、局部变量或静态方法的调用,则表示类A引用了类B
关联
关联关系有单向关联、双向关联、自身关联、多维关联。
较依赖关系较强,发生依赖关系的两个类都不会增加属性。
聚合
整体与部分、拥有的关系
组合
较聚合更强
同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束。