Skip to main content

设计模式

概念

模式名称

模式的助记名

问题

应在何时使用模式

解决方案

描述设计模式的组成成分

效果

模式的应用效果和使用该模式应权衡的问题

创建型设计模式

该类设计模式抽象了实例化过程

抽象工厂

提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类型

解决方案

  • 🤓Client.class:客户端,用于调用抽象的接口,而不用关心接口具体的实现
  • 🤓AbstractFactory.class:抽象工厂的接口
  • 🤓AbstractProduct.class:产品的接口
  • 😎MonoFactory:AbstractFactory.class:工厂的一种实现
  • 😎Mono:AbstractProduct.class:产品的一种实现

生成器

将一个复杂对象的构建与它的表示分离,使得相同构建过程可创建不同表示

解决方案

  • 🤓Director.class:构造 Builder,是 Builder 的聚集
  • 🤓Builder.class:构造器的接口
  • 🤓Product.class:产品的接口
  • 😎PartBuilder:Builder.class:Builder 的一种实现
  • 😎Part:Product.class:产品的一种实现

工厂方法

定义一个用于创建对象的接口,让子类决定实例化哪个类

解决方案

  • 🤓Creator.class:工厂的接口
  • 🤓Product.class:产品的接口
  • 😎MonoCreator:Creator.class:工厂的一种实现
  • 😎Mono:Product.class:产品的一种实现

原型

用原型实例指定创建对象的种类,并通过复制这些原型创建新的对象

解决方案

  • 🤓Client.class:操纵原型复制自身产生新对象
  • 😎Prototype.class:原型声明一个复制自身的接口
  • 😎Mono:Prototype.class:原型的一种实现

单例

保证一个类有且仅有一个实现,并提供全局访问点

解决方案

  • 🤓Singleton.class:隐藏构造器,并提供一个静态的自身类型的实例供外部访问

结构型设计模式

考虑如何组合类和对象以获得更大的结构

适配器

问题

将一个类的接口转换成另一个接口使得原本不兼容的两个接口可以一起工作

实施

🚧 类设计完成后

解决方案

  • 🤓Client.class:对接 Target 和 Adaptee 接口,实则调用了 Adapter 与 Adaptee 进行通信
  • 🤓Target.class:对接到 Adaptee 上,不支持 Adaptee 的接口格式
  • 🤓Adaptee.class:处理消息/操作的接口
  • 🤓Adapter.class:Target.class:使 Target 的消息格式与 Adaptee 兼容

桥接

问题

使抽象部分和实现部分分离,使他们可以独立变化

实施

🚧 类设计前

解决方案

  • 🤓Abstraction.class:定义一个抽象的接口,其维护一个指向实现的指针
  • 🤓Implementor.class:定义实现类的接口
  • 🤓RefinedAbstraction:Abstraction.class:扩充 Abstraction 接口
  • 🤓MonoImplementor:Implementor:Implementor 的一种实现

组合

问题

将对象组合成树形结构以表示部分/整体,使得对单个对象的操作和对整体的操作有一致性

实施

  • 基于递归组合组织可变数目对象
  • 🚧 通常和装饰器协同使用

解决方案

  • 🤓Composite.class:定义组合对象的接口
  • 🤓Component:Composite.class:实现 Composite 接口,提供堆子元素集合的操作
  • 🤓Leaf:Composite.class:实现 Composite 接口,叶节点无字元素

装饰器

问题

动态地给一个对象添加额外的职责

实施

  • 基于递归组合组织可变数目对象
  • 🚧 通常和组合协同使用

解决方案

  • 🤓Component.class:定义对象的接口,可以给这些对象动态添加职责
  • 🤓Decorator.class:装饰器接口,维护一个指向 Component 的指针
  • 🤓MonoDecorator:Decorator.class:装饰器的一种实现,在实现接口时拦截 Decorator 的操作或属性

代理

问题

为其他对象提供一种代理以控制对这个对象的访问

实施

🚧 不能动态地添加或者分离属性

解决方案

  • 🤓Subject.class:描述 RealSbject 的接口
  • 🤓RealSubject:Subject.class:Subject 的一种实现
  • 🤓Proxy:RealSubject.class:代理
  • 🤓Client.class:在任何使用 RealSubject 的地方都可以使用 RealSubject

外观

为一组接口提供一个一致的界面

解决方案

  • 🤓Facade.class:为子系统中的类向外提供统一界面(接口)
  • 🤓subsystem.pakage:子系统中的各个类

享元

利用共享及时有效地支持大量细粒度操作

解决方案

  • 🤓Flyweight.class:描述享元对象的接口
  • 🤓FlyweightFactory.class:享元工厂(创建和管理享元)
  • 🤓MonoFlyweight:Flyweight.class:享元的一个实现
  • 🤓Client.class:调用享元工厂并引用其创建的享元对象

行为设计模式

责任链

问题

使多个对象都有机会处理请求,从而避免发送者和接收者的耦合

实施

解决方案

  • 🤓Handler.class:描述处理请求的接口
  • 🤓MonoHandler.class:请求处理器的一种实现
  • 🤓Client.class:向责任链上的处理器提交请求

命令

问题

  • 将一个请求封装为对象
  • 对请求排队
  • 记录请求日志
  • 支持可撤销的操作

实施

解决方案

  • 🤓Command.class:描述处理请求的接口
  • 🤓MonoCommand:Command.class:请求处理器的一种实现
  • 🤓Invoker<>Command.class:执行请求处理器
  • 🤓Reciver.class:接收者

解释器

问题

给定一个语言,定义这种语言的一种文法表示,并定义一个解释器

实施

解决方案

  • 🤓Client.class:构建语法树(由 NonterminalExpression 和 TerminalExpression 组成)
  • 🤓Context.class:全局信息
  • 🤓AbstractExpression.class:请求处理器的一种实现
  • 🤓NonterminalExpression<>:AbstractExpression.class:非终结符解释器
  • 🤓TerminalExpression:AbstractExpression.class:终结符解释器

迭代器

问题

提供一种方法顺序访问一个聚合对象中的各元素,而无须关注该对象的内部表示

实施

解决方案

  • 🤓Aggregate.class:可迭代对象接口
  • 🤓Iterator.class:迭代器接口
  • 🤓MonoAggregate:Aggregate-->MonoIterator.class:可迭代对象接口的一种实现
  • 😎MonoIterator:Iterator==>MonoAggregate.class:迭代器的具体实现

中介

问题

用中介描述一系列对象的交互,使得各对象不需要显式地相互引用

实施

解决方案

  • 🤓Mediator.class:中介,定义一个用于各同事通信的接口
  • 🤓Colleague.class:同事,定义同事的规范,同事知道自己的中介
  • 🤓MonoMediator:Mediator.class:中介的一种实现
  • 😎MonoColleague:Colleague==>MonoMediator.class:同事的一种实现

备忘录

问题

在不破坏封装的前提下捕获一个对象的内部状态,并在对象外保存,使得对象可以和恢复到该状态

实施

解决方案

  • 🤓Memento.class:备忘录,存储原发器的内部状态
  • 🤓Originator.class:原发器,创建备忘录
  • 🤓Caretacker<>Memento.class:保存备忘录

观察者

问题

定义对象间的一种一对多的的依赖关系,当一个对象状态发生改变时,所有依赖该对象的对象都得到通知

实施

解决方案

  • 🤓Subject.class:目标,知道其观察者,提供注册和删除观察者对象的接口
  • 🤓Observer.class:观察者,为需要获得目标变化通知的对象提供一个接口
  • 🤓MonoSubject:Subject.class:具体目标实现
  • 🤓MonoObserver:Observer.class:具体观察者实现

状态

问题

允许一个对象在其内部状态发生改变时改变其行为,看起来像是对象的类型改变了

实施

解决方案

  • 🤓Context.class:状态上下文
  • 🤓State.class:定义状态的接口,表示上下文特定的状态的行为
  • 🤓MonoState:State.class:状态的一种实现

策略

问题

定义一系列的算法,把他们封装起来,并使他们可以相互替换,使得算法可以独立于使用他们的客户而变化

实施

解决方案

  • 🤓Strategy.class:定义所有支持的算法的公共接口
  • 🤓Context.class:维护一个对 Strategy 对象的引用,定义一个接口使 Strategy 可访问当前上下文的数据
  • 🤓MonoStrategy:Strategy.class:策略的一种实现

模板方法

问题

定义一个操作中的算法骨架,从而将一些步骤延迟到子类中

实施

解决方案

  • 🤓AbstractClass.class:定义抽象的原语操作
  • 🤓MonoClass:AbstractClass.class:实现原语操作

访问者

问题

表示一个用于某对象结构中的各元素的操作,允许在不改变元素的类的前提下定义作用于这些类的新操作

实施

解决方案

  • 🤓Visitor.class:定义访问者接口
  • 🤓Element.class:定义元素接口
  • 🤓MonoVisitor.class:Visitor 的一种实现
  • 🤓Mono:Element.class:元素的一种实现