23 种设计模式
创建型模式 Creational Patterns
- 工厂方法模式
Factory Method
定义一个创建对象的接口,让子类决定实例化哪一个类。工厂方法将类的实例化延迟到子类 - 抽象工厂模式
Abstract Factory
提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。主要用来创建产品集合 - 建造者模式
Builder
将一个复杂对象的构建与它的表示分离,使得同样的构建可以创建不同的表示。隐藏了产品是如何组装的 - 原型模式
Prototype
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新对象 - 单例模式
Singleton
保证一个类只产生唯一的一个实例
结构型模式 Structural Patterns
- 适配器模式
Adapter
将类的接口转换成客户希望的接口,使得原本由于接口不兼容的类可以一起工作 - 桥接模式
Bridge
将抽象和其实现分离,具体的子类使用不同的方式去实现,从而可以独立的改变它们。体现了组合重用原则。实现独立出来各自变化,每次变化不会影响其他实现 - 组合模式
Composite
描述如何构造一个类层次式结构,这一结构有基元对象和组合对象,从而形成任意复杂的结构。强调“整体—部分”的层次结构 - 装饰模式
Decorator
动态的给一个对象添加额外职责,这种模式对增加功能比生成子类更加灵活,常见于给某个对象添加功能而不是整个类 - 外观模式
Façade
描述如何用单个对象表示整个子系统。为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口。体现了依赖倒转原则,典型场景MVC结构使用该模式;基金对股票的封装 - 享元模式
Flyweight
运用共享技术有效的支持大量细粒度的对象 - 代理模式
Proxy
为其他对象提供一种代理以控制这个对象的访问,使得只有确实需要这个对象时才创建和初始化
行为型模式 Behavioral Patterns
- 解释器模式
Interpreter
定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子 - 模板方法模式
Template Method
定义一个操作中的算法的框架,而将详细的步骤延迟到子类中。可以在不改变算法的结构下重新定义算法的步骤 - 责任链模式
Chain of Responsibility
将多个对象的请求连成一条链,并沿着这条链传递请求,直到有一个对象处理为止,避免请求的发送者和接收者之间耦合 - 命令模式
Command
将请求封装在对象中,可以作为参数来传递。可以对请求排队或记录日志,以及支持可撤销的操作 - 迭代器模式
Iterator
顺序访问一个聚合对象中各个元素,而不暴露对象内部表示 - 中介者模式
Mediator
用一个中介对象来封装一系列的对象交互。使得各对象不用显式的交互,从而使其耦合松散 - 备忘录模式
Memento
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。后期可以直接恢复 - 观察者模式
Observer
定义一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。在主题对象在状态变化时会通知所有观察者对象,使它们自动更新 - 状态模式
State
当对象的内部状态改变时允许改变其行为,该对象看起来像是改变了其类 - 策略模式
Strategy
定义一系列的算法,单独封装并使它们可以相互替换。这一模式可以使算法独立于使用它的客户而变化 - 访问者模式
Visitor
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义于作用于这些元素的新操作
7 大原则
具体为:单一职责原则、开闭原则、里氏代换原则、接口隔离原则、依赖倒置原则、组合重用原则、迪米特原则。前五个为面向对象设计和编程(OOD & OOP
)中的 S.O.L.I.D
原则。
单一职责原则 Single Responsibility (SRP)
就一个类而言,应该仅有一个引起它变化的原因。也就是说一个类应该只有一个职责,如果有多个职责相当于职责耦合了,一个职责的变化就可能影响其他职责的能力,引起类的变化。所以在构造一个类时,将类的不同职责分离到多个类中,确保引起类变化的原因只有一个。
开闭原则 Open/Closed (OCP)
软件组成实体(类、模块、函数等等)应该是可扩展的,但是不可修改。该原则认为应该设计永远不需要改变的模块,可以添加新代码来扩展系统的行为,不能对已有的代码进行修改。这个原则很好的实现了面向对象的封装性和可重用性。
里氏代换原则 Liskov's Substitution (LSP)
子类应当可以替换父类并出现在父类能够出现的任何地方。它们之间具有 is-A
关系,但是反过来是行不通的。
接口隔离原则 Dependency Inversion (DIP)
采用多个与特定客户类有关的接口比采用一个通用的涵盖多个业务方法的接口要好。这个原则本质相当简单,如果拥有一个针对多个客户的类,为每个客户都创建特定的业务接口,让客户类实现多个接口比直接加载客户所需方法有效。
依赖倒置原则 Interface Segregation (ISP)
依赖关系应该尽量依赖接口和抽象类,而不是依赖具体类。高层模块不能依赖低层模块,他们都应该依赖抽象。具体类只负责业务实现,修改具体类不影响业务相关的依赖关系。
组合重用原则
能用组合的地方尽量使用组合实现,而不要使用继承来扩展功能。组合能更好的实现封装,比继承具有更大的灵活性和更稳定的结构。
迪米特原则
如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某个方法的话,可以通过第三者转发调用。该原则指一个对象应该对于其他对象有最少的了解,有效的降低类之间的耦合。