设计模式概述 - 中介 & 享元 & 解释器 & 访问者

举报
yd_294916736 发表于 2026/11/08 00:15:49 2026/11/08
【摘要】 设计模式概述 - 中介 & 享元 & 解释器 & 访问者

设计模式概述 - 中介 & 享元 & 解释器 & 访问者

中介者模式简述

中介者模式(Mediator Pattern)是一种行为型设计模式,它通过引入一个中介者对象来降低多个对象之间的复杂通信。中介者对象负责协调各个对象的交互,从而使得对象之间不需要直接引用,减少了耦合度,提高了系统的灵活性和可维护性。

角色

  • 中介者接口(Mediator):定义与各个同事对象的交互接口。
  • 具体中介者(ConcreteMediator):实现中介者接口,协调各个同事对象的交互。
  • 同事类(Colleague):定义与中介者的接口,并在需要时与中介者进行交互。

优点

  • 降低耦合度:中介者模式使得同事对象之间不需要直接交互,降低了耦合度。
  • 集中控制:所有的交互都通过中介者进行,便于控制和管理。
  • 易于扩展:可以通过增加新的同事类和中介者类,轻松扩展系统的功能。

缺点

  • 中介者复杂性:中介者可能变得过于复杂,尤其是在处理多个同事对象时。
  • 单点故障:中介者成为所有交互的中心,若中介者出现问题,整个系统的交互会受到影响。

示例代码

// 中介者接口
interface Mediator {
    void send(String message, Colleague colleague);
}

// 同事类
abstract class Colleague {
    protected Mediator mediator;

    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }

    public abstract void receive(String message);
}

// 具体同事类A
class ConcreteColleagueA extends Colleague {
    public ConcreteColleagueA(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void receive(String message) {
        System.out.println("Colleague A received: " + message);
    }

    public void send(String message) {
        System.out.println("Colleague A sends: " + message);
        mediator.send(message, this);
    }
}

// 具体同事类B
class ConcreteColleagueB extends Colleague {
    public ConcreteColleagueB(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void receive(String message) {
        System.out.println("Colleague B received: " + message);
    }

    public void send(String message) {
        System.out.println("Colleague B sends: " + message);
        mediator.send(message, this);
    }
}

// 具体中介者
class ConcreteMediator implements Mediator {
    private ConcreteColleagueA colleagueA;
    private ConcreteColleagueB colleagueB;

    public void setColleagueA(ConcreteColleagueA colleagueA) {
        this.colleagueA = colleagueA;
    }

    public void setColleagueB(ConcreteColleagueB colleagueB) {
        this.colleagueB = colleagueB;
    }

    @Override
    public void send(String message, Colleague colleague) {
        if (colleague == colleagueA) {
            colleagueB.receive(message);
        } else {
            colleagueA.receive(message);
        }
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        ConcreteMediator mediator = new ConcreteMediator();

        ConcreteColleagueA colleagueA = new ConcreteColleagueA(mediator);
        ConcreteColleagueB colleagueB = new ConcreteColleagueB(mediator);

        mediator.setColleagueA(colleagueA);
        mediator.setColleagueB(colleagueB);

        colleagueA.send("Hello, B!"); // Colleague A sends: Hello, B!
        colleagueB.send("Hi, A!");     // Colleague B sends: Hi, A!
    }
}

享元模式简述

享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享对象来减少内存使用和提高性能。享元模式特别适用于大量细粒度对象的场景,通过将对象的状态分为内部状态和外部状态,来实现对象的共享。

角色

  • 享元接口(Flyweight):定义享元对象的接口。
  • 具体享元(ConcreteFlyweight):实现享元接口,提供具体的共享对象。
  • 非共享享元(UnsharedFlyweight):不需要共享的对象。
  • 享元工厂(FlyweightFactory):负责创建和管理享元对象,确保共享的对象只有一个实例。

优点

  • 减少内存使用:通过共享对象,显著减少了内存的使用,特别是在大量相似对象的情况下。
  • 提高性能:减少了对象的创建和销毁,提高了性能。
  • 灵活性:可以轻松地扩展享元对象的数量和类型。

缺点

  • 复杂性:引入享元模式可能会增加系统的复杂性,特别是在管理共享对象时。
  • 状态管理:需要仔细管理对象的内部状态和外部状态,以避免不必要的共享。

示例代码

import java.util.HashMap;
import java.util.Map;

// 享元接口
interface Flyweight {
    void operation(String externalState);
}

// 具体享元
class ConcreteFlyweight implements Flyweight {
    private String intrinsicState;

    public ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    @Override
    public void operation(String externalState) {
        System.out.println("Intrinsic State: " + intrinsicState + ", External State: " + externalState);
    }
}

// 享元工厂
class FlyweightFactory {
    private static final Map<String, Flyweight> flyweightMap = new HashMap<>();

    public static Flyweight getFlyweight(String intrinsicState) {
        if (!flyweightMap.containsKey(intrinsicState)) {
            flyweightMap.put(intrinsicState, new ConcreteFlyweight(intrinsicState));
        }
        return flyweightMap.get(intrinsicState);
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();

        Flyweight flyweight1 = factory.getFlyweight("State1");
        flyweight1.operation("External State A");

        Flyweight flyweight2 = factory.getFlyweight("State1");
        flyweight2.operation("External State B");

        Flyweight flyweight3 = factory.getFlyweight("State2");
        flyweight3.operation("External State C");

        // 验证共享
        System.out.println("flyweight1 == flyweight2: " + (flyweight1 == flyweight2)); // 输出 true
    }
}

解释器模式简述

解释器模式(Interpreter Pattern)是一种行为型设计模式,它提供了一个语言的文法表示,并定义了一个解释器来解释该语言中的句子。该模式主要用于需要解析和执行特定语言或表达式的场景。

角色

  • 抽象表达式(AbstractExpression):定义了一个解释操作的接口。
  • 终结符表达式(TerminalExpression):实现了与文法中的终结符相关的解释操作。
  • 非终结符表达式(NonTerminalExpression):实现了与文法中的非终结符相关的解释操作。
  • 上下文(Context):包含解释所需的信息。

优点

  • 易于扩展:可以通过增加新的终结符和非终结符表达式来扩展语言。
  • 简化了语法分析:将语法规则与解释逻辑分离,使得语法分析和执行变得更加清晰。

缺点

  • 类的数量增加:每种文法规则都需要创建相应的类,可能导致类的数量激增。
  • 性能开销:在处理复杂表达式时,可能会引入性能开销。

示例代码

import java.util.HashMap;
import java.util.Map;

// 抽象表达式
interface Expression {
    int interpret(Map<String, Integer> context);
}

// 终结符表达式
class NumberExpression implements Expression {
    private String number;

    public NumberExpression(String number) {
        this.number = number;
    }

    @Override
    public int interpret(Map<String, Integer> context) {
        return context.get(number);
    }
}

// 非终结符表达式
class AddExpression implements Expression {
    private Expression leftExpression;
    private Expression rightExpression;

    public AddExpression(Expression left, Expression right) {
        this.leftExpression = left;
        this.rightExpression = right;
    }

    @Override
    public int interpret(Map<String, Integer> context) {
        return leftExpression.interpret(context) + rightExpression.interpret(context);
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        // 定义上下文
        Map<String, Integer> context = new HashMap<>();
        context.put("x", 10);
        context.put("y", 20);

        // 创建表达式:x + y
        Expression expression = new AddExpression(new NumberExpression("x"), new NumberExpression("y"));

        // 解释表达式
        int result = expression.interpret(context);
        System.out.println("Result: " + result); // 输出 "Result: 30"
    }
}

访问者模式简述

访问者模式(Visitor Pattern)是一种行为型设计模式,它允许你在不改变对象结构的前提下,定义新的操作。通过将操作封装在访问者对象中,可以在多个对象上执行这些操作,从而实现对对象结构的扩展。

角色

  • 访问者接口(Visitor):定义访问者的接口,声明访问每个元素的方法。
  • 具体访问者(ConcreteVisitor):实现访问者接口,定义对每个元素的具体操作。
  • 元素接口(Element):定义接受访问者的接口。
  • 具体元素(ConcreteElement):实现元素接口,定义接受访问者的方法。
  • 对象结构(ObjectStructure):维护元素对象的集合,并提供一个方法来接受访问者。

双分派技术

双分派意味着得到执行的操作决定于请求的种类和两个接收者的类型,换句话说,根据类的对象类型和该方法的参数去执行相应的操作。在访问者模式中,具体元素就使用了该技术。

优点

  • 灵活性:可以在不修改元素类的情况下,增加新的操作。
  • 单一职责:将操作与对象结构分离,符合单一职责原则。

缺点

  • 增加复杂性:引入访问者模式可能会使系统变得更加复杂,尤其是当元素类的数量较多时。
  • 难以维护:如果元素类的结构发生变化,需要对访问者接口进行修改,可能会影响到所有具体访问者。

示例代码

// 访问者接口
interface Visitor {
    void visit(ConcreteElementA elementA);
    void visit(ConcreteElementB elementB);
}

// 具体访问者
class ConcreteVisitor implements Visitor {
    @Override
    public void visit(ConcreteElementA elementA) {
        System.out.println("Visiting Element A");
    }

    @Override
    public void visit(ConcreteElementB elementB) {
        System.out.println("Visiting Element B");
    }
}

// 元素接口
interface Element {
    void accept(Visitor visitor);
}

// 具体元素A
class ConcreteElementA implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

// 具体元素B
class ConcreteElementB implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

// 对象结构
class ObjectStructure {
    private List<Element> elements = new ArrayList<>();

    public void addElement(Element element) {
        elements.add(element);
    }

    public void accept(Visitor visitor) {
        for (Element element : elements) {
            element.accept(visitor);
        }
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        ObjectStructure structure = new ObjectStructure();
        structure.addElement(new ConcreteElementA());
        structure.addElement(new ConcreteElementB());

        ConcreteVisitor visitor = new ConcreteVisitor();
        structure.accept(visitor); // 输出 "Visiting Element A" 和 "Visiting Element B"
    }
}
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。