软考中级-软件设计师 23种设计模式(内含详细解析)

针对软件设计师考试中设计模式题型,这篇文章对23种设计模式作总结

🎯 创建型设计模式

📌 抽象工厂(Abstract Factory) 设计模式

点击跳转:抽象工厂模式代码实例(Java)

💡 意图

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

💡 图例

在这里插入图片描述
图中绿色虚线是接口实现关系,白色虚线为实例化创建

💡 适用场景

  1. 一个系统要独立于它的产品的创建,组合和表示时;

  2. 一个系统要由多个产品系列中的一个来配置时;

  3. 需要强调一系列相关的产品对象的设计以便进行联合使用时;

  4. 提供一个产品类库,而只想显示它们的接口而不是实现时。

📌 工厂方法(Factory Method)设计模式

点击跳转:工厂方法模式代码实例(Java)

💡 意图

提供一个创建对象的接口,但由子类决定要实例化的具体类。工厂方法使得类的实例化延迟到子类

💡 图例

在这里插入图片描述
图中绿色虚线是接口实现关系,l蓝色实线表示抽象类继承,白色虚线为实例化创建

💡 适用场景

  1. 当一个类无法预见它所需要的对象的具体类型时,使用工厂方法模式。

  2. 当一个类希望将创建对象的责任委托给子类,以便于扩展时。

  3. 当需要避免在代码中直接依赖具体类,而是通过抽象接口或基类进行操作时。

  4. 当一组相关的产品需要动态创建,但只希望暴露其抽象接口时。

📌 单例(Singleton)设计模式

点击跳转:单例模式代码实例(Java)

💡 意图

确保一个类只有一个实例,并提供全局访问点来获取该实例。单例模式常用于管理共享资源或需要全局唯一对象的场景。

💡 图例

在这里插入图片描述

SingletonPattern没有实例化,只能通过getInstance()访问

💡 适用场景

  1. 当一个类只能有一个实例时,如配置管理器、日志对象、线程池等。

  2. 当需要全局访问点时,如访问数据库连接池或缓存管理器。

  3. 避免对象创建时浪费资源,如只需要一个共享实例而不需要重复创建时。

  4. 当类的实例化和使用分离时,可以通过延迟实例化来优化性能。

📌 生成器(Builder)设计模式

点击跳转:生成器模式代码实例(Java)

💡 意图

将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。生成器模式允许通过逐步构建的方式,灵活创建复杂对象。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当对象的构建过程复杂,涉及多个步骤时,如构建一个多层次的复杂对象。

  2. 当需要创建不同表现形式的复杂对象时,但构建过程相同时。

  3. 当需要在不同环境下构建不同的产品时,如不同的操作系统或数据库配置等。

  4. 当客户端只需要关心最终对象的类型,而不关心构建过程时,可以通过生成器模式提供更好的封装和灵活性。

📌 原型(Prototype)设计模式

点击跳转:原型模式代码实例(Java)

💡 意图

通过复制现有的对象来创建新的对象,而不是通过实例化新对象。原型模式允许在运行时动态地克隆对象,从而简化对象的创建过程,尤其适用于复杂对象的创建。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当创建对象的成本较高,且相似对象可以通过克隆来获得时。

  2. 当需要大量相似对象,但是其细节有所不同时,可以通过原型模式创建这些对象。

  3. 当类的构造过程复杂,但可以通过克隆现有对象来快速创建新实例时。

  4. 当对象的状态或行为需要从现有对象进行复制,而不需要重新构造时。

🎯 结构型设计模式

📌 适配器(Adapter)设计模式

点击跳转:适配器模式代码实例(Java)

💡 意图

将一个类的接口转换成客户端所期待的另一个接口,使得原本接口不兼容的类能够一起工作。适配器模式使得不同接口之间可以协同工作,通常用于连接新旧系统

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当你希望通过现有的接口来访问旧系统中的功能,但这些功能的接口和新的系统不兼容时。

  2. 当需要使用一些现有的类,但它们的接口不符合要求时,可以通过适配器模式使其兼容。

  3. 当系统中多个类的接口不一致,且这些类需要协同工作时。

  4. 当你需要让类具有更灵活的接口,能与不同的外部接口交互时。

📌 桥接(Bridge)设计模式

点击跳转:桥接模式代码实例(Java)

💡 意图

将抽象部分与实现部分分离,使得二者可以独立变化。桥接模式通过引入桥接接口,将抽象部分与实现部分解耦,从而在不改变客户端代码的前提下,改变或扩展系统的实现。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当需要将抽象部分与其实现部分解耦,使得二者可以独立扩展时。

  2. 当一个类存在多个变化维度,且每个维度都可能变化时,桥接模式可以减少子类的数量。

  3. 当需要在不同的操作系统或设备之间共享功能实现时,通过桥接模式实现对不同平台的支持。

  4. 当类的继承结构较为复杂,导致子类众多时,桥接模式有助于简化设计。

📌 组合(Composite)设计模式

点击跳转:组合模式代码实例(Java)

💡 意图

将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式让客户端可以统一地对待单个对象和对象集合,通常用于表示树形结构,如文件系统或组织结构。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当需要表示“部分-整体”层次结构时,如组织架构、文件目录等。

  2. 当客户端需要统一地处理单个对象和对象集合时,通过组合模式避免区分对象和容器。

  3. 当对象数量不确定且层次结构复杂时,组合模式可以简化操作。

  4. 你希望构建一个递归树形结构时,如树形菜单、图形组件等。

📌 装饰器(Decorator)设计模式

点击跳转:装饰器模式代码实例(Java)

💡 意图

动态地为对象添加新的功能,而不影响其原有结构。装饰器模式通过将对象包装在一个或多个装饰器中,增强其功能,而无需修改原始类。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当不希望通过继承来扩展类的功能时,可以使用装饰器模式动态地增加行为。

  2. 当需要在运行时为对象添加额外功能时,装饰器模式提供比继承更灵活的解决方案。

  3. 当希望用多个不同的功能装饰同一个对象时,装饰器模式允许自由组合不同的装饰功能。

  4. 当系统需要遵循开闭原则(OCP),即对扩展开放、对修改封闭时,装饰器模式是理想选择。

📌 外观(Facade)设计模式

点击跳转:外观模式代码实例(Java)

💡 意图

为子系统中的一组接口提供一个统一的接口,外观模式定义了一个高层接口,使得子系统更容易使用。它主要用于简化复杂系统的访问,提高代码的可读性和维护性。

💡 图例

图中绿色虚线表示继承或实现关系,白色虚线表示实例化创建。

💡 适用场景

  1. 当系统过于复杂,且外部调用者只需要关注高层逻辑时,外观模式可以提供简单的访问方式。

  2. 当多个子系统需要被统一管理时,外观模式可以减少直接访问子系统的复杂性。

  3. 当希望对子系统进行解耦,以便日后修改子系统时,外观模式可以隐藏子系统的细节。

  4. 当需要提供一个一致的接口,以屏蔽多个子系统的不同实现时,可以使用外观模式。

📌 享元(Flyweight)设计模式

点击跳转:享元模式代码实例(Java)

💡 意图

通过共享对象来减少内存使用,以支持大量细粒度对象的高效使用。享元模式避免了创建重复对象,从而提高性能,尤其适用于资源受限的环境。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当系统中存在大量相似对象,并且会消耗大量内存时,享元模式可以减少对象数量。

  2. 当对象的大部分状态是相同的,仅少部分状态有所变化时,可以将不变部分作为享元共享。

  3. 当创建对象的开销较大,且需要优化性能时,享元模式能够减少对象创建成本。

  4. 当系统需要支持大量对象但受限于内存资源时,享元模式提供了一种共享机制。

📌 代理(Proxy)设计模式

点击跳转:代理模式代码实例(Java)

💡 意图

为某个对象提供一个代理,以控制对该对象的访问。代理模式用于在访问对象前增加额外的逻辑,例如权限控制懒加载日志记录远程访问等。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 远程代理(Remote Proxy): 当需要访问远程对象时,代理模式可以封装网络通信细节,例如 RMI(远程方法调用)。

  2. 虚拟代理(Virtual Proxy): 当对象创建开销较大时,代理可以延迟对象的初始化(懒加载)。

  3. 保护代理(Protection Proxy): 当需要控制对对象的访问权限时,例如不同用户权限访问不同的功能。

  4. 缓存代理(Cache Proxy): 代理对象可以存储访问的结果,避免重复计算,提高性能。

  5. 智能引用代理(Smart Reference): 代理在访问对象时附加额外操作,例如记录日志或统计访问次数。

🎯 行为型设计模式

📌 责任链(Chain of Responsibility)设计模式

点击跳转:责任链模式代码实例(Java)

💡 意图

将多个处理者按顺序连接成一条链,每个处理者都可以处理请求或将其传递给下一个处理者。责任链模式避免了请求发送者与接收者之间的直接耦合,使请求处理更加灵活。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当请求需要被多个对象处理时,可以使用责任链模式动态决定处理者的顺序。

  2. 当请求的处理逻辑需要灵活扩展时,责任链模式允许动态增加或修改处理者。

  3. 当希望降低请求发送者与接收者的耦合度时,责任链模式使得请求者不需要关心具体的处理者。

  4. 当有多个处理者可以处理请求,但具体由谁处理在运行时决定时,责任链模式提供了一种灵活的解决方案。

📌 命令(Command)设计模式

点击跳转:命令模式代码实例(Java)

💡 意图

将请求封装成对象,以便使用不同的请求、队列或者日志来参数化对象。命令模式允许请求的发送者和接收者解耦,并支持操作的撤销(Undo)和恢复(Redo)。

💡 图例

图中绿色虚线表示继承或实现关系,白色虚线表示实例化创建。

💡 适用场景

  1. 当需要将请求封装为对象,以支持撤销(Undo)和恢复(Redo)功能时,命令模式能够很好地管理请求。

  2. 当系统需要对请求排队、记录日志或支持事务时,命令模式可以灵活处理这些需求。

  3. 当需要将请求的发送者和执行者解耦时,命令模式提供了一个中间层,使两者不直接交互。

  4. 当系统需要支持宏命令(批量命令)时,命令模式可以组合多个命令并统一执行。

📌 解释器(Interpreter)设计模式

点击跳转:解释器模式代码实例(Java)

💡 意图

定义一个语言的语法表示,并提供一个解释器来处理该语言的句子。解释器模式用于设计编译器表达式计算器规则引擎等,以解析和执行特定的语法规则。

💡 图例

图中绿色虚线表示继承或实现关系,白色虚线表示实例化创建。

💡 适用场景

  1. 当需要解析和执行特定语言的语法规则时,解释器模式能够将复杂的语法解析为对象结构。

  2. 当存在特定的业务规则需要频繁更改或扩展时,解释器模式可以提供灵活的规则定义方式。

  3. 当系统需要支持不同的表达式计算时,如数学计算、逻辑运算、SQL 解析等,解释器模式是合适的选择。

  4. 当要构造一个简单的编译器或解释器时,可以使用解释器模式解析语法树并执行相应的操作。

📌 迭代器(Iterator)设计模式

点击跳转:迭代器模式代码实例(Java)

💡 意图

提供一种方法顺序访问集合对象中的元素,而不暴露其内部表示。迭代器模式使得遍历不同集合结构(如数组、链表、树等)时可以使用统一的方式,并且解耦了遍历算法与集合对象的实现。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当需要遍历集合对象,但不希望暴露集合的内部结构时,迭代器模式可以提供一个统一的访问方式。

  2. 当需要支持多种遍历方式(正序、倒序、跳跃等)时,迭代器模式允许自定义迭代逻辑。

  3. 当希望对不同类型的集合结构(如数组、链表、哈希表等)使用相同的遍历接口时,迭代器模式提供了解决方案。

  4. 当多个对象需要顺序访问集合对象时,迭代器模式可以确保遍历过程的独立性和一致性。

📌 中介者(Mediator)设计模式

点击跳转:中介者模式代码实例(Java)

💡 意图

定义一个中介对象,封装多个对象之间的交互,使对象之间不再相互引用,而是通过中介者进行通信。中介者模式降低了对象之间的耦合度,使得系统更加可扩展和维护。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当对象之间存在复杂的交互关系时,中介者模式可以简化对象的相互依赖,避免对象之间形成网状结构。

  2. 当多个对象之间的交互需要统一管理时,中介者模式可以提供一个中心化的管理机制。

  3. 当对象之间的交互需要动态变化时,中介者模式可以让交互逻辑集中在一个类中,便于修改和扩展。

  4. 当需要减少类之间的耦合,提高代码的可维护性时,中介者模式是一个不错的选择。

📌 备忘录(Memento)设计模式

点击跳转:备忘录模式代码实例(Java)

💡 意图

备忘录模式在不暴露对象内部状态的情况下,保存对象的状态,以便在需要时恢复到先前的状态。它允许在不破坏封装的情况下保存和恢复对象的状态,适用于需要撤销或恢复功能的场景。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当系统需要提供撤销(Undo)或恢复(Redo)功能时,备忘录模式能够存储对象的历史状态。

  2. 当对象状态变化频繁,且需要随时恢复到某个历史状态时,备忘录模式可以有效管理和恢复这些状态。

  3. 当需要在不破坏封装的情况下,保存对象的状态时,备忘录模式允许保存对象的状态,而不会暴露其实现细节。

  4. 当需要在某个操作执行后,能够恢复到先前的状态时,备忘录模式非常适用。

📌 观察者(Observer)设计模式

点击跳转:观察者模式代码实例(Java)

💡 意图

定义了一种一对多的依赖关系,使得每当一个对象的状态发生改变时,所有依赖于它的对象都会自动收到通知并更新。观察者模式通常用于事件监听广播通信等场景,它解耦了被观察者和观察者之间的关系。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当一个对象的状态变化需要影响其他对象时,且不希望被观察者和观察者之间产生过强的耦合时,观察者模式是理想的解决方案。

  2. 当多个观察者对象需要响应同一事件的变化时,观察者模式能自动通知所有相关的观察者。

  3. 当需要提供事件驱动机制时,例如在 GUI 应用程序中,当按钮被点击时,需要通知多个组件进行相应的处理。

  4. 当一个对象的状态变化需要同时通知多个不同类型的对象时,观察者模式能够提供灵活的通知机制。

📌 状态(State)设计模式

点击跳转:状态模式代码实例(Java)

💡 意图

允许一个对象在其内部状态改变时改变其行为,看起来就像是改变了类。状态模式通过将不同的状态封装成独立的类,使得对象的行为随着状态的不同而变化,避免了大量的条件语句。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当一个对象的行为依赖于其状态,并且在运行时其状态可能会改变时,状态模式可以更好地组织和管理这些行为。

  2. 当对象的行为随着状态的改变而变化,且使用条件语句处理这种变化显得繁琐和难以维护时。

  3. 当系统中存在多种状态转换逻辑,并且每个状态下的行为都需要清晰分离时,状态模式非常适合。

  4. 当希望避免多个条件判断语句(如 if-else 或 switch)时,状态模式可以将每个状态的行为独立封装,减少复杂度。

📌 策略(Strategy)设计模式

点击跳转:策略模式代码实例(Java)

💡 意图

定义一系列的算法,将每一个算法封装起来,并使它们可以互换。策略模式使得算法的变化独立于使用算法的客户。通过定义策略接口和多个具体的策略实现,策略模式允许客户端在运行时选择不同的算法或行为。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当系统中存在多个算法(策略)且这些算法可以相互替换时,策略模式提供了一个灵活的方式来封装和选择不同的算法。

  2. 当需要根据不同的环境或条件来选择不同的行为时,策略模式能够帮助分离选择逻辑和具体算法。

  3. 当系统中有很多类似的条件语句(如 if-else 或 switch),而这些条件语句负责选择不同算法时,策略模式可以让条件逻辑更加清晰并易于扩展。

  4. 当算法或行为频繁变化时,策略模式让这些变化更加容易控制和扩展,避免对客户代码的修改。

📌 模板方法(Template Method)设计模式

点击跳转:模板方法模式代码实例(Java)

💡 意图

定义一个操作中的算法骨架,将一些步骤的实现延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下重新定义算法中的某些特定步骤。它主要用于定义一个不变的算法结构,并允许子类去实现其中的某些可变部分。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当一个算法中有一些不变的步骤,而某些步骤可以由子类改变时,模板方法模式非常适用,它将不变的部分提取到父类中。

  2. 当多个子类有共同的算法结构,但部分细节需要不同实现时,可以通过模板方法模式来定义统一的框架,并让子类提供不同的实现。

  3. 当你想在不修改类的情况下,扩展现有算法时,模板方法模式可以通过子类重写方法来进行扩展。

  4. 当一个操作的步骤是固定的,而某些步骤需要定制化时,模板方法模式帮助将步骤的共同部分和特定实现区分开。

📌 访问者(Visitor)设计模式

点击跳转:访问者模式代码实例(Java)

💡 意图

将数据结构与操作数据的行为分离,使得操作数据的行为可以独立于数据结构变化而变化。访问者模式允许你在不改变对象结构的前提下,增加新的操作。它通常用于需要对一组对象执行一系列操作的场景。

💡 图例

在这里插入图片描述

💡 适用场景

  1. 当需要对一组对象进行操作,但不希望修改对象结构时,访问者模式通过将操作逻辑从对象中抽离出来实现了操作与数据的解耦。

  2. 当需要在系统中增加新的操作时,访问者模式能够通过添加新的访问者来扩展系统,而无需修改已有的元素类。

  3. 当需要对元素结构中的对象进行复杂的操作,并且这些操作涉及不同类型的元素时,访问者模式能够简化操作的管理和扩展。

  4. 当你希望将操作集中管理,而不是让操作逻辑分散在不同的类中时,访问者模式可以帮助集中管理访问操作。

📚 软考知识点总结

🎯 创建型模式

  1. 单例模式(Singleton)
    意图:保证一个类只有一个实例,并提供一个访问它的全局访问点。
    适用场合:
    (1)当系统中需要有一个且仅有一个公共访问点的对象,例如配置对象或线程池。
    (2)当对象创建时资源开销较大,应避免频繁创建和销毁。
    (3)当对象需要被频繁访问,且希望减少系统开销。

  2. 工厂方法模式(Factory Method)
    意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。
    适用场合:
    (1)当一个类无法预知它所必须创建的对象的类时。
    (2)当一个类希望由它的子类来指定所创建的对象时。
    (3)当将创建对象的职责委托给多个子类中的某一个时。

  3. 抽象工厂模式(Abstract Factory)
    意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
    适用场合:
    (1)当系统需要独立于其产品的创建、组合和表示时。
    (2)当一个系统要由多个产品系列中的一个来配置时。
    (3)当你要强调一系列相关的产品对象的设计以便进行一致的使用时。

  4. 建造者模式(Builder)
    意图:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
    适用场合:
    (1)当创建复杂对象的算法应该独立于组成对象的部分及它们的装配方式时。
    (2)当构造过程必须允许被构造的对象有不同的表示时。

  5. 原型模式(Prototype)
    意图:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
    适用场合:
    (1)当一个系统应该独立于它的产品创建、构成和表示时。
    (2)当要实例化的类是在运行时指定时。
    (3)当一个类的实例只能有几个不同状态组合中的一个时。

🎯 结构型模式

  1. 适配器模式(Adapter)
    意图:将一个类的接口转换成客户希望的另外一个接口,适配器使得原本因接口不兼容而不能一起工作的那些类可以一起工作。
    适用场合:
    (1)希望复用一些现有的类,但接口又与复用环境要求不一致时。
    (2)通过适配使得两个已有接口的类协同工作。

  2. 桥接模式(Bridge)
    意图:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
    适用场合:
    (1)当一个抽象可能有多个实现时。
    (2)避免在抽象与实现之间建立静态的继承关系。
    (3)需要在运行时切换实现方式。

  3. 组合模式(Composite)
    意图:将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
    适用场合:
    (1)表示对象的部分-整体层次结构时。
    (2)希望用户忽略组合对象与单个对象的不同时。

  4. 装饰器模式(Decorator)
    意图:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活。
    适用场合:
    (1)在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
    (2)处理那些可以撤销的职责。
    (3)需要为类增加功能,但又不希望通过子类扩展方式实现。

  5. 外观模式(Facade)
    意图:为子系统中的一组接口提供一个一致的界面,使得子系统更易使用。
    适用场合:
    (1)为一个复杂子系统提供一个简单接口。
    (2)将客户端与复杂子系统解耦。
    (3)构建多层系统结构。

  6. 享元模式(Flyweight)
    意图:运用共享技术有效地支持大量细粒度对象的复用。
    适用场合:
    (1)系统中大量对象造成内存占用大时。
    (2)对象大多数状态可以外部化。
    (3)对象可以通过唯一标识识别。

  7. 代理模式(Proxy)
    意图:为其他对象提供一种代理以控制对这个对象的访问。
    适用场合:
    (1)需要远程代理、本地代表、安全代理、延迟加载等。
    (2)希望控制对某个对象的访问。

🎯 行为型模式

  1. 模板方法模式(Template Method)
    意图:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。
    适用场合:
    (1)多个子类有相同的方法结构,但实现细节不同。
    (2)希望控制子类扩展行为。

  2. 命令模式(Command)
    意图:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。
    适用场合:
    (1)需要将请求调用者和接收者解耦。
    (2)需要对请求排队或记录请求日志。

  3. 迭代器模式(Iterator)
    意图:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。
    适用场合:
    (1)访问一个聚合对象的内容而无需暴露它的内部表示。
    (2)为遍历不同的数据结构提供统一接口。

  4. 观察者模式(Observer)
    意图:定义对象间的一种一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
    适用场合:
    (1)当一个抽象模型有两个方面,其中一个方面依赖于另一个方面时。
    (2)当一个对象的改变需要同时改变其他对象,而不知道具体有哪些对象有待改变时。
    (3)当一个对象必须通知其他对象,而它又不希望这些对象是紧耦合的。

  5. 中介者模式(Mediator)
    意图:用一个中介对象来封装一系列对象交互,使对象不需要显式地引用彼此,从而使其耦合松散。
    适用场合:
    (1)对象之间存在复杂的引用关系,结构混乱且难以复用。
    (2)想通过一个中间类来封装多个类之间的交互。

  6. 状态模式(State)
    意图:允许对象在内部状态发生改变时改变它的行为。
    适用场合:
    (1)对象的行为依赖于它的状态,并且它必须在运行时根据状态改变行为时。
    (2)避免过多使用条件语句。

  7. 策略模式(Strategy)
    意图:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。
    适用场合:
    (1)多个类仅在算法或行为上略有不同。
    (2)希望从多个行为中选择一种。

  8. 职责链模式(Chain of Responsibility)
    意图:使多个对象有机会处理请求,从而避免请求的发送者和接收者之间的耦合。
    适用场合:
    (1)有多个对象可以处理一个请求,处理者动态确定。
    (2)希望请求者不明确指定接收者。

  9. 访问者模式(Visitor)
    意图:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变元素类的前提下定义作用于这些元素的新操作。
    适用场合:
    (1)对象结构中包含很多类型对象,需要对它们执行很多操作。
    (2)需要对一个对象结构中的对象进行很多不同的操作,而且希望在不改变这些类的前提下定义新的操作。

  10. 备忘录模式(Memento)
    意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
    适用场合:
    (1)需要保存与恢复对象的状态。
    (2)实现撤销操作。

  11. 解释器模式(Interpreter)
    意图:给定一个语言,定义它的文法的一种表示,并定义一个解释器来解释语言中的句子。
    适用场合:
    (1)需要解释执行的语言或表达式。
    (2)语法规则频繁变化但结构稳定。

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

在这里插入图片描述

### 解决 PP-OCRv4 出现的错误 当遇到 `WARNING: The pretrained params backbone.blocks2.0.dw_conv.lab.scale not in model` 这样的警告时,这通常意味着预训练模型中的某些参数未能匹配到当前配置下的模型结构中[^2]。 对于此问题的一个有效解决方案是采用特定配置文件来适配预训练权重。具体操作方法如下: 通过指定配置文件 `ch_PP-OCRv4_det_student.yml` 并利用已有的最佳精度预训练模型 (`best_accuracy`) 来启动训练过程可以绕过上述不兼容的问题。执行命令如下所示: ```bash python3 tools/train.py -c configs/det/ch_PP-OCRv4/ch_PP-OCRv4_det_student.yml ``` 该方案不仅解决了参数缺失带来的警告,还能够继续基于高质量的预训练成果进行微调,从而提升最终检测效果。 关于蒸馏的概念,在机器学习领域内指的是将大型复杂网络(teacher 模型)的知识迁移到小型简单网络(student 模型)。这里 student 和 teacher 的关系是指两个不同规模或架构的神经网络之间的指导与被指导的关系;其中 teacher 已经经过充分训练并具有良好的性能,而 student 则试图模仿前者的行为模式以达到相似的效果但保持更高效的计算特性。 至于提到的 `Traceback` 错误信息部分,由于未提供具体的跟踪堆栈详情,难以给出针对性建议。不过一般而言,这类报错往往涉及代码逻辑错误或是环境配置不当等问题。为了更好地帮助定位和解决问题,推荐记录完整的异常日志,并仔细检查最近修改过的代码片段以及确认依赖库版本的一致性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值