上一篇地址:整理好了!2024年最常见 20 道设计模式面试题(七)-CSDN博客
十五、模板方法模式是如何帮助代码复用的?
模板方法模式(Template Method Pattern)是一种行为设计模式,它在超类中定义了一个操作的算法框架,同时允许子类在不改变算法结构的情况下,重新定义算法的某些特定步骤。这种模式主要用于提高代码的复用性,同时保持算法的结构不变。
模板方法模式的组成部分:
- 抽象类(Abstract Class):定义了模板方法和一些基本方法(钩子方法、抽象方法)。
- 具体类(Concrete Class):继承自抽象类,实现抽象方法,也可以覆盖钩子方法。
模板方法模式的工作原理:
- 模板方法:在抽象类中定义一个模板方法,它调用基本方法来完成某些操作。模板方法定义了算法的骨架,即算法的步骤。
- 基本方法:可以是抽象的,也可以是具体的。抽象的基本方法需要在具体类中实现;具体的基本方法提供了算法的可执行步骤。
- 钩子方法:在抽象类中定义,可以被子类覆盖。钩子方法通常在模板方法中调用,用于在算法中提供扩展点。
模板方法模式如何帮助代码复用:
- 算法框架的复用:模板方法定义了算法的框架,子类可以继承这个框架,而不需要重新编写整个算法流程。
- 可定制性:子类可以根据自己的需求,重写某些基本方法,以实现算法的特定步骤,这增加了代码的灵活性。
- 避免代码重复:如果多个子类有相同的算法结构,但某些步骤不同,模板方法模式可以避免在每个子类中重复编写相同的代码。
使用场景:
模板方法模式特别适用于以下情况:
- 当多个类有相似的行为时,它们可以共享一个模板方法。
- 当算法的整体结构固定,但某些步骤在不同的子类中有所不同时。
- 当需要通过子类来定制化或扩展算法的特定步骤时。
代码示例(伪代码):
// 抽象类
abstract class Game {
// 模板方法
public final void play() {
initialize();
startPlay();
endPlay();
}
// 抽象方法,由子类实现
protected abstract void initialize();
// 钩子方法,可以被子类覆盖
protected void startPlay() {
// 默认行为
}
// 钩子方法,可以被子类覆盖
protected void endPlay() {
// 默认行为
}
}
// 具体类:足球游戏
class SoccerGame extends Game {
protected void initialize() {
System.out.println("Setting up the soccer game.");
}
protected void startPlay() {
System.out.println("Kickoff!");
}
protected void endPlay() {
System.out.println("Game over, final score.");
}
}
// 具体类:篮球游戏
class BasketballGame extends Game {
protected void initialize() {
System.out.println("Setting up the basketball game.");
}
protected void startPlay() {
System.out.println("Tip-off!");
}
protected void endPlay() {
System.out.println("Game finished, final score.");
}
}
// 客户端代码
Game game = new SoccerGame();
game.play(); // 输出: Setting up the soccer game. Kickoff! Game over, final score.
game = new BasketballGame();
game.play(); // 输出: Setting up the basketball game. Tip-off! Game finished, final score.
在这个示例中,Game
类定义了所有游戏共有的模板方法 play
,它按照固定的顺序调用 initialize
、startPlay
和 endPlay
方法。SoccerGame
和 BasketballGame
类继承自 Game
类,并实现了或覆盖了这些方法,以提供具体的游戏逻辑。这样,play
方法的框架在所有子类中都是相同的,实现了代码的复用。
十六、描述中介者模式,并解释它如何减少类之间的耦合。
中介者模式(Mediator Pattern)是一种行为设计模式,它定义了一个中介对象,用于封装一系列对象之间的交互。中介者使各对象不需要显示地相互引用,从而使耦合度降低,而且可以独立地改变它们之间的交互。
中介者模式的组成部分:
- 中介者(Mediator):定义了同事对象之间进行通信的接口。
- 具体中介者(Concrete Mediator):实现了中介者接口,协调各个同事对象之间的交互。
- 同事对象(Colleague):也称为参与者,它们知道中介者,并通过中介者与其他同事对象进行通信。
中介者模式的工作原理:
- 同事对象不直接与其他同事对象通信,而是通过中介者来间接通信。
- 中介者负责协调各个同事对象之间的交互,它知道所有同事对象的引用。
- 同事对象通过调用中介者的方法来请求服务,或者将某些事件通知给中介者。
- 中介者根据这些请求或事件,来协调相应的同事对象进行处理。
中介者模式如何减少类之间的耦合:
- 解耦通信:通过中介者,同事对象之间的通信被抽象化,每个同事对象不需要知道其他同事对象的存在。
- 集中控制:中介者集中处理对象间的交互逻辑,这使得控制逻辑更加集中,便于管理和维护。
- 易于扩展:当需要添加新的同事对象时,只需要让新对象知道中介者即可,不需要修改其他同事对象的代码。
- 简化对象:同事对象不需要管理与其他对象的通信逻辑,可以更专注于自身的业务逻辑。
使用场景:
中介者模式特别适用于以下情况:
- 当一个系统由许多类组成,这些类之间存在复杂的引用关系,形成了网状结构时。
- 当想通过一个中间类来简化这些复杂的引用关系,从而降低系统的耦合度时。
代码示例(伪代码):
// 同事对象接口
interface Colleague {
void setMediator(Mediator mediator);
void receive(String message);
void send(String message);
}
// 具体同事对象A
class ColleagueA implements Colleague {
private Mediator mediator;
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public void receive(String message) {
System.out.println("ColleagueA received: " + message);
}
public void send(String message) {
mediator.notify(this, message);
}
}
// 具体同事对象B
class ColleagueB implements Colleague {
private Mediator mediator;
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public void receive(String message) {
System.out.println("ColleagueB received: " + message);
}
public void send(String message) {
mediator.notify(this, message);
}
}
// 中介者接口
interface Mediator {
void notify(Colleague colleague, String message);
}
// 具体中介者
class ConcreteMediator implements Mediator {
private Colleague colleagueA;
private Colleague colleagueB;
public void setColleagueA(Colleague colleagueA) {
this.colleagueA = colleagueA;
colleagueA.setMediator(this);
}
public void setColleagueB(Colleague colleagueB) {
this.colleagueB = colleagueB;
colleagueB.setMediator(this);
}
public void notify(Colleague colleague, String message) {
if (colleague == colleagueA) {
colleagueB.receive(message);
} else if (colleague == colleagueB) {
colleagueA.receive(message);
}
}
}
// 客户端代码
ConcreteMediator mediator = new ConcreteMediator();
ColleagueA colleagueA = new ColleagueA();
ColleagueB colleagueB = new ColleagueB();
mediator.setColleagueA(colleagueA);
mediator.setColleagueB(colleagueB);
colleagueA.send("Hello from A");
// 输出: ColleagueB received: Hello from A
colleagueB.send("Hello from B");
// 输出: ColleagueA received: Hello from B
在这个示例中,ConcreteMediator
类作为中介者,负责协调 ColleagueA
和 ColleagueB
之间的通信。每个同事对象只知道中介者,并通过中介者来发送和接收消息。这样,同事对象之间的耦合度被降低,而且如果需要添加新的同事对象,只需要让新对象知道中介者即可,而不需要修改现有的同事对象。