设计模式 (四) 行为型设计模式系列

目录

1.职责链模式

2.命令模式

3.解释器模式

5.中介者模式

6.备忘录模式

7.观察者模式

8.状态模式

9.策略模式

10.模板方法模式


1.职责链模式

职责链模式将请求的发送者和接收者解耦,从而允许多个对象都有机会处理请求。这种模式通常用于处理请求的分发、过滤等操作。

职责链模式的实现方式比较简单,只需要定义一个处理请求的接口和一些具体处理者,然后让处理者持有下一个处理者的引用即可。客户端可以根据需要创建不同的处理者,并将它们串成一条链,从而实现请求的分发和过滤。

下面是一个职责链模式的实现:

public interface Handler {
    void handleRequest(Request request);
}

public class ConcreteHandlerA implements Handler {
    private Handler nextHandler;

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

    @Override
    public void handleRequest(Request request) {
        if (request.getType() == RequestType.TYPE1) {
            System.out.println("ConcreteHandlerA handles request: " + request.getName());
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

public class ConcreteHandlerB implements Handler {
    private Handler nextHandler;

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

    @Override
    public void handleRequest(Request request) {
        if (request.getType() == RequestType.TYPE2) {
            System.out.println("ConcreteHandlerB handles request: " + request.getName());
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

public class Request {
    private RequestType type;
    private String name;

    public Request(RequestType type, String name) {
        this.type = type;
        this.name = name;
    }

    public RequestType getType() {
        return type;
    }

    public String getName() {
        return name;
    }
}

public enum RequestType {
    TYPE1, TYPE2
}

2.命令模式

命令模式是一种行为型设计模式,它将请求封装成对象,从而允许我们使用不同的请求、队列或者日志来参数化其他对象。这种模式通常用于处理请求的撤销、重做、事务等操作。

命令模式的实现方式比较简单,只需要定义一个命令接口和一些具体命令类,然后让命令类持有执行命令的对象的引用即可。客户端可以根据需要创建不同的命令对象,并将它们传递给执行命令的对象。

在命令模式中,有以下几个角色:

  • Command(命令接口):定义了执行命令的方法 execute。

  • ConcreteCommand(具体命令类):实现了 Command 接口,并持有执行命令的对象的引用。

  • Receiver(执行命令的对象):定义了执行命令的方法,具体命令类将调用该方法来执行命令。

  • Invoker(调用者):持有命令对象的引用,并调用命令对象的 execute 方法来执行命令。

下面是一个命令模式的实现:

public interface Command {
    void execute();
}

public class ConcreteCommand implements Command {
    private Receiver receiver;

    public ConcreteCommand(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        receiver.action();
    }
}

public class Receiver {
    public void action() {
        System.out.println("Receiver action");
    }
}

public class Invoker {
    private Command command;

    public Invoker(Command command) {
        this.command = command;
    }

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

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

3.解释器模式

解释器模式定义了一种语言,用于解释特定的上下文。这种模式通常用于处理自然语言、数学表达式等问题。

解释器模式的实现方式比较复杂,需要定义一个抽象语法树和一些具体节点类,用于表示语言的语法结构。然后,我们定义一个解释器接口和一些具体解释器类,用于解释语法树中的节点。客户端可以根据需要创建不同的语法树和解释器对象,并将它们组合起来来解决特定的问题。

4.迭代器模式

迭代器模式提供一种方法来访问聚合对象中的元素,而不需要暴露聚合对象的内部表示。这种模式通常用于处理集合类对象的遍历操作。

迭代器模式的实现方式比较简单,只需要定义一个迭代器接口和一个具体迭代器类,然后让聚合对象实现迭代器接口中的方法即可。客户端可以通过迭代器对象来访问聚合对象中的元素。

下面是一个迭代器模式的实现:

public interface Iterator<T> {
    boolean hasNext();

    T next();
}

public interface Aggregate<T> {
    Iterator<T> createIterator();
}

public class ConcreteAggregate<T> implements Aggregate<T> {
    private List<T> list = new ArrayList<>();

    public void add(T t) {
        list.add(t);
    }

    public void remove(T t) {
        list.remove(t);
    }

    @Override
    public Iterator<T> createIterator() {
        return new ConcreteIterator<>(list);
    }
}

public class ConcreteIterator<T> implements Iterator<T> {
    private List<T> list;
    private int index = 0;

    public ConcreteIterator(List<T> list) {
        this.list = list;
    }

    @Override
    public boolean hasNext() {
        return index < list.size();
    }

    @Override
    public T next() {
        if (hasNext()) {
            return list.get(index++);
        }
        return null;
    }
}

在这个例子中,我们定义了一个迭代器接口 Iterator 和一个聚合接口 Aggregate。然后,我们定义了一个具体聚合类 ConcreteAggregate,它实现了 Aggregate 接口中的 createIterator 方法,并持有一个元素列表 list。最后,我们定义了一个具体迭代器类 ConcreteIterator,它实现了 Iterator 接口中的 hasNext 和 next 方法,用于遍历元素列表 list。客户端可以通过调用 ConcreteAggregate 的 createIterator 方法来获取一个迭代器对象,并使用迭代器对象来访问聚合对象中的元素。

5.中介者模式

中介者模式定义了一个中介对象,用于协调一组对象之间的交互。这种模式通常用于处理对象之间的复杂交互,从而减少对象之间的耦合。

中介者模式的实现方式比较简单,只需要定义一个中介者接口和一些具体中介者类,然后让对象持有中介者对象的引用即可。客户端可以通过中介者对象来协调对象之间的交互。

6.备忘录模式

7.观察者模式

观察者模式定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。这种模式通常用于处理对象之间的消息传递,例如 GUI 中的事件处理。

观察者模式的实现方式比较简单,只需要定义一个主题和一些观察者,然后让观察者注册到主题中即可。当主题的状态发生改变时,它会自动通知所有注册的观察者,并调用它们的更新方法。

下面是一个观察者模式的实现:

public interface Observer {
    void update();
}

public class ConcreteObserver implements Observer {
    private String name;
    private ConcreteSubject subject;

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

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

public interface Subject {
    void registerObserver(Observer observer);

    void removeObserver(Observer observer);

    void notifyObservers();
}

public class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
        notifyObservers();
    }

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer); 
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

在这个例子中,我们定义了一个观察者接口 Observer 和一个具体观察者类 ConcreteObserver。然后,我们定义了一个主题接口 Subject 和一个具体主题类 ConcreteSubject。在 ConcreteSubject 中,我们定义了一个观察者列表 observers 和一个消息 message,然后实现了 Subject 接口中的三个方法。当消息发生改变时,我们会调用 notifyObservers 方法,通知所有注册的观察者,并调用它们的 update 方法。

8.状态模式

状态模式允许对象在内部状态发生改变时改变它的行为,从而使对象看起来像是改变了它的类。这种模式通常用于处理对象的状态转换和行为变化。

状态模式的实现方式比较简单,只需要定义一个状态接口和一些具体状态类,然后让对象持有当前状态的引用即可。客户端可以通过改变对象的状态来改变它的行为。

9.策略模式

策略模式定义一系列算法,将每个算法都封装起来,并且使它们之间可以互换。这种模式通常用于处理多种算法的情况,例如排序算法中的比较函数。

策略模式的实现方式比较简单,只需要定义一个策略接口和一些具体策略类,然后让客户端持有策略接口的引用即可。客户端可以根据需要选择不同的具体策略类,从而实现不同的算法。

下面是一个策略模式的实现:

public interface SortStrategy {
    void sort(int[] array);
}

public class BubbleSortStrategy implements SortStrategy {
    @Override
    public void sort(int[] array) {
        for (int i = 0; i < array.length - 1; i++) {
            for (int j = 0; j < array.length - i - 1; j++) {
                if (array[j] > array[j + 1]) {
                    int temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
    }
}

public class QuickSortStrategy implements SortStrategy {
    @Override
    public void sort(int[] array) {
        quickSort(array, 0, array.length - 1);
    }

    private void quickSort(int[] array, int left, int right) {
        if (left >= right) {
            return;
        }
        int pivot = partition(array, left, right);
        quickSort(array, left, pivot - 1);
        quickSort(array, pivot + 1, right);
    }

    private int partition(int[] array, int left, int right) {
        int pivot = array[left];
        int i = left, j = right;
        while (i < j) {
            while (i < j && array[j] >= pivot) {
                j--;
            }
            array[i] = array[j];
            while (i < j && array[i] <= pivot) {
                i++;
            }
            array[j] = array[i];
        }
        array[i] = pivot;
        return i;
    }
}

public class Sorter {
    private SortStrategy sortStrategy;

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

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

在这个例子中,我们定义了一个策略接口 SortStrategy 和两个具体策略类 BubbleSortStrategy 和 QuickSortStrategy。然后,我们定义了一个排序器类 Sorter,让它持有策略接口的引用。最后,我们可以通过调用 Sorter 的 sort 方法来排序一个数组,并且可以根据需要选择不同的具体策略类。

10.模板方法模式

模板方法模式定义一个操作中的算法骨架,而将一些步骤延迟到子类中。这种模式通常用于处理算法的变化点,例如排序算法中的比较函数。

模板方法模式的实现方式比较简单,只需要定义一个抽象类和一些具体子类,然后在抽象类中定义一个模板方法,该方法包含算法的骨架,而将一些步骤延迟到具体子类中实现。

下面是一个模板方法模式的实现:

public abstract class AbstractSort {
    public final void sort(int[] array) {
        if (array == null || array.length <= 1) {
            return;
        }
        doSort(array);
    }

    protected abstract void doSort(int[] array);
}

public class BubbleSort extends AbstractSort {
    @Override
    protected void doSort(int[] array) {
        for (int i = 0; i < array.length - 1; i++) {
            for (int j = 0; j < array.length - i - 1; j++) {
                if (array[j] > array[j + 1]) {
                    int temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
    }
}

public class QuickSort extends AbstractSort {
    @Override
    protected void doSort(int[] array) {
        quickSort(array, 0, array.length - 1);
    }

    private void quickSort(int[] array, int left, int right) {
        if (left >= right) {
            return;
        }
        int pivot = partition(array, left, right);
        quickSort(array, left, pivot - 1);
        quickSort(array, pivot + 1, right);
    }

    private int partition(int[] array, int left, int right) {
        int pivot = array[left];
        int i = left, j = right;
        while (i < j) {
            while (i < j && array[j] >= pivot) {
                j--;
            }
            array[i] = array[j];
            while (i < j && array[i] <= pivot) {
                i++;
            }
            array[j] = array[i];
        }
        array[i] = pivot;
        return i;
    }
}

在这个例子中,我们定义了一个抽象类 AbstractSort 和两个具体子类 BubbleSort 和 QuickSort。在抽象类中,我们定义了一个模板方法 sort,该方法包含算法的骨架,而将一些步骤延迟到具体子类中实现。在具体子类中,我们实现了 doSort 方法,该方法实现了算法中的具体步骤。最后,我们可以通过调用 sort 方法来排序一个数组。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值