Unity 面试篇|(三)设计模式篇 【全面总结 | 持续更新 | 建议收藏】

目录

    • 1. 什么是设计模式?
    • 2. 设计模式的七大原则?
    • 3. 单例模式
    • 4. 三类设计模式
    • 5. 什么是单例模式,适用场景以及优缺点?
    • 6. 什么是原型模式,适用场景以及优缺点?
    • 7. 什么是生成器模式,适用场景以及优缺点?
    • 8. 什么是抽象工厂模式,适用场景以及优缺点?
    • 9. 什么是工厂方法模式,适用场景以及优缺点?
    • 10. 什么是适配器模式,适用场景以及优缺点?
    • 11. 什么是桥接模式,适用场景以及优缺点?
    • 12. 什么是组合模式,适用场景以及优缺点?
    • 13. 什么是装饰模式,适用场景以及优缺点?
    • 14. 什么是外观模式,适用场景以及优缺点?
    • 15. 什么是享元模式,适用场景以及优缺点?
    • 16. 什么是代理模式,适用场景以及优缺点?
    • 17. 什么是责任链模式,适用场景以及优缺点?
    • 18. 什么是命令模式,适用场景以及优缺点?
    • 19. 什么是迭代器模式,适用场景以及优缺点?
    • 20. 什么是中介者模式,适用场景以及优缺点?
    • 21. 什么是备忘录模式,适用场景以及优缺点?
    • 22. 什么是观察者模式,适用场景以及优缺点?
    • 23. 什么是状态模式,适用场景以及优缺点?
    • 24. 什么是策略模式,适用场景以及优缺点?
    • 25. 什么是模板方法模式,适用场景以及优缺点?
    • 26. 什么是访问者模式,适用场景以及优缺点?

在这里插入图片描述

1. 什么是设计模式?

  • 设计模式是一套被反复使用、多数人知晓、经过分类编目、代码设计经验的总结。
  • 设计模式与方法或库的使用方式不同, 你很难直接在自己的程序中套用某个设计模式。 模式并不是一段特定的代码, 而是解决特定问题的一般性概念。 你可以根据模式来实现符合自己程序实际所需的解决方案。
  • 常常会混淆模式和算法, 因为两者在概念上都是已知特定问题的典型解决方案。 但算法总是明确定义达成特定目标所需的一系列步骤, 而模式则是对解决方案的更高层次描述。 同一模式在两个不同程序中的实现代码可能会不一样。

2. 设计模式的七大原则?

  • 开闭原则:对扩展开放,对修改封闭
  • 单一职责原则:一个类只负责一个功能领域中的相应职责
  • 里氏转换原则:所有引用基类的地方必须能透明的去使用其子类的对象
  • 依赖倒转原则:依赖于抽象,不能依赖于具体实现
  • 接口依赖原则:类之间的依赖关系应该建立在最小的接口上
  • 合成/聚合复用原则:尽量使用合成/聚成,而不是通过继承来达到复用的目的
  • 最少知识原则(迪米特法则):一个软件应当尽可能少的和其他实体发生相互作用

3. 单例模式

  • 单例模式也分为两种模式:
    1.饿汉模式:在类加载时就生成该单例对象
    • 优点:简单方便;线程安全,调用时反应速度快
    • 缺点:会降低启动速度;不关程序是否使用,都会创建该单例对象
    • 应用场景:单例对象功能简单,占用内存小,需要频繁使用的时候
public class SingLeton{private static SingLeton instance;private SingLeton(){instance = new SingLeton();}public static SingLeton Instace{get{return instance;}}}    

2.懒汉模式:第一次调用时才创建该单例对象

  • 优点:在需要时创建,利用率高;提高启动速度
  • 缺点:多线程不安全,可能会创建多个实例
  • 应用场景:单例对象功能复杂,内存占用大,需要快速启动
 public class LazySingleton{private static LSingleton _instance;public static Singleton Instace{get{if (_instance == null){_instance = new Singleton();}return _instance;}}}

4. 三类设计模式

  • 创建型模式:提供创建对象的机制, 能够提升已有代码的灵活性和可复用性。
  • 结构型模式:这类模式介绍如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效。
  • 行为模式:这类模式负责对象间的高效沟通和职责委派。

5. 什么是单例模式,适用场景以及优缺点?

  • 单例模式是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。
  • 适合应用场景:
    • 如果程序中的某个类对于所有客户端只有一个可用的实例
    • 如果你需要更加严格地控制全局变量
  • 优点:
    • 可以保证一个类只有一个实例。
    • 获得了一个指向该实例的全局访问节点。
    • 仅在首次请求单例对象时对其进行初始化。
  • 缺点:
    • 违反了单一职责原则。 该模式同时解决了两个问题。
    • 单例模式可能掩盖不良设计, 比如程序各组件之间相互了解过多等。
    • 该模式在多线程环境下需要进行特殊处理, 避免多个线程多次创建单例对象。
    • 单例的客户端代码单元测试可能会比较困难, 因为许多测试框架以基于继承的方式创建模拟对象。 由于单例类的构造函数是私有的, 而且绝大部分语言无法重写静态方法, 所以你需要想出仔细考虑模拟单例的方法。 要么干脆不编写测试代码, 或者不使用单例模式。
 public sealed class Singleton{private Singleton() { }private static Singleton _instance;public static Singleton GetInstance(){if (_instance == null){_instance = new Singleton();}return _instance;}public void someBusinessLogic(){// ...}}

6. 什么是原型模式,适用场景以及优缺点?

  • 原型模式是一种创建型设计模式, 使你能够复制已有对象, 而又无需使代码依赖它们所属的类。
  • 适合应用场景:
    • 如果你需要复制一些对象, 同时又希望代码独立于这些对象所属的具体类, 可以使用原型模式。
    • 如果子类的区别仅在于其对象的初始化方式, 那么你可以使用该模式来减少子类的数量。 别人创建这些子类的目的可能是为了创建特定类型的对象。
  • 优点:
    • 可以克隆对象, 而无需与它们所属的具体类相耦合。
    • 可以克隆预生成原型, 避免反复运行初始化代码。
    • 可以更方便地生成复杂对象。
    • 可以用继承以外的方式来处理复杂对象的不同配置。
  • 缺点:
    • 违克隆包含循环引用的复杂对象可能会非常麻烦。

7. 什么是生成器模式,适用场景以及优缺点?

  • 生成器模式是一种创建型设计模式, 使你能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。
  • 适合应用场景:
    • 使用生成器模式可避免 “重叠构造函数 (telescoping constructor)” 的出现。
    • 假设你的构造函数中有十个可选参数, 那么调用该函数会非常不方便; 因此, 你需要重载这个构造函数, 新建几个只有较少参数的简化版。 但这些构造函数仍需调用主构造函数, 传递一些默认数值来替代省略掉的参数。
    • 当你希望使用代码创建不同形式的产品 (例如石头或木头房屋) 时, 可使用生成器模式。
    • 生成器模式让你能分步骤构造产品。 你可以延迟执行某些步骤而不会影响最终产品。 你甚至可以递归调用这些步骤, 这在创建对象树时非常方便。
  • 优点:
    • 可以分步创建对象, 暂缓创建步骤或递归运行创建步骤。
    • 生成不同形式的产品时, 你可以复用相同的制造代码。
    • 单一职责原则。 你可以将复杂构造代码从产品的业务逻辑中分离出来。
  • 缺点:
    • 由于该模式需要新增多个类, 因此代码整体复杂程度会有所增加。

8. 什么是抽象工厂模式,适用场景以及优缺点?

  • 抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。
  • 适合应用场景:
    • 如果代码需要与多个不同系列的相关产品交互, 但是由于无法提前获取相关信息, 或者出于对未来扩展性的考虑, 你不希望代码基于产品的具体类进行构建, 在这种情况下, 你可以使用抽象工厂。
    • 抽象工厂为你提供了一个接口, 可用于创建每个系列产品的对象。 只要代码通过该接口创建对象, 那么你就不会生成与应用程序已生成的产品类型不一致的产品。
    • 如果你有一个基于一组抽象方法的类, 且其主要功能因此变得不明确, 那么在这种情况下可以考虑使用抽象工厂模式。
    • 在设计良好的程序中, 每个类仅负责一件事。 如果一个类与多种类型产品交互, 就可以考虑将工厂方法抽取到独立的工厂类或具备完整功能的抽象工厂类中。
  • 优点:
    • 可以确保同一工厂生成的产品相互匹配。
    • 可以避免客户端和具体产品代码的耦合。
    • 单一职责原则。 你可以将产品生成代码抽取到同一位置, 使得代码易于维护。
    • 开闭原则。 向应用程序中引入新产品变体时, 你无需修改客户端代码。
  • 缺点:
    • 由于采用该模式需要向应用中引入众多接口和类, 代码可能会比之前更加复杂。

9. 什么是工厂方法模式,适用场景以及优缺点?

  • 工厂方法模式是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。
  • 适合应用场景:
    • 当你在编写代码的过程中, 如果无法预知对象确切类别及其依赖关系时, 可使用工厂方法。
    • 如果你希望用户能扩展你软件库或框架的内部组件, 可使用工厂方法。
    • 如果你希望复用现有对象来节省系统资源, 而不是每次都重新创建对象, 可使用工厂方法。
  • 优点:
    • 可以避免创建者和具体产品之间的紧密耦合。
    • 单一职责原则。 你可以将产品创建代码放在程序的单一位置, 从而使得代码更容易维护。
    • 开闭原则。 无需更改现有客户端代码, 你就可以在程序中引入新的产品类型。
  • 缺点:
    • 应用工厂方法模式需要引入许多新的子类, 代码可能会因此变得更复杂。 最好的情况是将该模式引入创建者类的现有层次结构中。

10. 什么是适配器模式,适用场景以及优缺点?

  • 适配器模式是一种结构型设计模式, 它能使接口不兼容的对象能够相互合作。
  • 适合应用场景:
    • 当你希望使用某个类, 但是其接口与其他代码不兼容时, 可以使用适配器类。
    • 如果您需要复用这样一些类, 他们处于同一个继承体系, 并且他们又有了额外的一些共同的方法, 但是这些共同的方法不是所有在这一继承体系中的子类所具有的共性。
  • 优点:
    • 单一职责原则你可以将接口或数据转换代码从程序主要业务逻辑中分离。
    • 开闭原则。 只要客户端代码通过客户端接口与适配器进行交互, 你就能在不修改现有客户端代码的情况下在程序中添加新类型的适配器。
  • 缺点:
    • 代码整体复杂度增加, 因为你需要新增一系列接口和类。 有时直接更改服务类使其与其他代码兼容会更简单。

11. 什么是桥接模式,适用场景以及优缺点?

  • 桥接模式是一种结构型设计模式, 可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构, 从而能在开发时分别使用。
  • 适合应用场景:
    • 如果你想要拆分或重组一个具有多重功能的庞杂类 (例如能与多个数据库服务器进行交互的类), 可以使用桥接模式。
    • 如果你希望在几个独立维度上扩展一个类, 可使用该模式。
    • 如果你需要在运行时切换不同实现方法, 可使用桥接模式。
  • 优点:
    • 可以创建与平台无关的类和程序。
    • 客户端代码仅与高层抽象部分进行互动, 不会接触到平台的详细信息。
    • 开闭原则。 你可以新增抽象部分和实现部分, 且它们之间不会相互影响。
    • 单一职责原则。 抽象部分专注于处理高层逻辑, 实现部分处理平台细节。
  • 缺点:
    • 对高内聚的类使用该模式可能会让代码更加复杂。

12. 什么是组合模式,适用场景以及优缺点?

  • 组合模式是一种结构型设计模式, 你可以使用它将对象组合成树状结构, 并且能像使用独立对象一样使用它们。
  • 适合应用场景:
    • 如果你需要实现树状对象结构, 可以使用组合模式。
    • 如果你希望客户端代码以相同方式处理简单和复杂元素, 可以使用该模式。
  • 优点:
    • 可以利用多态和递归机制更方便地使用复杂树结构。
    • 开闭原则。 无需更改现有代码, 你就可以在应用中添加新元素, 使其成为对象树的一部分。
  • 缺点:
    • 对于功能差异较大的类, 提供公共接口或许会有困难。 在特定情况下, 你需要过度一般化组件接口, 使其变得令人难以理解。

13. 什么是装饰模式,适用场景以及优缺点?

  • 装饰模式是一种结构型设计模式, 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。
  • 适合应用场景:
    • 如果你希望在无需修改代码的情况下即可使用对象, 且希望在运行时为对象新增额外的行为, 可以使用装饰模式。
    • 如果用继承来扩展对象行为的方案难以实现或者根本不可行, 你可以使用该模式。
  • 优点:
    • 你无需创建新子类即可扩展对象的行为。
    • 你可以在运行时添加或删除对象的功能。
    • 你可以用多个装饰封装对象来组合几种行为。
    • 单一职责原则。 你可以将实现了许多不同行为的一个大类拆分为多个较小的类。
  • 缺点:
    • 对在封装器栈中删除特定封装器比较困难。
    • 实现行为不受装饰栈顺序影响的装饰比较困难。
    • 各层的初始化配置代码看上去可能会很糟糕。

14. 什么是外观模式,适用场景以及优缺点?

  • 外观模式是一种结构型设计模式, 能为程序库、 框架或其他复杂类提供一个简单的接口。
  • 适合应用场景:
    • 如果你需要一个指向复杂子系统的直接接口, 且该接口的功能有限, 则可以使用外观模式。
    • 如果需要将子系统组织为多层结构, 可以使用外观。
  • 优点:
    • 你可以让自己的代码独立于复杂子系统。
  • 缺点:
    • 外观可能成为与程序中所有类都耦合的上帝对象。

15. 什么是享元模式,适用场景以及优缺点?

  • 享元模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。
  • 适合应用场景:
    • 仅在程序必须支持大量对象且没有足够的内存容量时使用享元模式。
  • 优点:
    • 如果程序中有很多相似对象, 那么你将可以节省大量内存。
  • 缺点:
    • 你可能需要牺牲执行速度来换取内存, 因为他人每次调用享元方法时都需要重新计算部分情景数据。
    • 代码会变得更加复杂。 团队中的新成员总是会问: ​ “为什么要像这样拆分一个实体的状态?”。

16. 什么是代理模式,适用场景以及优缺点?

  • 代理模式是一种结构型设计模式, 让你能够提供对象的替代品或其占位符。 代理控制着对于原对象的访问, 并允许在将请求提交给对象前后进行一些处理。
  • 适合应用场景:
    • 延迟初始化 (虚拟代理)。 如果你有一个偶尔使用的重量级服务对象, 一直保持该对象运行会消耗系统资源时, 可使用代理模式。
    • 访问控制 (保护代理)。 如果你只希望特定客户端使用服务对象, 这里的对象可以是操作系统中非常重要的部分, 而客户端则是各种已启动的程序 (包括恶意程序), 此时可使用代理模式。
    • 本地执行远程服务 (远程代理)。 适用于服务对象位于远程服务器上的情形。
    • 记录日志请求 (日志记录代理)。 适用于当你需要保存对于服务对象的请求历史记录时。
    • 智能引用。 可在没有客户端使用某个重量级对象时立即销毁该对象。
  • 优点:
    • 你可以在客户端毫无察觉的情况下控制服务对象。
    • 如果客户端对服务对象的生命周期没有特殊要求, 你可以对生命周期进行管理。
    • 即使服务对象还未准备好或不存在, 代理也可以正常工作。
    • 开闭原则。 你可以在不对服务或客户端做出修改的情况下创建新代理。
  • 缺点:
    • 代码可能会变得复杂, 因为需要新建许多类。
    • 服务响应可能会延迟。

17. 什么是责任链模式,适用场景以及优缺点?

  • 责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
  • 适合应用场景:
    • 当程序需要使用不同方式处理不同种类请求, 而且请求类型和顺序预先未知时, 可以使用责任链模式。
    • 当必须按顺序执行多个处理者时, 可以使用该模式。
    • 如果所需处理者及其顺序必须在运行时进行改变, 可以使用责任链模式。
  • 优点:
    • 可以控制请求处理的顺序。
    • 单一职责原则。 你可对发起操作和执行操作的类进行解耦。
    • 开闭原则。 你可以在不更改现有代码的情况下在程序中新增处理者。
  • 缺点:
    • 部分请求可能未被处理。

18. 什么是命令模式,适用场景以及优缺点?

  • 命令模式是一种行为设计模式, 它可将请求转换为一个包含与请求相关的所有信息的独立对象。 该转换让你能根据不同的请求将方法参数化、 延迟请求执行或将其放入队列中, 且能实现可撤销操作。
  • 适合应用场景:
    • 如果你需要通过操作来参数化对象, 可使用命令模式。
    • 如果你想要将操作放入队列中、 操作的执行或者远程执行操作, 可使用命令模式。
    • 如果你想要实现操作回滚功能, 可使用命令模式。
  • 优点:
    • 单一职责原则。 你可以解耦触发和执行操作的类。
    • 开闭原则。 你可以在不修改已有客户端代码的情况下在程序中创建新的命令。
    • 你可以实现撤销和恢复功能。
    • 你可以实现操作的延迟执行。
    • 你可以将一组简单命令组合成一个复杂命令。
  • 缺点:
    • 代码可能会变得更加复杂, 因为你在发送者和接收者之间增加了一个全新的层次。

19. 什么是迭代器模式,适用场景以及优缺点?

  • 迭代器模式是一种行为设计模式, 让你能在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。
  • 适合应用场景:
    • 当集合背后为复杂的数据结构, 且你希望对客户端隐藏其复杂性时 (出于使用便利性或安全性的考虑), 可以使用迭代器模式。
    • 使用该模式可以减少程序中重复的遍历代码。
    • 如果你希望代码能够遍历不同的甚至是无法预知的数据结构, 可以使用迭代器模式。
  • 优点:
    • 单一职责原则。 通过将体积庞大的遍历算法代码抽取为独立的类, 你可对客户端代码和集合进行整理。
    • 开闭原则。 你可实现新型的集合和迭代器并将其传递给现有代码, 无需修改现有代码。
    • 你可以并行遍历同一集合, 因为每个迭代器对象都包含其自身的遍历状态。
    • 相似的, 你可以暂停遍历并在需要时继续。
  • 缺点:
    • 如果你的程序只与简单的集合进行交互, 应用该模式可能会矫枉过正。
    • 对于某些特殊集合, 使用迭代器可能比直接遍历的效率低。

20. 什么是中介者模式,适用场景以及优缺点?

  • 中介者模式是一种行为设计模式, 能让你减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互, 迫使它们通过一个中介者对象进行合作。
  • 适合应用场景:
    • 当一些对象和其他对象紧密耦合以致难以对其进行修改时, 可使用中介者模式。
    • 当组件因过于依赖其他组件而无法在不同应用中复用时, 可使用中介者模式。
    • 如果为了能在不同情景下复用一些基本行为, 导致你需要被迫创建大量组件子类时, 可使用中介者模式。
  • 优点:
    • 单一职责原则。 你可以将多个组件间的交流抽取到同一位置, 使其更易于理解和维护。
    • 开闭原则。 你无需修改实际组件就能增加新的中介者。
    • 你可以减轻应用中多个组件间的耦合情况。
    • 你可以更方便地复用各个组件。
  • 缺点:
    • 一段时间后, 中介者可能会演化成为上帝对象。

21. 什么是备忘录模式,适用场景以及优缺点?

  • 备忘录模式是一种行为设计模式, 允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。
  • 适合应用场景:
    • 当你需要创建对象状态快照来恢复其之前的状态时, 可以使用备忘录模式。
    • 当直接访问对象的成员变量、 获取器或设置器将导致封装被突破时, 可以使用该模式。
  • 优点:
    • 你可以在不破坏对象封装情况的前提下创建对象状态快照。
    • 你可以通过让负责人维护原发器状态历史记录来简化原发器代码。
  • 缺点:
    • 如果客户端过于频繁地创建备忘录, 程序将消耗大量内存。
    • 负责人必须完整跟踪原发器的生命周期, 这样才能销毁弃用的备忘录。
    • 绝大部分动态编程语言 (例如 PHP、 Python 和 JavaScript) 不能确保备忘录中的状态不被修改。

22. 什么是观察者模式,适用场景以及优缺点?

  • 观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。
  • 适合应用场景:
    • 当一个对象状态的改变需要改变其他对象, 或实际对象是事先未知的或动态变化的时, 可使用观察者模式。
    • 当应用中的一些对象必须观察其他对象时, 可使用该模式。 但仅能在有限时间内或特定情况下使用。
  • 优点:
    • 开闭原则。 你无需修改发布者代码就能引入新的订阅者类 (如果是发布者接口则可轻松引入发布者类)。
    • 你可以在运行时建立对象之间的联系。
  • 缺点:
    • 订阅者的通知顺序是随机的。

23. 什么是状态模式,适用场景以及优缺点?

  • 状态模式是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。
  • 适合应用场景:
    • 如果对象需要根据自身当前状态进行不同行为, 同时状态的数量非常多且与状态相关的代码会频繁变更的话, 可使用状态模式。
    • 如果某个类需要根据成员变量的当前值改变自身行为, 从而需要使用大量的条件语句时, 可使用该模式。
    • 当相似状态和基于条件的状态机转换中存在许多重复代码时, 可使用状态模式。
  • 优点:
    • 单一职责原则。 将与特定状态相关的代码放在单独的类中。
    • 开闭原则。 无需修改已有状态类和上下文就能引入新状态。
    • 通过消除臃肿的状态机条件语句简化上下文代码。
  • 缺点:
    • 如果状态机只有很少的几个状态, 或者很少发生改变, 那么应用该模式可能会显得小题大作。

24. 什么是策略模式,适用场景以及优缺点?

  • 策略模式是一种行为设计模式, 它能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。
  • 适合应用场景:
    -当你想使用对象中各种不同的算法变体, 并希望能在运行时切换算法时, 可使用策略模式。
    • 如果某个类需要根据成员变量的当前值改变自身行为, 从而需要使用大量的条件语句时, 可使用该模式。
    • 当你有许多仅在执行某些行为时略有不同的相似类时, 可使用策略模式。
    • 如果算法在上下文的逻辑中不是特别重要, 使用该模式能将类的业务逻辑与其算法实现细节隔离开来。
    • 当类中使用了复杂条件运算符以在同一算法的不同变体中切换时, 可使用该模式。
  • 优点:
    • 你可以在运行时切换对象内的算法。
    • 你可以将算法的实现和使用算法的代码隔离开来。
    • 你可以使用组合来代替继承。
    • 开闭原则。 你无需对上下文进行修改就能够引入新的策略。
  • 缺点:
    • 如果你的算法极少发生改变, 那么没有任何理由引入新的类和接口。 使用该模式只会让程序过于复杂。
    • 客户端必须知晓策略间的不同——它需要选择合适的策略。
    • 许多现代编程语言支持函数类型功能, 允许你在一组匿名函数中实现不同版本的算法。 这样, 你使用这些函数的方式就和使用策略对象时完全相同, 无需借助额外的类和接口来保持代码简洁。

25. 什么是模板方法模式,适用场景以及优缺点?

  • 模板方法模式是一种行为设计模式, 它在超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。
  • 适合应用场景:
    • 当你只希望客户端扩展某个特定算法步骤, 而不是整个算法或其结构时, 可使用模板方法模式。
    • 当多个类的算法除一些细微不同之外几乎完全一样时, 你可使用该模式。 但其后果就是, 只要算法发生变化, 你就可能需要修改所有的类。
  • 优点:
    • 你可仅允许客户端重写一个大型算法中的特定部分, 使得算法其他部分修改对其所造成的影响减小。
    • 你可将重复代码提取到一个超类中。
  • 缺点:
    • 部分客户端可能会受到算法框架的限制。
    • 通过子类抑制默认步骤实现可能会导致违反里氏替换原则。
    • 模板方法中的步骤越多, 其维护工作就可能会越困难。

26. 什么是访问者模式,适用场景以及优缺点?

  • 访问者模式是一种行为设计模式, 它能将算法与其所作用的对象隔离开来。
  • 适合应用场景:
    • 如果你需要对一个复杂对象结构 (例如对象树) 中的所有元素执行某些操作, 可使用访问者模式。
    • 可使用访问者模式来清理辅助行为的业务逻辑。
    • 当某个行为仅在类层次结构中的一些类中有意义, 而在其他类中没有意义时, 可使用该模式。
  • 优点:
    • 开闭原则。 你可以引入在不同类对象上执行的新行为, 且无需对这些类做出修改。
    • 单一职责原则。 可将同一行为的不同版本移到同一个类中。
    • 访问者对象可以在与各种对象交互时收集一些有用的信息。 当你想要遍历一些复杂的对象结构 (例如对象树), 并在结构中的每个对象上应用访问者时, 这些信息可能会有所帮助。
  • 缺点:
    • 每次在元素层次结构中添加或移除一个类时, 你都要更新所有的访问者。
    • 在访问者同某个元素进行交互时, 它们可能没有访问元素私有成员变量和方法的必要权限。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/647189.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣经典题:链表合并

解决链表合并问题需要有特定的思路: 、链表合并 王赫辰/c语言 - Gitee.com 简述思路:首先先处理特殊情况,将空指针时的情况进行提前处理 然后再创建新的链表,此时使用尾插比较法: 循环条件:当两个链表中…

甲基四嗪-PEG5-炔烃,Methyltetrazine-PEG5-alkyne,可以提高生物分子的稳定性和保存期

您好,欢迎来到新研之家 文章关键词:甲基四嗪五聚乙二醇炔,甲基四嗪-PEG5-炔烃,Methyltetrazine-PEG5-alkyne 一、基本信息 产品简介:Methyltetrazine PEG5 alkyne contains methyltetrazole and PEG5 chains, as we…

pyecharts模块的下载方法以及介绍,折线图的创立

目录 1.pyecharts是什么 2.pyecharts下载方法 1.在屏幕左下角搜索这里输入cmd,找到命令提示符并且打开 2.输入pip install pyecharts 然后回车进行下载 3.检查是否下载完成 4.另一个方法 3.pyecharts入门 4.pyecharts的配置选项 set_global_opts全局配置选…

有关Quick BI中Case子句中多次使用lod函数返回空值问题分析

一、Quick BI中的lod_ include函数 lod_ include {维度1[,维度2]...:聚合表达式[:过滤条件]} 作用:将表达式中的维度一起作为分组依据进行订算。其中, 1) 维度1[,维度2]... :声明维度,指定聚合表达式要连接到的一个或多个维…

聊聊 程序员裁员潮:技术变革下的职业危机

前几天一则新闻爆料:一对来自中国的工程师夫妻在美身亡,疑因谷歌裁员致悲剧发生。看到后深感可惜,鲜活的生命就因为裁员殒落了;同时我也深有感触,有幸经历过裁员,体会过那一段低迷不振的日子。 但是回首当下…

关于达梦认证DCA DCP,TIDB认证PCTA PCTP考试那点事儿

文章最后有彩蛋,一定要看到最后... 一、正确的道路上遇到正确的你 伴随中国数据库领域的快速技术进步,国内数据库生态蓬勃发展,并不断涌现出极具创新力的产品,推动了数据库应用的遍地开花。截至2024年1月,墨天轮数据社…

【sgTree】自定义组件:加载el-tree树节点整棵树数据,实现增删改操作。

特性 可以自定义主键、配置选项支持预定义节点图标:folder文件夹|normal普通样式多个提示文本可以自定义支持动态接口增删改节点可以自定义根节点id可以设置最多允许添加的层级深度支持拖拽排序,排序过程还可以针对拖拽的节点深度进行自定义限制支持隐藏…

新建虚拟机并安装配置linux

记得看目录哦! 1. 打开VMware2. 新建虚拟机3. 配置虚拟机内存4. 配置处理器5. 配置网络6. 开始安装CentOS系统系统安装包此处自取 7. 启动虚拟机进行安装如果出现这种情况这样转成图形化界面继续安装 1. 打开VMware 点击文件—点击新建虚拟机 2. 新建虚拟机 3. 配置…

JavaScript注释使用

JavaScript注释使用心得 在学习JavaScript的过程中,我渐渐发现了注释的奥妙。它们不仅仅是代码的附属品,更是提升代码可读性和调试效率的神器。 单行注释初探 你知道吗?JavaScript中的单行注释,只需要在代码前面加上//就可以了。…

基于 MQTT 的开源桥接器:自由控制物联网设备 | 开源日报 No.151

Koenkk/zigbee2mqtt Stars: 10.5k License: GPL-3.0 Zigbee2MQTT 是一个 Zigbee 🐝 到 MQTT 桥接器 🌉,可以摆脱专有的 Zigbee 桥接器 🔨 允许您在不使用供应商桥接器或网关的情况下使用 Zigbee 设备通过 MQTT 桥接事件并控制 Z…

redis持久化之RDBAOF压缩

前引 1、redis持久化的文件是什么 dump.rdb appendonly.aof 2、这两中文件有什么异同 save 秒 1 alaways everysec no 3、文件存放的位置 dir ./ 4、默认的存放位置:命令启动的地方 dir 自定义的路径 rdb 和aof 文件 存放在同一个路径下面 5、rdb文件默认备份的策略是什么&…

redis + 拦截器 :防止数据重复提交

1.项目用到,不是核心 我们干系统开发,不免要考虑一个点,数据的重复提交。 我想我们之前如果要校验数据重复提交要求,会怎么干?会在业务层,对数据库操作,查询数据是否存在,存在就禁止插入数据; 但是吧,我们每次crud操作都会连接…

【docker】解决docker overlay2目录占用大量磁盘空间,导致验证码出不来,报错Can‘t create output stream!

问题: 验证码出现Cant create output stream!报错信息 排查: 所在服务器磁盘使用率已经到达100%,经排查,服务器目录/var/lib/docker/overlay2占用大量磁盘空间, 解决: 使用【docker system prune】命令删…

基于移动边缘计算 (MEC) 的资源调度分配优化研究(提供MATLAB代码)

一、优化模型简介 边缘计算资源调度优化模型是为了解决边缘计算场景下的资源分配和任务调度问题而提出的一种数学模型。该模型旨在通过优化算法来实现资源的有效利用和任务的高效执行,以提高边缘计算系统的性能和用户的服务体验。 在边缘计算资源调度优化模型中&a…

【python题解17】给你一个有符号整数x,返回将x中的数字部分反转后的结果。输入的整数不超过int类型的最大范围。

1. 题目&#xff1a;给你一个有符号整数x&#xff0c;返回将x中的数字部分反转后的结果。输入的整数不超过int类型的最大范围。 输入样例&#xff1a;-123 输出样例&#xff1a;-321 2. 源代码 n int(input()) flag True #代表正数 if n < 0: #当n是负数时候&#xff…

前端学习:HTTP协议、请求响应、分层解耦

HTTP协议 HTTP-概述 HTTP&#xff1a;Hyper Text Transfer Protocol(超文本传输协议)&#xff0c;规定了浏览器与服务器之间数据传输的规则。如果想知道http协议的数据传输格式有哪些&#xff0c;可以打开浏览器&#xff0c;点击 F12 打开开发者工具&#xff0c;点击Network 来…

E7数据库备份和恢复

E7数据库备份和恢复 一、实验目的 在Mysql上&#xff0c;学习如何备份数据库和恢复的各种方法。 二、实验要求: 1、基本硬件配置:英特尔Pentium III 以上,大于4G内存&#xff1b; 2、软件要求:Mysql&#xff1b; 3、时间:1小时&#xff1b; 4、撰写实验报告并按时提交。 三、…

C++刷题日记:Day 1

题目描述 小明是一野生动物园的管理人员&#xff0c;他统计了一份野生动物的名单&#xff0c;糟糕的是&#xff0c;因为操作不当导致打乱了名单&#xff0c;每种野生动物出现的次数都无法进行查询。 小明只能重新进行统计&#xff0c;已知名单中的动物名称只由大小写字母构成&a…

实用工具合集(持续更新...)

一、搜索引擎 1.1、小白盘 网站&#xff1a;https://www.xiaobaipan.com 度盘资源搜索的网站&#xff0c;能够搜索电影、电视剧、小说、音乐等资源&#xff08;注意&#xff1a;评论区很多小伙伴说小白盘有毒&#xff0c;我用谷歌浏览器搜索过几次并无大碍&#xff0c;请慎用…

C++ day 1

思维导图 使用C编写一个程序&#xff0c;输入一个字符串&#xff0c;统计大小写字母、数字、空格和其他符号的个数 #include <iostream>using namespace std;int main() {int capital 0;int lower 0;int digit 0;int spaces 0;int others 0;cout << "请…