设计模式

109 阅读8分钟

设计模式

设计模式主要分为三大类

创建型设计模式主要解决“对象的创建”问题,结构型设计模式主要解决“类或对象的组合或组装”问题,那行为型设计模式主要解决的就是“类或对象之间的交互”问题。

  • 创建型 单例模式,工厂模式 | 抽象工厂,建造者,原型
  • 结构型 装饰器模式,代理模式,适配器模式 | 外观,桥接,组合,享元
  • 行为型 策略模式,观察者模式(发布订阅),中介者模式,迭代器模式 | 模板,状态,职责链,命令,访问者,备忘录,解释器

注:| 竖线后面的都是没了解过的。

个人了解比较多的有:工厂模式,单例模式,代理模式,装饰器模式,适配器模式,策略模式,观察者模式。

创建型

工厂模式&抽象工厂模式

工厂模式是创建对象的一种方式,用来创建一类(拥有相同结构属性)对象。抽象工厂模式是在工厂方法的基础上再抽象一层,用来管理多个工厂类。

单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点 。 项目中只需要存在一个实例,不需要(不允许)多个实例的存在,就是用单例模式,在使用的时候判断是否已存在,已存在则使用该实例,不存在则创建实例,后续无需创建。

建造者

用来参数需要在构造函数中初始化,但是参数又过多的场景。 参考建造者

原型

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。

结构型

适配器模式

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

装饰器

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

代理模式

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。

在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

外观模式

外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。

这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。

它和适配器模式类似,配器是做接口转换,解决的是原接口和目标接口不匹配的问题,而外观模式做接口整合,解决多接口带来的调用问题。

getUserBaseInfo() {
  return API.getUserBaseInfo();
}

getUserPriority() {
  return API.getUserPriority();
}

getUserCustomContent() {
  return API.getUserCustomContent();
}

// 对外提供一个总的接口
async getUserInfo() {
  const baseInfo = await getUserBaseInfo();
  const priority = await getUserPriority();
  const customContent = await getUserCustomContent();
  return { ...baseInfo, ...priority, ...customContent };
}

const userInfo = getUserInfo();

桥接模式(?)

桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。

这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。

注: 不太理解,感觉像是通过中间者来将双方联系在一起,中间者不做任何业务只做二者通行。(这和中介者有啥区别呢?)

组合(?)

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

享元模式(?)

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。

享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

行为型

策略模式

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

模版模式 (?)

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

观察者

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。 又称发布-订阅模式,它定义对象间的一种一对多的依赖关系。主要用于异步编程。JavaScript 本身也是一门基于事件驱动的语言,也利用了发布订阅模式。

迭代器

是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。分为内部迭代器和外部迭代器

中介者模式

中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。

定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。主要解决各个类之间关系复杂,且每个类都需要知道它要交互的类。这个时候就可以引入中介者,把脏活累活,耦合关系全放到中介者类中,我们其他类负责貌美如花。

状态模式

在状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。

在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。

状态模式的关键是区分事物内部的状态,事物内部状态的改变往往会带来事物的行为改变。举个例子,有一个电灯,电灯上面只有一个开关。当电灯开着的时候,此时按下开关,电灯会切换到关闭状态;再按一次开关,电灯又将被打开。同一个开关按钮,在不同的状态下,表现出来的行为是不一样的。

职责链

命令

访问者

在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。其次,必须定义一个访问者类,并且内部有visit方法。元素的执行算法实现accept方法,而内部通常都是visitor.visit(this)

备忘录

解释器

注:个人学习记录用