持续总结中!2024年面试必问 20 道设计模式面试题(九)

上一篇地址:持续总结中!2024年面试必问 20 道设计模式面试题(八)-CSDN博客

十七、模板方法模式(Template Method Pattern)是如何工作的?

模板方法模式(Template Method Pattern)是一种行为型设计模式,它在超类中定义了一个算法的框架,同时允许子类在不改变算法结构的前提下,重新定义算法的特定步骤。

模板方法模式的定义:

模板方法模式通过提供一个抽象类(模板类),在其中定义了一系列基本操作的序列,并在某些步骤中使用钩子(hook)方法来指定子类可以扩展或重写的地方。

模板方法模式的组成:

  1. 抽象模板类(Abstract Template Class):定义了算法的框架,包括基本操作的序列和钩子方法。
  2. 具体模板类(Concrete Template Class):继承自抽象模板类,实现或重写钩子方法以及一些基本操作。
  3. 钩子方法(Hook Method):在抽象模板类中定义的可以被子类重写的方法,用于在算法中提供扩展点。

模板方法模式如何工作:

  1. 定义算法框架:在抽象模板类中定义算法的骨架,包括算法的各个步骤和执行顺序。

  2. 基本操作:算法框架中包括一些基本操作,这些操作可以是具体实现的,也可以是抽象的,需要子类实现。

  3. 钩子方法:在算法框架中定义一些可以被子类重写的方法,这些方法通常用于提供额外的行为或配置。

  4. 子类实现:具体模板类继承自抽象模板类,并根据需要重写钩子方法和实现抽象操作。

  5. 算法执行:模板方法提供一个方法(通常是final的),用于启动算法的执行。这个方法按照定义好的顺序调用基本操作和钩子方法。

  6. 扩展性:通过重写钩子方法,子类可以在不改变算法结构的前提下,向算法中添加特定的行为。

使用场景:

  • 当需要在多个类中复用相同的算法框架,但允许每个类在某些步骤中有不同的行为时。
  • 当需要控制子类扩展,同时提供开放-封闭原则的实现时。

示例:

假设我们有一个咖啡制作流程,其中包括烧水、研磨咖啡豆、冲泡咖啡等步骤。不同的咖啡类型可能在某些步骤上有所不同,例如添加调料。

  1. 抽象模板类CoffeeTemplate,定义了制作咖啡的算法框架,包括boilWater()grindCoffeeBeans()brewCoffee()等基本操作,以及一个addCondiments()钩子方法。
  2. 具体模板类LatteCoffeeEspressoCoffee,继承自CoffeeTemplate,实现或重写钩子方法和基本操作。
  3. 客户端:使用具体模板类来制作咖啡。

客户端代码可以这样使用模板方法模式:

CoffeeTemplate coffee;
coffee = new LatteCoffee();
coffee.prepareRecipe(); // 制作拿铁咖啡

coffee = new EspressoCoffee();
coffee.prepareRecipe(); // 制作浓缩咖啡

在这个例子中,CoffeeTemplate是抽象模板类,定义了咖啡制作的算法框架;LatteCoffeeEspressoCoffee是具体模板类,提供了不同的调料添加方法。通过模板方法模式,我们可以保持算法结构的一致性,同时允许每个具体类在某些步骤中有不同的行为。这提供了高度的可扩展性和可维护性。

十八、访问者模式(Visitor Pattern)解决了什么问题?

访问者模式(Visitor Pattern)解决了面向对象设计中的两个主要问题:

  1. 对象结构的扩展性问题:在传统的面向对象设计中,如果要增加新的操作,通常需要修改已有的对象类。这意味着要更改对象类中的代码,违反了开闭原则(对扩展开放,对修改封闭)。访问者模式通过将操作逻辑从对象结构中分离出来,封装到独立的访问者类中,使得在不修改现有对象结构的情况下,可以增加新的操作。

  2. 对象结构与操作之间的耦合问题:当对象结构和操作逻辑紧密耦合时,任何对操作逻辑的修改都可能影响到对象结构,反之亦然。这会导致代码难以维护和扩展。访问者模式通过引入一个访问者接口,将操作逻辑集中管理,降低了对象结构和操作逻辑之间的耦合度。

访问者模式的主要优点包括:

  • 分离操作逻辑:将操作逻辑从对象结构中分离,使得操作可以在不修改对象结构的情况下添加或修改。
  • 增强灵活性:通过访问者模式,可以很容易地定义新的操作,而无需了解对象结构的内部实现。
  • 单一职责原则:对象结构专注于其自身的职责,而访问者类负责执行操作,这符合单一职责原则。
  • 多态性:访问者模式利用了多态性,可以在运行时动态地将不同的操作应用到不同的对象上。

访问者模式的组成部分:

  1. 访问者接口(Visitor Interface):定义了对所有具体元素类的操作接口。
  2. 具体访问者(Concrete Visitor):实现访问者接口,提供对各个具体元素类的访问操作。
  3. 元素接口(Element Interface):声明了一个接受访问者的接口,通常包含一个accept方法。
  4. 具体元素(Concrete Element):实现元素接口,每个具体元素类可以提供一个接受访问者的方法。
  5. 对象结构(Object Structure):可以是一个复合集合,允许访问者访问其包含的所有元素,同时提供了遍历集合的机制。

使用场景:

  • 当对象结构稳定,但需要对结构中的元素执行多种不同的操作时。
  • 当需要在不修改现有类的情况下,向对象结构中添加新的操作时。
  • 当对象结构中的元素需要动态地与多种不同的操作关联时。

示例:

假设有一个文档编辑系统,文档由多种不同类型的元素组成,例如段落、图片和表格。我们希望在不修改这些元素类的情况下,添加新的文档操作,如“打印”或“复制”。

  1. 访问者接口:定义了visit(Paragraph)visit(Image)visit(Table)等方法。
  2. 具体访问者:如PrintVisitorCopyVisitor,实现了访问者接口,定义了如何打印或复制文档中的每个元素。
  3. 元素接口:定义了一个accept方法,用于接受访问者。
  4. 具体元素:如ParagraphImageTable类,实现了元素接口,并通过accept方法接收访问者。
  5. 对象结构:如Document类,包含一个元素的集合,并提供了遍历这些元素的方法。

通过访问者模式,我们可以轻松地添加新的操作,如添加一个ExportVisitor来导出文档,而不需要修改现有的元素类。这种模式提高了系统的灵活性和可维护性。

  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值