设计模式
设计模式是描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样我们就可以对于同样的问题使用同样的解决办法。
为什么要有设计模式呢?因为软件设计本身复杂性大,复杂的根本原因在于变化,包括需求的变化,平台的变化,环境的变化等。
如何解决复杂性呢? 常用的解决办法有分解和抽象。分解是分而治之,将大问题分解为多个小问题,将复杂问题分解为多个简单的问题。抽象是更高层次的一种通用技术。由于不能掌握全部的复杂对象,我们选择忽视它的非本质细节,而去处理泛化和理想化了的对象模型。
面向对象设计原则
变化是复用的天敌,面向对象设计的最大优势在于:抵御变化。
理解面向对象可以包含三个层面的意思:1)理解隔离变化 2)类各司其职 3)对象的含义(从语言实现层面来看,对象封装了数据和代码;从规格层面讲,对象是一系列可被使用的公共接口;从概念层面讲,对象是某种拥有责任的抽象)
面向对象设计的 8 大原则:
- 依赖倒置原则
- 开发封闭原则
- 单一职责原则
- Liskov替换原则
- 接口隔离原则
- 优先使用对象组合,而不是继承
- 封装变化点
- 针对接口编程,而不是针对实现编程
设计模式的分类
从目的来看,可分为创建型,结构型,行为型。从范围来看,可分为类模式处理类与子类的静态关系;对象模式处理对象间的动态关系。
从封装变化角度对模式分类:
组件协作: Template Method, Strategy, Observer/ Event
单一职责: Decotator, Bridge
对象创建: Factory Method, Abstruct Factory, Prototype, Builder
对象性能: Sigleton, Flyweight
接口隔离: Facede, Proxy, Mediator, Adapter
状态变化: Memento, State
数据结构: Composite, Iterator, Chain of Resposibility
行为变化: Command, Visitor
领域问题: Interpreter
重构关键技法:
- 静态 -> 动态
- 早绑定 -> 晚绑定
- 继承 -> 组合
- 编译时依赖 -> 运行时依赖
- 紧耦合 -> 松耦合
策略模式
观察者模式
装饰模式
桥模式
通过“对象创建” 模式绕开new,来避免对象创建过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。
工厂方法
在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要在创建的对象的具体类型经常变化。
工厂模式是定义一个用于创建对象的接口,让子类决定实例化哪一个类。使得一个类的实例化延迟到子类。
在组建的构成中,某些接口之间直接依赖常常会带来很多问题,甚至根本无法实现。采用添加一层间接(稳定)接口,来隔离本来互相紧密关联的接口是一种常见的解决方案。
门面模式
在程序设计中,可能客户端需要和多个复杂的子系统打交道,如果客户端直接和子系统接触,这样系统的耦合度就会激增。某个子系统的变化,都会造成客户端的改变。
可以通过为子系统中的一组接口提供一个一致(稳定) 的界面,通过这个稳定的界面沟通客户端和子系统。比如API 网关的设计就是一个门面模式的例子。
代理模式
在面向对象的系统中,有些对象由于某种原因(比如对象创建的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等)直接访问会给使用者或者系统结构带来很多的麻烦。
代理模式就是为其他对象提供一种代理以控制(隔离,使用接口)对这个对象的访问。
增加一层中间层是软件系统中对于很多复杂问题的一种常见的解决方案,
适配器
在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象” 放在新的环境中应用,但是新环境要求的接口是这些现存对象所不能满足的。
将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能在一起工作的那些类可以在一起工作。