简介

七大原则

  1. 单一职责原则(Single Responsibility Principle)

    每个类都应该 只负责一项职责,并且该功能应该由这个类完全封装起来。

  2. 开闭原则(Open Close Principle)

    当程序需要扩展的时候,尽量不修改原有代码,实现「热拔插」功能,便于维护与升级。

  3. 里氏代换原则(Liskov Substitution Principle)

    任何基类可出现的地方,子类都可以出现并正常使用,从而实现复用。

  4. 依赖倒转原则(Dependence Inversion Principle)

    针对接口编程,依赖于抽象而不依赖于具体。

  5. 接口隔离原则(Interface Segregation Principle)

    使用多个隔离的接口比使用单个接口要好,降低程序耦合度

  6. 迪米特法则(Demeter Principle)

    一个实体应当 尽量少与其他实体发生相互作用,使得系统功能模块相对独立。

  7. 合成复用原则(Composite Reuse Principle)

    优先使用对象组合,少用继承。

C 创造型(Creational)

工厂(Factory)*

工厂模式(Factory Pattern):通过一个结构根据不同条件创建不同实例,同时不暴露创建逻辑。

  • (+) 根据不同条件创建不同实例,且隐藏创建逻辑。

抽象工厂(Abstract Factory)

抽象工厂模式(Abstract Factory Pattern):与 工厂模式 类似,但它创建的不是一个对象(例如一件衬衫),而是一套不同类的对象组合(例如一套西装,包括衬衫对象、西装裤对象、西装外套对象)。

  • (+) 保证只使用某一套对象组合,而不会错用混用。
  • (-) 扩展比较麻烦,为某个组合增加对象时,需要改动抽象工厂代码。

单例(Singleton)*

单例模式(Singleton Pattern):对于某个单例类,它有且只有同一个对象被创建和访问。

  • (+) 内存中只有一个对象实例,减少内存开销,避免频繁创建、销毁实例。
  • (-) 违背了单一职责原则,一个类应该只负责一件事,并且只关心内部逻辑,不应该关心外界怎么实例化。

建造者(Builder)

建造者模式(Builder Pattern):使用多个简单对象一步一步构建成一个复杂对象,例如创建麦当劳 A 套餐对象时要先创建汉堡对象、薯条对象、可乐对象,然后组装之后返回该套餐对象。

  • (+) 易扩展,便于控制创建细节。
  • (-) 内部变化可能比较复杂。

原型(Prototype)

原型模式(Prototype Pattern):对可能重复创建的对象(即 原型)进行缓存,然后在需要创建该对象时返回它的拷贝,例如某个需要进行高代价的数据库操作之后才能创建的对象。

  • (+) 性能较高。
  • (-) 使用场景需要考虑该类的全部功能,防止冲突或者调用出错。

S 结构型(Structural)

适配器(Adapter)*

适配器模式(Adapter Pattern):连接两个不兼容的接口。

  • (+) 灵活,可以连接任意两个不适配的类,有利于类的复用。
  • (-) 容易看起来混乱,例如表面上调用了 A 接口但实际上经过适配器调用了 B 接口。

桥接(Bridge)

桥接模式(Bridge Pattern):将一个类的抽象与实现解耦,从而使得他们可以独立变化,例如将开关类的抽象(开、关操作)与实现(怎么开、怎么关)解耦。

  • (+) 分离抽象与实现,实现对用户透明,且便于扩展。
  • (-) 增加系统的理解和设计难度。

过滤器(Filter)

过滤器模式(Filter Pattern):使用不同过滤器(实现过滤的类)来过滤一组对象,并且通过逻辑运算(自己写的类)将他们连接,实现任意组合的过滤功能。

组合(Composite)

组合模式(Composite Pattern):将一组相似对象组合起来,可以进行同样的操作,例如员工类、部门类都实现了「自我介绍」方法,部门对象中包含多个员工对象,当调用部门对象的该方法时,会逐一调用员工对象的该方法。

  • (+) 通过高层统一调用比较方便,而且里面的对象可以随意增减。
  • (-) 组合的时候,把高层类跟里面的具体类依赖在一起了。

装饰器(Decorator)*

装饰器模式(Decorator Pattern):在现有的类的外层进行一层包装(装饰类),从而可以添加新的功能(例如运行计时)又不改变其结构。

  • (+) 动态扩展类的功能。
  • (-) 多层装饰比较复杂。

外观(Facade)

外观模式(Facade Pattern):在客户端和复杂系统之间增加一个接口,客户端只需要通过该接口即可访问系统,从而隐藏了系统的复杂性。

  • (+) 减少系统相互依赖,提高灵活性。
  • (+) 安全性更好。

享元(Flyweight)

享元模式(Flyweight Pattern):尝试重用现有的同类对象,如果未找到匹配的对象再创建新对象,从而减少内存占用和提高性能。

  • (+) 减少对象的创建,降低系统的内存,提高效率。
  • (-) 增加了复杂度。

代理(Proxy)

代理模式(Proxy Pattern):用一个类 A 来代理另一个类 B,访问 B 的功能需要通过 A。

  • (+) 既有高扩展性,又隐藏了实现细节。
  • (-) 代理需要代价。

B 行为型(Behavioral)

责任链(Chain of Responsibility)*

责任链模式(Chain of Responsibility Pattern):为请求创建了一个接收者对象的链,每个接收者都包含对另一个接收者的引用。如果自身不能处理该请求,则把相同请求传给下一个接收者,依此类推。

  • (+) 将请求的发送者和接收者解耦,大大降低耦合度,相互不需要知道对方。
  • (+) 增强给对象指派职责的灵活性,并且可以很方便地动态新增或者删除接受者,改变责任。
  • (-) 不能保证请求一定被接收。

命令(Command)

命令模式(Command Pattern):请求以命令的形式包裹在对象中,并传给调用对象。

  • (+) 降低系统耦合度,容易增加新的命令。
  • (-) 增加了不确定性,可能有安全风险。

解释器(Interpreter)

解释器模式(Interpreter Pattern):实现一个解释器,该解释器可以解析一句「语言」,输出「翻译」或者做出对应操作。

  • (+) 灵活。
  • (-) 太灵活,有点飘。
  • (-) 随着功能的增加,定义的语法可能会越来越复杂,难以维护。

迭代器(Iterator)*

迭代器模式(Iterator Pattern):提供一个接口顺序访问一个聚合对象中的各个元素,无须暴露该对象的内部表示。

  • (+) 无须暴露细节。
  • (+) 支持以不同方式遍历,增加或者删除新的遍历方法都很容易。

中介者(Mediator)

中介者模式(Mediator Pattern):提供一个中介类来处理不同类之间的通信。

  • (+) 降低类的复杂度,从多对多(n^2)转化为多对一、一对多(n + n)。
  • (-) 中介者比较复杂。

备忘录(Memento)

备忘录模式(Memento Pattern):保存一个对象的某个状态,以便在适当的时候恢复对象。

  • (+) 提供了恢复功能,并且隐藏了细节。
  • (-) 消耗资源。

观察者(Observer)*

观察者模式(Observer Pattern):定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

  • (+) 不需要每个观察者都定期查看被观察者,而是被观察者主动通知,高效。
  • (-) 实现不好可能搞出循环调用。

状态(State)*

状态模式(State Pattern):允许对象在内部状态发生改变时改变它的行为(例如某个方法的执行内容)。

  • (+) 灵活,根据不同状态执行不同行为。
  • (-) 需要预先定义好状态,和每种状态下的行为。

空对象(Null Object)

空对象模式(Null Object Pattern):对于继承了某个抽象类的实体类,如果我们调用其某个方法(例如根据在数据库中查询的某个商品的 ID 输出价格),往往要先判断它是否为空(例如该商品没有 ID),因此可以另外写一个类继承该抽象类,对每个方法的实现都为写为「do nothing」,来代替这里的空判断。

  • (+) 不需要手动判断其是否为空再调用方法。

策略(Strategy)*

策略模式(Strategy Pattern):对于某个方法有多种实现(即策略),在不同的场景中使用不同实现(例如传入构造函数)。

  • (+) 根据不同场景使用不同策略。
  • (-) 调用者必须知道到底有哪些策略才能调。

模板(Template)

模板模式(Template Pattern):定义某一个方法中的「骨架」,将一些步骤的具体实现延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

  • (+) 封装不变的部分(父类实现整体框架),扩展可变的部分(子类实现步骤内具体行为)。
  • (-) 每一个不同的实现可能都需要一个子类来实现,容易变得复杂。

访问者(Visitor)

访问者模式(Visitor Pattern):封装一些对某种数据结构中的元素的操作,从而在不改变这个数据结构的前提下作用于这些元素。例如某人访问电脑对象时会使用 Safari 对象、微信对象、网易云音乐对象,另一个人访问时则会使用 Chrome 对象、Sublime 对象、iTerm2 对象,他们都是对电脑对象的访问(即操作),但是不会改变电脑对象的数据结构。

  • (+) 比较灵活,容易扩展。
  • (-) 访问者需要知道具体元素细节。

参考