八大面向对象设计原则
如果模式违背了设计原则,则这个模式是错误的。
一、依赖倒置原则(DIP)
高层模块(稳定)不应该依赖底层模块(变化),二者都该依赖抽象(稳定)。
抽象(稳定)不应该依赖实现细节,实现细节(变化)应该依赖抽象(稳定)。
例如A依赖B,就是A在编译时B需要存在,才能编译通过(此处的依赖通常是指编译时依赖,只有抽象在才能编译通过)。
(Before)
(After)
二、开放封闭原则(OCP)
- 对扩展开放,对更改封闭
- 类模块应该是可扩展的,但是不可修改
应该扩展(增加)文件来应对需求变化,不需要对原有的代码重新编译、测试、部署
三、单一职责原则(SRP)
一个类应该仅有一个引起它变化的原因
变化的方向隐含着类的责任
典型模式:
- Decorator
- Bridge
四、Lisov替换原则(LSP)
- 子类必须能够替换它们的基类(IS-A)
- 继承表达类型抽象
五、接口隔离原则(ISP)
不应该强迫客户程序依赖它们不用的方法
接口应该小而完备
没必要暴露的方法尽量不使用public,子类使用portected,本类使用private。否则很容易让外部程序对public的方法产生依赖
六、优先使用组合而不是继承
七、封装变化点
封装创建对象之间的分届层(变化点),一侧变化,一侧稳定
八、针对接口编程,而不是针对实现编程
1、组件合协作模式
现代软件专业分工后的第一个结果是”框架与应用程序的划分”,”组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式。
- Template Method
- Strategy
- Observer/Event
2、对象创建模式
通过“对象创建”模式绕开new,来避免对象创建过程中所导致的紧耦合(依赖具体类,new通常会带来细节依赖,违背依赖倒转原则)
1 | ISpliter fp = new PicturSpliter(); // PicturSpliter就是具体类 |
典型模式:
- Factory Method
- Abstract Factory
- Prototype
- Builder
3、对象性能模式
面向对象很好地解决了“抽象”的问题,但是不可避免地要付出一定的代价。对于通常情况,面向对象的成本大都可以忽略不计,但某些情况,面向对象所带来的成本问题必须谨慎处理。
典型模式:
- Singleton
- Flyweight
4、”接口隔离”模式
在组件构建过程中,某些接口的依赖常常会带来很多问题、甚至根本无法实现。采用添加一层间接(稳定)接口,来隔离本来互相紧密关联的接口是一种常见的解决方案。
典型模式:
- Facade
- Proxy
- Adapter
- Mediator
5、“数据结构”模式
常常有一些组件在内部具有特定的数据结构,如果客户端依赖这些特定的数据结构,将极大地破坏组件的复用。
这时候,将这些特定的数据结构封装在内部,在外部提供统一的接口,来实现与特定数据结构无关的访问,是一种行之有效的解决方案。
- Composite
- Iterator
- Chain of Responsibility