整理好了!2024年最常见 20 道设计模式面试题(八)

上一篇地址:整理好了!2024年最常见 20 道设计模式面试题(七)-CSDN博客

十五、模板方法模式是如何帮助代码复用的?

模板方法模式(Template Method Pattern)是一种行为设计模式,它在超类中定义了一个操作的算法框架,同时允许子类在不改变算法结构的情况下,重新定义算法的某些特定步骤。这种模式主要用于提高代码的复用性,同时保持算法的结构不变。

模板方法模式的组成部分:

  1. 抽象类(Abstract Class):定义了模板方法和一些基本方法(钩子方法、抽象方法)。
  2. 具体类(Concrete Class):继承自抽象类,实现抽象方法,也可以覆盖钩子方法。

模板方法模式的工作原理:

  1. 模板方法:在抽象类中定义一个模板方法,它调用基本方法来完成某些操作。模板方法定义了算法的骨架,即算法的步骤。
  2. 基本方法:可以是抽象的,也可以是具体的。抽象的基本方法需要在具体类中实现;具体的基本方法提供了算法的可执行步骤。
  3. 钩子方法:在抽象类中定义,可以被子类覆盖。钩子方法通常在模板方法中调用,用于在算法中提供扩展点。

模板方法模式如何帮助代码复用:

  • 算法框架的复用:模板方法定义了算法的框架,子类可以继承这个框架,而不需要重新编写整个算法流程。
  • 可定制性:子类可以根据自己的需求,重写某些基本方法,以实现算法的特定步骤,这增加了代码的灵活性。
  • 避免代码重复:如果多个子类有相同的算法结构,但某些步骤不同,模板方法模式可以避免在每个子类中重复编写相同的代码。

使用场景:

模板方法模式特别适用于以下情况:

  • 当多个类有相似的行为时,它们可以共享一个模板方法。
  • 当算法的整体结构固定,但某些步骤在不同的子类中有所不同时。
  • 当需要通过子类来定制化或扩展算法的特定步骤时。

代码示例(伪代码):

// 抽象类
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,它按照固定的顺序调用 initializestartPlayendPlay 方法。SoccerGameBasketballGame 类继承自 Game 类,并实现了或覆盖了这些方法,以提供具体的游戏逻辑。这样,play 方法的框架在所有子类中都是相同的,实现了代码的复用。

十六、描述中介者模式,并解释它如何减少类之间的耦合。

中介者模式(Mediator Pattern)是一种行为设计模式,它定义了一个中介对象,用于封装一系列对象之间的交互。中介者使各对象不需要显示地相互引用,从而使耦合度降低,而且可以独立地改变它们之间的交互。

中介者模式的组成部分:

  1. 中介者(Mediator):定义了同事对象之间进行通信的接口。
  2. 具体中介者(Concrete Mediator):实现了中介者接口,协调各个同事对象之间的交互。
  3. 同事对象(Colleague):也称为参与者,它们知道中介者,并通过中介者与其他同事对象进行通信。

中介者模式的工作原理:

  1. 同事对象不直接与其他同事对象通信,而是通过中介者来间接通信。
  2. 中介者负责协调各个同事对象之间的交互,它知道所有同事对象的引用。
  3. 同事对象通过调用中介者的方法来请求服务,或者将某些事件通知给中介者。
  4. 中介者根据这些请求或事件,来协调相应的同事对象进行处理。

中介者模式如何减少类之间的耦合:

  • 解耦通信:通过中介者,同事对象之间的通信被抽象化,每个同事对象不需要知道其他同事对象的存在。
  • 集中控制:中介者集中处理对象间的交互逻辑,这使得控制逻辑更加集中,便于管理和维护。
  • 易于扩展:当需要添加新的同事对象时,只需要让新对象知道中介者即可,不需要修改其他同事对象的代码。
  • 简化对象:同事对象不需要管理与其他对象的通信逻辑,可以更专注于自身的业务逻辑。

使用场景:

中介者模式特别适用于以下情况:

  • 当一个系统由许多类组成,这些类之间存在复杂的引用关系,形成了网状结构时。
  • 当想通过一个中间类来简化这些复杂的引用关系,从而降低系统的耦合度时。

代码示例(伪代码):

// 同事对象接口
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 类作为中介者,负责协调 ColleagueAColleagueB 之间的通信。每个同事对象只知道中介者,并通过中介者来发送和接收消息。这样,同事对象之间的耦合度被降低,而且如果需要添加新的同事对象,只需要让新对象知道中介者即可,而不需要修改现有的同事对象。

  • 39
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值