设计模式 之 行为型模式

简介

行为型模式是一种面向对象设计模式,用于解决对象之间的交互问题。这些模式关注对象之间的通信和协作,以实现特定的行为和功能。

组成

行为型模式是一种面向对象设计模式,它关注对象之间的通信和协作,以实现特定的行为和功能。行为型模式包括以下几种:

1. 观察者模式(Observer Pattern):定义对象之间的一对多依赖关系,当一个对象状态发生改变时,其所有依赖对象都会得到通知并自动更新。

2. 命令模式(Command Pattern):将请求封装为一个对象,使得可以将请求的发送者和接收者解耦,以支持命令的撤销、重做等操作。

3. 策略模式(Strategy Pattern):定义一系列算法,将每个算法都封装起来,并使它们可以互换使用,从而使算法的变化独立于使用它的客户端。

4. 模板方法模式(Template Method Pattern):定义一个算法的骨架,将一些步骤的实现延迟到子类中,以支持在不改变算法结构的情况下定制算法的某些步骤。

5. 迭代器模式(Iterator Pattern):提供一种访问一个聚合对象中各个元素的方法,而又不暴露该对象的内部表示。

6. 状态模式(State Pattern):允许对象在其内部状态发生改变时改变其行为,从而使对象在运行时看起来像是改变了其类。

7. 职责链模式(Chain of Responsibility Pattern):将请求的发送者和接收者解耦,将多个对象连接成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

8. 访问者模式(Visitor Pattern):定义一组操作,可以在不改变对象结构的前提下对对象的元素进行操作。

9. 备忘录模式(Memento Pattern):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便于以后恢复该对象的状态。

10. 中介者模式(Mediator Pattern):用一个中介对象来封装一系列的对象交互,使得这些对象之间的交互不需要显式地相互引用,从而使其耦合松散,可以独立地改变它们之间的交互。

11. 解释器模式(Interpreter Pattern):定义一个语言的文法,并定义一个解释器,用来解释语言中的句子。

这些模式提供了灵活、可扩展的解决方案,可以帮助开发者更好地组织和管理对象之间的交互。

观察者模式

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生改变时,其所有依赖对象都会自动得到通知并更新自身状态。观察者模式也被称为发布/订阅模式

观察者模式由如下两个主要组成部分组成:

  1. 被观察者对象(也称为主题):维护一个观察者列表,提供方法来添加、删除和通知观察者对象。当被观察者对象的状态发生改变时,会遍历观察者列表,调用每个观察者对象的更新方法。
  2. 观察者对象:定义一个更新方法,当被观察者对象的状态发生改变时,被通知并进行相应的更新操作。观察者对象可以根据被观察者对象的状态进行相应的更新操作。

下面是一个Java示例:

import java.util.ArrayList;
import java.util.List;

interface Observer {
    void update(String message);
}

class Subject {
    private List observers = new ArrayList<>();

    public void attach(Observer observer) {
        observers.add(observer);
    }

    public void detach(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " received message: " + message);
    }
}

public class ObserverPatternDemo {
    public static void main(String[] args) {
        Subject subject = new Subject();

        ConcreteObserver observer1 = new ConcreteObserver("Observer 1");
        ConcreteObserver observer2 = new ConcreteObserver("Observer 2");
        subject.attach(observer1);
        subject.attach(observer2);

        subject.notifyObservers("Hello World!");

        subject.detach(observer2);
        subject.notifyObservers("Goodbye!");
    }
}

在上面的示例中,Subject类表示被观察者对象,Observer接口表示观察者对象,ConcreteObserver类表示具体的观察者对象。当调用Subject对象的notifyObservers方法时,会遍历观察者列表,调用每个观察者对象的update方法,并传入被观察者对象的状态信息。在ConcreteObserver的update方法中,可以根据被观察者对象的状态进行相应的更新操作。

运行上面的示例代码,可以看到如下输出:

Observer 1 received message: Hello World!
Observer 2 received message: Hello World!
Observer 1 received message: Goodbye!

总之,观察者模式是一种常用的设计模式,它可以帮助我们实现对象之间的松耦合,并使系统更易于扩展和维护。

命令模式

命令模式(Command Pattern)是一种行为型设计模式,它将请求(命令)封装成一个对象,从而使你可以用不同的请求(命令)来参数化其他对象,同时支持命令的排队、记录日志、撤销、重做等操作。

命令模式由如下几个要素组成:

  1. 命令接口(Command Interface):定义了命令的执行方法。
  2. 具体命令类(Concrete Command):实现了命令接口,持有一个接收者对象,并在执行方法中调用接收者对象的方法。
  3. 接收者类(Receiver):负责执行具体的操作。
  4. 请求者类(Invoker):负责创建命令对象,并将其发送给接收者执行。
  5. 客户端(Client):负责创建请求者对象,并设置其命令对象。

下面是一个简单的Java示例,演示如何使用命令模式实现一个简单的遥控器控制器:

// 命令接口
interface Command {
    void execute();
}

// 具体命令类
class LightOnCommand implements Command {
    private Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.on();
    }
}

// 接收者类
class Light {
    public void on() {
        System.out.println("Light is on");
    }

    public void off() {
        System.out.println("Light is off");
    }
}

// 请求者类
class RemoteControl {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void pressButton() {
        command.execute();
    }
}

// 客户端类
public class CommandPatternDemo {
    public static void main(String[] args) {
        Light light = new Light();
        Command lightOnCommand = new LightOnCommand(light);

        RemoteControl remote = new RemoteControl();
        remote.setCommand(lightOnCommand);
        remote.pressButton();
    }
}

在上面的示例中,LightOnCommand类是一个具体的命令类,它实现了Command接口,持有一个Light对象,并在执行方法中调用Light对象的on方法。Light类是接收者类,负责执行具体的操作。RemoteControl类是请求者类,负责创建命令对象,并将其发送给接收者执行。在客户端类CommandPatternDemo中,我们创建了一个Light对象和一个LightOnCommand对象,并将LightOnCommand对象设置到RemoteControl对象中。当我们调用RemoteControl对象的pressButton方法时,就可以执行LightOnCommand对象的execute方法,从而调用Light对象的on方法。

总之,命令模式可以帮助我们将请求操作解耦,从而使系统更加灵活和易于扩展。

策略模式

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以互换。策略模式使得算法可以独立于使用它们的客户端而变化。

策略模式由如下几个要素组成:

  1. 策略接口(Strategy Interface):定义了算法的执行方法。
  2. 具体策略类(Concrete Strategy):实现了策略接口,定义了具体的算法逻辑。
  3. 上下文(Context):持有一个策略对象,负责将具体的算法委托给策略对象执行。

下面是一个简单的Java示例,演示如何使用策略模式实现一个简单的排序算法:

// 策略接口
interface SortStrategy {
    void sort(int[] array);
}

// 具体策略类
class BubbleSortStrategy implements SortStrategy {
    @Override
    public void sort(int[] array) {
        System.out.println("Sorting using bubble sort algorithm");
        // 省略具体的排序逻辑
    }
}

class QuickSortStrategy implements SortStrategy {
    @Override
    public void sort(int[] array) {
        System.out.println("Sorting using quick sort algorithm");
        // 省略具体的排序逻辑
    }
}

// 上下文
class Sorter {
    private SortStrategy strategy;

    public Sorter(SortStrategy strategy) {
        this.strategy = strategy;
    }

    public void setStrategy(SortStrategy strategy) {
        this.strategy = strategy;
    }

    public void sort(int[] array) {
        strategy.sort(array);
    }
}

// 客户端
public class StrategyPatternDemo {
    public static void main(String[] args) {
        int[] array = {5, 3, 8, 4, 1, 2};

        SortStrategy bubbleSort = new BubbleSortStrategy();
        SortStrategy quickSort = new QuickSortStrategy();

        Sorter sorter = new Sorter(bubbleSort);
        sorter.sort(array);

        sorter.setStrategy(quickSort);
        sorter.sort(array);
    }
}

在上面的示例中,SortStrategy是策略接口,定义了sort方法用于执行排序算法。BubbleSortStrategy和QuickSortStrategy是具体的策略类,实现了SortStrategy接口,分别定义了冒泡排序和快速排序的具体排序逻辑。Sorter是上下文类,持有一个SortStrategy对象,并在sort方法中调用SortStrategy对象的sort方法来执行具体的排序算法。在客户端类StrategyPatternDemo中,我们创建了一个Sorter对象,并将其初始化为使用冒泡排序算法。然后我们调用Sorter对象的sort方法,就可以执行冒泡排序算法。接着我们将Sorter对象的策略设置为使用快速排序算法,再次调用sort方法,就可以执行快速排序算法。

总之,策略模式可以帮助我们将算法和使用算法的客户端解耦,从而使系统更加灵活和易于扩展。

模板方法模式

模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤延迟到子类中实现。模板方法模式使得子类可以在不改变算法结构的情况下重新定义算法的某些步骤。

模板方法模式由如下几个要素组成:

  1. 抽象模板类(Abstract Template):定义了算法的骨架,包含若干个抽象方法(由子类实现)和具体方法(由抽象类实现)。
  2. 具体模板类(Concrete Template):实现了抽象模板类中的抽象方法,从而完成算法的具体实现。

下面是一个简单的Java示例,演示如何使用模板方法模式实现一个简单的煮咖啡算法:

// 抽象模板类
abstract class CoffeeMaker {
    public void makeCoffee() {
        boilWater();
        brewCoffee();
        pourInCup();
        addCondiments();
    }

    public void boilWater() {
        System.out.println("Boiling water");
    }

    public abstract void brewCoffee();

    public void pourInCup() {
        System.out.println("Pouring coffee into cup");
    }

    public abstract void addCondiments();
}

// 具体模板类
class AmericanoCoffeeMaker extends CoffeeMaker {
    @Override
    public void brewCoffee() {
        System.out.println("Brewing Americano coffee");
    }

    @Override
    public void addCondiments() {
        System.out.println("Adding sugar and milk");
    }
}

class EspressoCoffeeMaker extends CoffeeMaker {
    @Override
    public void brewCoffee() {
        System.out.println("Brewing Espresso coffee");
    }

    @Override
    public void addCondiments() {
        System.out.println("Adding whipped cream");
    }
}

// 客户端
public class TemplateMethodPatternDemo {
    public static void main(String[] args) {
        CoffeeMaker americanCoffeeMaker = new AmericanoCoffeeMaker();
        americanCoffeeMaker.makeCoffee();

        CoffeeMaker espressoCoffeeMaker = new EspressoCoffeeMaker();
        espressoCoffeeMaker.makeCoffee();
    }
}

在上面的示例中,CoffeeMaker是抽象模板类,定义了煮咖啡的算法骨架,包含了若干个抽象方法(brewCoffee和addCondiments)和具体方法(boilWater和pourInCup)。AmericanoCoffeeMaker和EspressoCoffeeMaker是具体模板类,实现了抽象模板类中的抽象方法,从而完成了算法的具体实现。在客户端类TemplateMethodPatternDemo中,我们创建了一个AmericanoCoffeeMaker对象和一个EspressoCoffeeMaker对象,并调用它们的makeCoffee方法,就可以煮出美式咖啡和意式浓缩咖啡了。

总之,模板方法模式可以帮助我们实现一个算法的骨架,将一些步骤延迟到子类中实现,从而使得子类可以在不改变算法结构的情况下重新定义算法的某些步骤。这种设计方式使得代码更加灵活和易于扩展。

迭代器模式

迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供一种访问集合内元素的方法,而不用暴露集合的内部结构。迭代器模式可以帮助我们在不暴露集合的内部结构的情况下,顺序访问一个集合中的元素。

迭代器模式由如下几个要素组成:

  1. 迭代器接口(Iterator Interface):定义了访问集合中元素的方法。
  2. 具体迭代器类(Concrete Iterator):实现了迭代器接口,负责遍历集合中的元素。
  3. 集合接口(Collection Interface):定义了管理集合的方法。
  4. 具体集合类(Concrete Collection):实现了集合接口,用于管理集合中的元素。

下面是一个简单的Java示例,演示如何使用迭代器模式遍历一个集合中的元素:

// 迭代器接口
interface Iterator {
    boolean hasNext();
    Object next();
}

// 集合接口
interface Collection {
    Iterator createIterator();
}

// 具体迭代器类
class ConcreteIterator implements Iterator {
    private ConcreteCollection collection;
    private int index = 0;

    public ConcreteIterator(ConcreteCollection collection) {
        this.collection = collection;
    }

    public boolean hasNext() {
        return index < collection.size();
    }

    public Object next() {
        if (hasNext()) {
            return collection.get(index++);
        }
        return null;
    }
}

// 具体集合类
class ConcreteCollection implements Collection {
    private Object[] elements = {"element1", "element2", "element3"};

    public Iterator createIterator() {
        return new ConcreteIterator(this);
    }

    public int size() {
        return elements.length;
    }

    public Object get(int index) {
        return elements[index];
    }
}

// 客户端
public class IteratorPatternDemo {
    public static void main(String[] args) {
        ConcreteCollection collection = new ConcreteCollection();
        Iterator iterator = collection.createIterator();

        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

在上面的示例中,Iterator是迭代器接口,定义了访问集合中元素的方法。ConcreteIterator是具体迭代器类,实现了迭代器接口,负责遍历集合中的元素。Collection是集合接口,定义了管理集合的方法。ConcreteCollection是具体集合类,实现了集合接口,用于管理集合中的元素。在客户端类IteratorPatternDemo中,我们创建了一个ConcreteCollection对象,并调用它的createIterator方法,返回一个ConcreteIterator对象,然后使用while循环遍历集合中的元素并输出。

总之,迭代器模式提供了一种访问集合内元素的方法,而不用暴露集合的内部结构,从而使得代码更加灵活和易于扩展。使用迭代器模式可以有效地解耦集合的遍历算法和集合本身,使得它们可以独立地变化和发展。

状态模式

状态模式(State Pattern)是一种行为型设计模式,它允许对象在其内部状态发生改变时改变其行为。状态模式将对象的行为和状态分离开来,通过定义不同状态下对象的不同行为,从而使得对象在运行时可以根据其内部状态而改变其行为。

状态模式由如下几个要素组成:

  1. 抽象状态类(Abstract State):定义了一个接口,用于封装对象的行为。
  2. 具体状态类(Concrete State):实现了抽象状态类中定义的接口,用于定义不同状态下对象的不同行为。
  3. 上下文类(Context):维护一个抽象状态类的实例,用于管理对象的状态。

下面是一个简单的Java示例,演示如何使用状态模式控制一个电视机的开关:

// 抽象状态类
interface State {
    void pressButton(TV context);
}

// 具体状态类
class OnState implements State {
    public void pressButton(TV context) {
        System.out.println("Turning off TV");
        context.setState(new OffState());
    }
}

class OffState implements State {
    public void pressButton(TV context) {
        System.out.println("Turning on TV");
        context.setState(new OnState());
    }
}

// 上下文类
class TV {
    private State state;

    public TV() {
        this.state = new OffState();
    }

    public void setState(State state) {
        this.state = state;
    }

    public void pressButton() {
        state.pressButton(this);
    }
}

// 客户端
public class StatePatternDemo {
    public static void main(String[] args) {
        TV tv = new TV();
        tv.pressButton();
        tv.pressButton();
    }
}

在上面的示例中,State是抽象状态类,定义了一个接口pressButton,用于封装对象的行为。OnState和OffState是具体状态类,实现了State中定义的接口,用于定义不同状态下对象的不同行为。TV是上下文类,维护一个State类型的实例,用于管理对象的状态。在客户端类StatePatternDemo中,我们创建了一个TV对象,并调用其pressButton方法,从而改变其状态并执行相应的行为。

总之,状态模式允许对象在其内部状态发生改变时改变其行为从而使得对象的行为可以根据其内部状态而变化。使用状态模式可以减少大量的条件语句,使得代码更加灵活和易于扩展。状态模式也符合“开闭原则”,即对修改关闭,对扩展开放。

责任链模式

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。责任链模式将这些对象串成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

责任链模式由如下几个要素组成:

  1. 抽象处理者类(Handler):定义了一个处理请求的接口,并维护一个指向下一个处理者的引用。
  2. 具体处理者类(Concrete Handler):实现了抽象处理者类中定义的接口,并负责处理某个请求或将请求传递给下一个处理者。
  3. 客户端类(Client):创建一个链,并将请求发送给链的第一个处理者。

下面是一个简单的Java示例,演示如何使用责任链模式处理员工请假申请:

// 抽象处理者类
abstract class Handler {
    protected Handler nextHandler;

    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    public abstract void handleRequest(int days);
}

// 具体处理者类
class Supervisor extends Handler {
    public void handleRequest(int days) {
        if (days <= 2) {
            System.out.println("Supervisor approved the leave for " + days + " days");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(days);
        } else {
            System.out.println("Leave application denied");
        }
    }
}

class Manager extends Handler {
    public void handleRequest(int days) {
        if (days <= 5) {
            System.out.println("Manager approved the leave for " + days + " days");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(days);
        } else {
            System.out.println("Leave application denied");
        }
    }
}

class Director extends Handler {
    public void handleRequest(int days) {
        if (days <= 10) {
            System.out.println("Director approved the leave for " + days + " days");
        } else {
            System.out.println("Leave application denied");
        }
    }
}

// 客户端类
public class ChainOfResponsibilityDemo {
    public static void main(String[] args) {
        Handler supervisor = new Supervisor();
        Handler manager = new Manager();
        Handler director = new Director();

        supervisor.setNextHandler(manager);
        manager.setNextHandler(director);

        supervisor.handleRequest(3);
        supervisor.handleRequest(7);
        supervisor.handleRequest(12);
    }
}

在上面的示例中,Handler是抽象处理者类,定义了一个处理请求的接口,并维护一个指向下一个处理者的引用。Supervisor、Manager和Director是具体处理者类,实现了Handler中定义的接口,并负责处理某个请求或将请求传递给下一个处理者。ChainOfResponsibilityDemo是客户端类,创建一个链,并将请求发送给链的第一个处理者。

总之,责任链模式允许多个对象都有机会处理请求从而避免请求的发送者和接收者之间的耦合关系。使用责任链模式可以使得代码更加灵活和易于扩展,同时也符合“开闭原则”,即对修改关闭,对扩展开放。

访问模式

访问者模式(Visitor Pattern)是一种行为型设计模式,它允许在不修改现有类的情况下向现有类结构中添加新的行为。访问者模式通过定义一个访问者类,该类可以在不改变元素类的前提下,访问并操作元素类中的各个元素。

访问者模式由如下几个要素组成:

  1. 抽象元素类(Element):定义了一个接受访问者的接口,并声明了一个接受操作的方法。
  2. 具体元素类(Concrete Element):实现了Element中定义的接口,并具体实现了接受操作的方法。
  3. 抽象访问者类(Visitor):定义了一组访问操作,分别对应不同类型的元素。
  4. 具体访问者类(Concrete Visitor):实现了Visitor中定义的接口,具体实现了一组访问操作。
  5. 对象结构类(Object Structure):定义了一个可以被访问的元素的集合,并提供了一个接受访问者的方法。

下面是一个简单的Java示例,演示如何使用访问者模式实现一个简单的购物车程序:

// 抽象元素类
interface Item {
    void accept(Visitor visitor);
}

// 具体元素类
class Book implements Item {
    private double price;

    public Book(double price) {
        this.price = price;
    }

    public double getPrice() {
        return price;
    }

    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

class CD implements Item {
    private double price;

    public CD(double price) {
        this.price = price;
    }

    public double getPrice() {
        return price;
    }

    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

// 抽象访问者类
interface Visitor {
    void visit(Book book);

    void visit(CD cd);
}

// 具体访问者类
class ShoppingCartVisitor implements Visitor {
    private double totalPrice = 0;

    public void visit(Book book) {
        totalPrice += book.getPrice();
    }

    public void visit(CD cd) {
        totalPrice += cd.getPrice();
    }

    public double getTotalPrice() {
        return totalPrice;
    }
}

// 对象结构类
class ShoppingCart {
    private List items = new ArrayList<>();

    public void addItem(Item item) {
        items.add(item);
    }

    public void accept(Visitor visitor) {
        for (Item item : items) {
            item.accept(visitor);
        }
    }
}

// 客户端类
public class VisitorDemo {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        cart.addItem(new Book(10.99));
        cart.addItem(new CD(5.99));

        ShoppingCartVisitor visitor = new ShoppingCartVisitor();
        cart.accept(visitor);

        System.out.println("Total price: " + visitor.getTotalPrice());
    }
}

在上面的示例中,Item是抽象元素类,定义了一个接受访问者的接口,并声明了一个接受操作的方法。Book和CD是具体元素类,实现了Item中定义的接口,并具体实现了接受操作的方法。Visitor是抽象访问者类,定义了一组访问操作,分别对应不同类型的元素。ShoppingCartVisitor是具体访问者类,实现了Visitor中定义的接口,具体实现了一组访问操作。ShoppingCart是对象结构类,定义了一个可以被访问的元素的集合,并提供了一个接受访问者的方法。VisitorDemo是客户端类,创建一个购物车,添加商品并接受访问者的访问。

总之,访问者模式允许在不修改现有类的情况下向现有类结构中添加新的行为。使用访问者模式可以使得代码更加灵活和易于扩展,同时也符合“开闭原则”,即对修改关闭,对扩展开放。但是,访问者模式也会增加代码的复杂度和理解难度。

备忘录模式

备忘录模式(Memento Pattern)是一种行为型设计模式,它允许在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便在以后的某个时候可以将该对象恢复到先前的状态。

备忘录模式由如下几个要素组成:

  1. 发起人类(Originator):负责创建一个备忘录,用于记录当前时刻它的内部状态,并可以使用备忘录恢复其内部状态。
  2. 备忘录类(Memento):用于存储发起人对象的内部状态,并可以防止发起人以外的其他对象访问备忘录。
  3. 管理者类(Caretaker):负责保存备忘录,并可以使用备忘录恢复发起人对象的内部状态。

下面是一个简单的Java示例,演示如何使用备忘录模式实现一个简单的文本编辑器程序:

// 备忘录类
class EditorMemento {
    private final String content;

    public EditorMemento(String content) {
        this.content = content;
    }

    public String getContent() {
        return content;
    }
}

// 发起人类
class Editor {
    private String content;

    public void setContent(String content) {
        this.content = content;
    }

    public EditorMemento save() {
        return new EditorMemento(content);
    }

    public void restore(EditorMemento memento) {
        content = memento.getContent();
    }

    public String getContent() {
        return content;
    }
}

// 管理者类
class History {
    private List mementos = new ArrayList<>();

    public void save(EditorMemento memento) {
        mementos.add(memento);
    }

    public EditorMemento get(int index) {
        return mementos.get(index);
    }
}

// 客户端类
public class MementoDemo {
    public static void main(String[] args) {
        Editor editor = new Editor();
        History history = new History();

        editor.setContent("Hello, World!");
        history.save(editor.save());

        editor.setContent("This is a new content.");
        history.save(editor.save());

        editor.setContent("This is another new content.");
        history.save(editor.save());

        System.out.println(editor.getContent());

        editor.restore(history.get(1));
        System.out.println(editor.getContent());

        editor.restore(history.get(0));
        System.out.println(editor.getContent());
    }
}

在上面的示例中,Editor是发起人类,负责创建一个备忘录,用于记录当前时刻它的内部状态,并可以使用备忘录恢复其内部状态。EditorMemento是备忘录类,用于存储发起人对象的内部状态,并可以防止发起人以外的其他对象访问备忘录。History是管理者类,负责保存备忘录,并可以使用备忘录恢复发起人对象的内部状态。MementoDemo是客户端类,创建一个编辑器对象和一个历史记录对象,对编辑器进行多次操作并保存备忘录,并使用历史记录对象恢复编辑器的状态。

总之,备忘录模式允许在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便在以后的某个时候可以将该对象恢复到先前的状态。使用备忘录模式可以使得对象的状态保存和恢复变得更加灵活和方便,同时也可以避免在对象外部直接访问对象的内部状态,从而保证了对象的封装性和安全性。

中介者模式

中介者模式(Mediator Pattern)是一种行为型设计模式,它可以将一组对象之间的交互行为封装到一个中介者对象中,从而使得这些对象之间的交互变得更加松散和可维护

在中介者模式中,多个对象之间不再直接相互通信,它们通过一个中介者对象进行通信。中介者对象负责协调对象之间的交互行为,并将交互行为转发给其他相关对象。这样,对象之间的交互行为就变成了一对多的关系,从而避免了对象之间的相互依赖关系,从而提高了系统的可维护性和可扩展性。

中介者模式通常包括如下几个角色:

  1. 中介者(Mediator):定义一个接口,用于与各个同事对象进行通信,并协调它们之间的交互行为。
  2. 具体中介者(Concrete Mediator):实现中介者接口,并负责协调各个同事对象之间的交互行为。
  3. 同事类(Colleague):定义一个接口,用于与中介者进行通信,并接收和发送消息。
  4. 具体同事类(Concrete Colleague):实现同事接口,并通过中介者对象和其他同事对象进行交互。

下面是一个简单的Java示例,演示如何使用中介者模式实现一个简单的聊天室程序:

// 中介者接口
interface ChatRoomMediator {
    void sendMessage(String message, User user);
}

// 具体中介者
class ChatRoom implements ChatRoomMediator {
    @Override
    public void sendMessage(String message, User user) {
        System.out.println(user.getName() + ": " + message);
    }
}

// 同事类
abstract class User {
    protected String name;
    protected ChatRoomMediator mediator;

    public User(String name, ChatRoomMediator mediator) {
        this.name = name;
        this.mediator = mediator;
    }

    public String getName() {
        return name;
    }

    public abstract void sendMessage(String message);
    public abstract void receiveMessage(String message);
}

// 具体同事类
class ChatUser extends User {
    public ChatUser(String name, ChatRoomMediator mediator) {
        super(name, mediator);
    }

    @Override
    public void sendMessage(String message) {
        mediator.sendMessage(message, this);
    }

    @Override
    public void receiveMessage(String message) {
        System.out.println(name + " received: " + message);
    }
}

// 客户端类
public class MediatorDemo {
    public static void main(String[] args) {
        ChatRoomMediator mediator = new ChatRoom();
        User john = new ChatUser("John", mediator);
        User jane = new ChatUser("Jane", mediator);

        john.sendMessage("Hi, Jane!");
        jane.sendMessage("Hello, John!");
    }
}

在上面的示例中,ChatRoom是具体中介者,负责协调各个同事对象之间的交互行为。User是同事类,定义一个接口,用于与中介者进行通信,并接收和发送消息。ChatUser是具体同事类,实现同事接口,并通过中介者对象和其他同事对象进行交互。MediatorDemo是客户端类,创建一个聊天室中介者对象和两个聊天用户对象,通过中介者对象和其他用户对象进行交互。

总之,中介者模式可以将一组对象之间的交互行为封装到一个中介者对象中,从而使得这些对象之间的交互变得更加松散和可维护。使用中介者模式可以避免对象之间的相互依赖关系,从而提高了系统的可维护性和可扩展性。

解释器模式

解释器模式(Interpreter Pattern)是一种行为型设计模式,它定义了一种语言文法表示,以及一个解释器来解释该语言中的句子

解释器模式通常用于对某种语言进行解释,将一些复杂的问题分解成更小的问题,然后使用语法规则来解释这些问题。解释器模式可以有效地处理一些复杂的问题,例如数学表达式、正则表达式、查询语言等。

解释器模式通常包括如下几个角色:

  1. 抽象表达式(Abstract Expression):定义一个抽象的解释器接口,包含解释方法interpret()。
  2. 终结符表达式(Terminal Expression):实现抽象表达式接口,并提供具体的解释方法。
  3. 非终结符表达式(Non-terminal Expression):实现抽象表达式接口,并包含其他表达式的集合,用于组合表达式。
  4. 上下文(Context):包含要解释的语言文法表示,并维护解释器需要的状态。

下面是一个简单的Java示例,演示如何使用解释器模式对数学表达式进行解释:

// 抽象表达式
interface Expression {
    int interpret(Context context);
}

// 终结符表达式
class NumberExpression implements Expression {
    private int value;

    public NumberExpression(int value) {
        this.value = value;
    }

    @Override
    public int interpret(Context context) {
        return value;
    }
}

// 非终结符表达式
class AddExpression implements Expression {
    private Expression left;
    private Expression right;

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

    @Override
    public int interpret(Context context) {
        return left.interpret(context) + right.interpret(context);
    }
}

// 上下文
class Context {
    private int x;
    private int y;
    private int z;

    public Context(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getZ() {
        return z;
    }
}

// 客户端类
public class InterpreterDemo {
    public static void main(String[] args) {
        Context context = new Context(3, 4, 5);

        Expression expression = new AddExpression(
                new NumberExpression(context.getX()),
                new AddExpression(
                        new NumberExpression(context.getY()),
                        new NumberExpression(context.getZ())
                )
        );

        int result = expression.interpret(context);
        System.out.println("Result: " + result);
    }
}

在上面的示例中,Expression是抽象表达式,定义了解释方法interpret()。NumberExpression是终结符表达式,实现抽象表达式接口,并提供具体的解释方法。AddExpression是非终结符表达式,实现抽象表达式接口,并包含其他表达式的集合,用于组合表达式。Context是上下文,包含要解释的语言文法表示,并维护解释器需要的状态。InterpreterDemo是客户端类,创建一个上下文对象,并使用表达式来解释该上下文。

总之,解释器模式可以用于对某种语言进行解释,将一些复杂的问题分解成更小的问题,然后使用语法规则来解释这些问题。使用解释器模式可以有效地处理一些复杂的问题,例如数学表达式、正则表达式、查询语言等。

展开阅读全文

页面更新:2024-05-20

标签:模式   观察者   示例   抽象   算法   接口   定义   对象   状态   方法

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top