设计模式介绍

 2024-07-29    0 条评论    74 浏览

设计模式

设计模式是面向对象设计中的重要概念,旨在解决软件开发中的各种常见问题。以下是对常见设计模式的详细介绍,涵盖每种模式的目的、结构、优缺点和使用场景。

设计模式一般分为三大类,创建型模式结构型模式行为型模式

创建型模式

  1. 单例模式(Singleton Pattern)

    • 目的:确保一个类只有一个实例,并提供一个全局访问点。
    • 结构
      • Singleton:包含一个静态实例和一个获取实例的静态方法。
    • 优点
      • 确保唯一性。
      • 全局访问。
    • 缺点
      • 可能会有线程安全问题。
    • 使用场景
      • SpringBoot容器化实例管理。
      • 大对象复用。
      • 连接池。
  2. 工厂方法模式(Factory Method Pattern)

    • 目的:定义一个创建对象的接口,有不同的实例化类,通过工厂类决定具体实例化的类,一般通过工厂类方法的参数决定实例化类型。
    • 结构
      • Creator:声明创建产品的方法。
      • ConcreteCreator:实现创建产品的方法。
      • Product:定义产品的接口。
      • ConcreteProduct:实现产品接口。
    • 优点
      • 隐藏对象创建的具体细节。
      • 支持开放/关闭原则。
    • 缺点
      • 需要创建一个新的子类。
      • 增加系统复杂性。
    • 使用场景
      • 当系统需要独立于产品的创建、组合和表示时。
      • 产品类的创建过程比较复杂。
  3. 抽象工厂模式(Abstract Factory Pattern)

    • 目的:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
    • 结构
      • AbstractFactory:声明创建一系列产品的方法。
      • ConcreteFactory:实现创建具体产品的方法。
      • AbstractProduct:声明一系列产品的接口。
      • ConcreteProduct:实现具体产品接口。
    • 优点
      • 抽象创建过程。
      • 支持产品族的变化。
    • 缺点
      • 增加系统的复杂性。
    • 使用场景
      • 需要创建一组相关对象时。
      • 需要保证产品的一致性。
  4. 建造者模式(Builder Pattern)

    • 目的:通过逐步构建复杂对象,允许不同的表示。
    • 结构
      • Builder:定义创建产品的步骤。
      • ConcreteBuilder:实现具体的构建过程。
      • Director:指导构建过程。
      • Product:表示复杂的对象。
    • 优点
      • 分离构建和表示。
      • 适合创建复杂对象。
    • 缺点
      • 增加了构建复杂性。
    • 使用场景
      • 需要构建复杂对象,并希望分步构建。
      • 不同的构建过程产生不同的表现形式。
  5. 原型模式(Prototype Pattern)

    • 目的:通过复制现有对象来创建新的对象。
    • 结构
      • Prototype:定义一个用于复制自身的接口。
      • ConcretePrototype:实现复制方法。
    • 优点
      • 可以避免重复创建对象。
      • 动态配置和调整。
    • 缺点
      • 需要实现克隆方法。
      • 可能会导致额外的复杂性。
    • 使用场景
      • 对象的创建成本较高时。
      • 需要复制对象而不是重新创建。

结构型模式

  1. 适配器模式(Adapter Pattern)

    • 目的:将一个类的接口转换成客户希望的另一个接口。
    • 结构
      • Target:定义客户希望的接口。
      • Adaptee:需要适配的现有接口。
      • Adapter:实现目标接口,委托给适配者。
    • 优点
      • 使接口不兼容的类可以协同工作。
      • 代码复用。
    • 缺点
      • 可能会增加系统的复杂性。
    • 使用场景
      • 需要使不兼容的接口能够合作时。
      • 将旧系统与新系统连接。
  2. 装饰器模式(Decorator Pattern)

    • 目的:动态地给对象添加一些额外的职责。
    • 结构
      • Component:定义对象的接口。
      • ConcreteComponent:实现组件接口。
      • Decorator:维护一个指向组件对象的引用,并实现组件接口。
      • ConcreteDecorator:扩展装饰的功能。
    • 优点
      • 动态添加功能。
      • 避免了类爆炸问题。
    • 缺点
      • 可能会导致大量的小类。
    • 使用场景
      • 需要在运行时动态地扩展对象的功能时。
      • 避免使用子类来扩展功能。
  3. 代理模式(Proxy Pattern)

    • 目的:为其他对象提供一种代理以控制对这个对象的访问。
    • 结构
      • Subject:定义客户端可以访问的接口。
      • RealSubject:实现具体的业务逻辑。
      • Proxy:实现Subject接口,并控制对RealSubject的访问。
    • 优点
      • 可以控制对对象的访问。
      • 实现延迟加载和权限控制。
    • 缺点
      • 可能会增加系统的复杂性。
    • 使用场景
      • 需要对对象的访问进行控制时。
      • 实现延迟加载、缓存、权限验证。
  4. 桥接模式(Bridge Pattern)

    • 目的:将抽象部分与实现部分分离,使它们可以独立变化。
    • 结构
      • Abstraction:定义抽象接口。
      • RefinedAbstraction:扩展Abstraction。
      • Implementor:定义实现接口。
      • ConcreteImplementor:实现具体的实现接口。
    • 优点
      • 降低了抽象与实现之间的耦合。
      • 支持独立扩展。
    • 缺点
      • 增加了系统的复杂性。
    • 使用场景
      • 需要在不同维度上扩展系统时。
      • 需要分离抽象和实现的层次结构。
  5. 组合模式(Composite Pattern)

    • 目的:将对象组合成树形结构以表示部分-整体层次结构。
    • 结构
      • Component:定义叶子和容器的共同接口。
      • Leaf:叶子节点,表示树中的基本元素。
      • Composite:容器节点,包含叶子和其他Composite。
    • 优点
      • 允许客户端一致地对待单个对象和对象组合。
      • 简化了客户端代码。
    • 缺点
      • 可能会导致过度设计。
    • 使用场景
      • 需要处理树形结构或层次结构时。
      • 需要对单一对象和对象组合进行统一处理。
  6. 外观模式(Facade Pattern)

    • 目的:为子系统中的一组接口提供一个一致的接口,使子系统更易于使用。
    • 结构
      • Facade:提供简化的接口。
      • Subsystem Classes:实现子系统的具体功能。
    • 优点
      • 提供简化的接口,减少复杂性。
      • 隐藏子系统的复杂性。
    • 缺点
      • 可能会导致Facade成为系统的单点故障。
    • 使用场景
      • 需要简化复杂子系统的接口时。
      • 为系统提供统一的访问入口。
  7. 享元模式(Flyweight Pattern)

    • 目的:通过共享对象来有效地支持大量细粒度的对象。
    • 结构
      • Flyweight:定义接口,并实现共享的部分。
      • ConcreteFlyweight:实现具体的共享对象。
      • FlyweightFactory:管理和创建Flyweight对象。
    • 优点
      • 减少了对象的创建和内存消耗。
      • 提高了系统性能。
    • 缺点
      • 增加了对象的管理复杂性。
    • 使用场景
      • 需要处理大量相似对象时。
      • 需要节省内存和提高性能时。

行为型模式

  1. 观察者模式(Observer Pattern)

    • 目的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
    • 结构
      • Subject:声明附加和删除观察者的方法。
      • ConcreteSubject:实现通知机制。
      • Observer:定义更新接口。
      • ConcreteObserver:实现更新接口。
    • 优点
      • 实现了对象间的松耦合。
      • 支持广播通信。
    • 缺点
      • 可能导致过多的更新操作。
    • 使用场景
      • 当一个对象的状态改变需要通知多个其他对象时。
      • 需要实现发布/订阅机制时。
  2. 策略模式(Strategy Pattern)

    • 目的:定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换。
    • 结构
      • Strategy:定义策略接口。
      • ConcreteStrategy:实现具体策略。
      • Context:使用策略的上下文。
    • 优点
      • 算法的选择在运行时进行。
      • 算法可以独立于客户端变化。
    • 缺点
      • 增加了系统的复杂性。
    • 使用场景
      • 需要在运行时选择不同算法时。
      • 算法的实现可能会经常变化时。
  3. 模板方法模式(Template Method Pattern)

    • 目的:模板方法模式定义了一个算法的蓝图,但将某些步骤延迟到子类中实现。
    • 结构
      • AbstractClass:定义算法框架,并实现某些步骤。
      • ConcreteClass:实现算法中的具体步骤。
    • 优点
      • 提供了一个固定的算法结构。
      • 允许子类扩展特定的步骤。
    • 缺点
      • 可能会导致类的层次结构复杂。
    • 使用场景
      • 当算法的步骤是固定的,但某些步骤需要子类实现时。
      • 需要避免重复代码时。
  4. 命令模式(Command Pattern)

    • 目的:将请求封装为一个对象,从而使您可以使用不同的请求、队列请求和日志请求。
    • 结构
      • Command:声明执行操作的接口。
      • ConcreteCommand:实现具体的请求操作。
      • Invoker:请求操作的触发者。
      • Receiver:执行操作的具体实现。
    • 优点
      • 将请求者与执行者解耦。
      • 支持撤销和重做操作。
    • 缺点
      • 增加了系统的复杂性。
    • 使用场景
      • 需要将请求、操作和处理分开时。
      • 需要支持撤销和重做操作时。
  5. 状态模式(State Pattern)

    • 目的:允许对象在其内部状态改变时改变它的行为。
    • 结构
      • Context:维护当前状态。
      • State:定义状态接口。
      • ConcreteState:实现具体的状态行为。
    • 优点
      • 状态之间的转换变得清晰。
      • 易于扩展新的状态。
    • 缺点
      • 可能会导致状态类数量增加。
    • 使用场景
      • 对象的行为依赖于其状态时。
      • 状态和行为之间有明显的关联时。
  6. 访问者模式(Visitor Pattern)

    • 目的:将元素类与操作类分开,根据元素类决定具体操作类,允许在不改变元素类的情况下定义作用于这些元素的新操作。
    • 结构
      • Visitor:定义访问操作的接口。
      • ConcreteVisitor:实现具体的访问操作。
      • Element:定义接受访问者的方法。
      • ConcreteElement:实现具体的元素类。
    • 优点
      • 可以增加新的操作而不修改元素类。
      • 支持元素的双重访问。
    • 缺点
      • 对元素类的结构改变不友好。
    • 使用场景
      • 需要在不修改元素类的情况下添加新操作时。
      • 需要遍历复杂结构并对其执行操作时。
  7. 中介者模式(Mediator Pattern)

    • 目的:定义一个对象,封装一组对象之间的交互,使这些对象不需要显式地相互引用。
    • 结构
      • Mediator:定义与中介相关的接口。
      • ConcreteMediator:实现具体的中介逻辑。
      • Colleague:定义与中介交互的接口。
    • 优点
      • 降低了对象之间的耦合。
      • 中介者可以集中处理对象间的交互。
    • 缺点
      • 可能会导致中介者成为系统的单点故障。
    • 使用场景
      • 需要协调多个对象之间的复杂交互时。
      • 需要集中处理对象间的通信时。
  8. 解释器模式(Interpreter Pattern)

    • 目的:为语言定义一个语法,并定义一个解释器来解释该语言。
    • 结构
      • Context:解释器的上下文。
      • AbstractExpression:定义解释的接口。
      • TerminalExpression:实现终结符表达式。
      • NonTerminalExpression:实现非终结符表达式。
    • 优点
      • 支持动态解释。
      • 易于实现简单语言的解释。
    • 缺点
      • 可能会导致类的数量激增。
      • 不适合复杂的语言或表达式。
    • 使用场景
      • 需要解释简单语法或语言时。
      • 需要动态解释和执行表达式时。

这些设计模式提供了一些通用的解决方案,旨在提高代码的灵活性、可维护性和可扩展性。了解这些模式及其适用场景,可以帮助开发者在实际项目中做出更合理的设计决策。