当前位置: 首页 > article >正文

设计模式学习(三)

行为模式

职责链模式(Chain of Responsibility Pattern)

定义

它允许多个对象有机会处理请求,从而避免请求的发送者与接收者之间的耦合。职责链模式将这些对象连成一条链,并沿着这条链传递请求,直到有对象处理它为止。

职责链模式的角色
  • 处理器接口(Handler):定义处理请求的接口,通常包含一个方法用于处理请求和一个方法用于设置下一个处理器。
  • 具体处理器(Concrete Handler):实现处理器接口,负责处理请求。如果自己不能处理,则将请求传递给下一个处理器。
  • 客户端(Client):创建职责链,并向链上的第一个处理器提交请求。

假设我们有一个审批流程,需要多个级别的审批人(如经理、总监、CEO)来处理请求。我们可以使用职责链模式来实现这个流程。

// 处理器接口:审批人
interface Approver {
    void setNextApprover(Approver nextApprover);
    void processRequest(PurchaseRequest request);
}
// 具体处理器:经理
class Manager implements Approver {
    private Approver nextApprover;

    @Override
    public void setNextApprover(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }

    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getAmount() <= 1000) {
            System.out.println("Manager approves the request for $" + request.getAmount());
        } else if (nextApprover != null) {
            nextApprover.processRequest(request);
        }
    }
}

// 具体处理器:总监
class Director implements Approver {
    private Approver nextApprover;

    @Override
    public void setNextApprover(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }

    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getAmount() <= 5000) {
            System.out.println("Director approves the request for $" + request.getAmount());
        } else if (nextApprover != null) {
            nextApprover.processRequest(request);
        }
    }
}

// 具体处理器:CEO
class CEO implements Approver {
    @Override
    public void setNextApprover(Approver nextApprover) {
        // CEO 是最后一个审批人,没有下一个审批人
    }

    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getAmount() <= 10000) {
            System.out.println("CEO approves the request for $" + request.getAmount());
        } else {
            System.out.println("Request for $" + request.getAmount() + " requires a board meeting.");
        }
    }
}
// 请求类:采购请求
class PurchaseRequest {
    private double amount;

    public PurchaseRequest(double amount) {
        this.amount = amount;
    }

    public double getAmount() {
        return amount;
    }
}
public class ChainOfResponsibilityPatternDemo {
    public static void main(String[] args) {
        // 创建审批人
        Approver manager = new Manager();
        Approver director = new Director();
        Approver ceo = new CEO();

        // 设置职责链
        manager.setNextApprover(director);
        director.setNextApprover(ceo);

        // 创建采购请求
        PurchaseRequest request1 = new PurchaseRequest(800);
        PurchaseRequest request2 = new PurchaseRequest(4500);
        PurchaseRequest request3 = new PurchaseRequest(12000);

        // 处理请求
        manager.processRequest(request1);
        manager.processRequest(request2);
        manager.processRequest(request3);
    }
}
jdk或者android系统上的应用
  • Java 异常处理

Java 的异常处理机制是职责链模式的一个典型应用。当一个异常被抛出时,它会沿着调用栈向上传递,直到找到能够处理该异常的 catch 块。

try {
    // 可能会抛出异常的代码
} catch (NullPointerException e) {
    System.out.println("Caught NullPointerException");
} catch (Exception e) {
    System.out.println("Caught Exception");
}
  • Android事件分发机制

Android 的事件分发机制是职责链模式的一个典型应用。当用户触摸屏幕时,触摸事件会从 Activity 传递到 ViewGroup,再传递到具体的 View,直到有 View 处理该事件。

@Override
public boolean onTouchEvent(MotionEvent event) {
    // 处理触摸事件
    return super.onTouchEvent(event);
}

命令模式(Command Pattern)

定义

它将请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,并支持请求的排队、记录日志、撤销等操作。命令模式的核心思想是将“请求”抽象为一个独立的对象,从而解耦请求的发送者和接收者。

命令模式的角色
  • 命令接口(Command):定义执行操作的接口。
  • 具体命令(Concrete Command):实现命令接口,封装具体的操作。
  • 接收者(Receiver):执行具体操作的对象。
  • 调用者(Invoker):持有命令对象,并调用命令的执行方法。
  • 客户端(Client):创建命令对象并设置其接收者。

假设我们有一个遥控器,可以控制多种家电(如灯、风扇等)。我们可以使用命令模式来实现遥控器的功能。

// 命令接口
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 LightOffCommand implements Command {
    private Light light;

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

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

// 具体命令:开风扇
class FanOnCommand implements Command {
    private Fan fan;

    public FanOnCommand(Fan fan) {
        this.fan = fan;
    }

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

// 具体命令:关风扇
class FanOffCommand implements Command {
    private Fan fan;

    public FanOffCommand(Fan fan) {
        this.fan = fan;
    }

    @Override
    public void execute() {
        fan.off();
    }
}
// 接收者:灯
class Light {
    public void on() {
        System.out.println("Light is on");
    }

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

// 接收者:风扇
class Fan {
    public void on() {
        System.out.println("Fan is on");
    }

    public void off() {
        System.out.println("Fan 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();
        Fan fan = new Fan();

        // 创建具体命令
        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);
        Command fanOn = new FanOnCommand(fan);
        Command fanOff = new FanOffCommand(fan);

        // 创建调用者
        RemoteControl remote = new RemoteControl();

        // 控制灯
        remote.setCommand(lightOn);
        remote.pressButton(); // 输出: Light is on

        remote.setCommand(lightOff);
        remote.pressButton(); // 输出: Light is off

        // 控制风扇
        remote.setCommand(fanOn);
        remote.pressButton(); // 输出: Fan is on

        remote.setCommand(fanOff);
        remote.pressButton(); // 输出: Fan is off
    }
}
jdk或者android系统上的应用
  • Runnable 接口

Java 的 Runnable 接口是命令模式的一个典型应用。Runnable 封装了一个任务,而 Thread 是调用者,负责执行任务。

// 命令接口
Runnable task = new Runnable() {
    @Override
    public void run() {
        System.out.println("Task is running");
    }
};

// 调用者
Thread thread = new Thread(task);
thread.start();
  • Handler 和 Message

在 Android 中,Handler 和 Message 是命令模式的一个典型应用。Message 封装了一个任务,而 Handler 是调用者,负责处理任务。

// 命令接口
Message message = Message.obtain(handler, new Runnable() {
    @Override
    public void run() {
        System.out.println("Message is handled");
    }
});

// 调用者
Handler handler = new Handler(Looper.getMainLooper());
handler.sendMessage(message);

解释器模式(Interpreter Pattern)

定义

它定义了一种语言的语法表示,并使用解释器来解释语言中的句子。这种模式通常用于需要解释和执行特定语法规则的场景,例如编译器、正则表达式引擎等。

解释器模式的角色
  • 抽象表达式(AbstractExpression):定义解释操作的接口。
  • 终结符表达式(TerminalExpression):实现与文法中的终结符相关的解释操作。
  • 非终结符表达式(NonterminalExpression):实现与文法中的非终结符相关的解释操作。
  • 上下文(Context):包含解释器需要的全局信息。
  • 客户端(Client):构建抽象语法树并调用解释操作。

假设我们需要解释简单的数学表达式,例如 1 + 2 - 3。我们可以使用解释器模式来实现这个功能。

//定义抽象接口
interface Expression {
    int interpret(Context context);
}
//定义终结符表达式
class NumberExpression implements Expression {
    private int number;

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

    @Override
    public int interpret(Context context) {
        return number;
    }
}
//定义非终结符表达式
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 SubtractExpression implements Expression {
    private Expression left;
    private Expression right;

    public SubtractExpression(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 {
    // 这里可以包含解释器需要的全局信息
}
public class InterpreterPatternDemo {
    public static void main(String[] args) {
        Context context = new Context();

        // 构建表达式:1 + 2 - 3
        Expression expression = new SubtractExpression(
            new AddExpression(new NumberExpression(1), new NumberExpression(2)),
            new NumberExpression(3)
        );

        // 解释并输出结果
        int result = expression.interpret(context);
        System.out.println("Result: " + result);  // 输出: Result: 0
    }
}
jdk或者android系统上的应用

迭代器模式(Iterator Pattern)

定义

它提供了一种顺序访问聚合对象(如列表、集合等)中元素的方法,而不需要暴露其底层表示。迭代器模式将遍历逻辑从聚合对象中分离出来,使得聚合对象和遍历逻辑可以独立变化。

迭代器模式的角色
  • 迭代器接口(Iterator):定义遍历和访问元素的方法。
  • 具体迭代器(ConcreteIterator):实现迭代器接口,负责管理当前遍历的位置。
  • 聚合接口(Aggregate):定义创建迭代器的方法。
  • 具体聚合类(ConcreteAggregate):实现聚合接口,返回一个具体迭代器的实例。

假设我们有一个自定义的集合类 MyCollection,它存储了一组整数。我们希望提供一个迭代器来遍历这个集合中的元素。

  1. 定义迭代器接口
interface Iterator<T> {
    boolean hasNext();  // 检查是否还有下一个元素
    T next();           // 返回下一个元素
}
  1. 定义具体迭代器
class MyCollectionIterator implements Iterator<Integer> {
    private int[] collection;
    private int position = 0;

    public MyCollectionIterator(int[] collection) {
        this.collection = collection;
    }

    @Override
    public boolean hasNext() {
        return position < collection.length;
    }

    @Override
    public Integer next() {
        if (this.hasNext()) {
            return collection[position++];
        }
        throw new IndexOutOfBoundsException("No more elements");
    }
}
  1. 定义聚合接口
interface Aggregate<T> {
    Iterator<T> createIterator();  // 创建迭代器
}
  1. 定义具体聚合类
class MyCollection implements Aggregate<Integer> {
    private int[] items;

    public MyCollection(int[] items) {
        this.items = items;
    }

    @Override
    public Iterator<Integer> createIterator() {
        return new MyCollectionIterator(items);
    }
}
public class IteratorPatternDemo {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5};
        MyCollection collection = new MyCollection(numbers);

        // 获取迭代器
        Iterator<Integer> iterator = collection.createIterator();

        // 遍历集合
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}
迭代器模式的优缺点

优点:

  • 将遍历逻辑与聚合对象分离,符合单一职责原则。
  • 提供了一种统一的方式来遍历不同类型的聚合对象。
  • 支持多种遍历方式(例如正向遍历、反向遍历)。

缺点:

  • 对于简单的集合,使用迭代器可能会增加代码的复杂性。
  • 如果集合的结构发生变化,可能需要修改迭代器的实现。
jdk或者android系统上的应用

Java 的集合框架(如 List、Set、Map)已经内置了迭代器模式。

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

public class JavaIteratorExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Cherry");

        // 使用 Java 内置的迭代器
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

中介者模式(Mediator Pattern)

定义

它通过引入一个中介者对象来封装一组对象之间的交互。中介者模式减少了对象之间的直接依赖,使得对象之间的耦合度降低,从而更容易维护和扩展。

迭代器模式的角色
  • 中介者接口(Mediator):定义对象之间通信的接口。
  • 具体中介者(ConcreteMediator):实现中介者接口,协调各个对象之间的交互。
  • 同事类(Colleague):定义各个对象的接口,每个同事类都知道中介者对象。
  • 具体同事类(ConcreteColleague):实现同事类接口,负责与其他同事类通信。

假设我们有一个聊天室系统,多个用户可以通过聊天室发送消息。聊天室作为中介者,负责将消息从一个用户传递给其他用户。

  1. 定义中介者接口
interface ChatMediator {
    void sendMessage(String message, User user);  // 发送消息
    void addUser(User user);                      // 添加用户
}
  1. 定义具体中介者
class ChatRoom implements ChatMediator {
    private List<User> users;

    public ChatRoom() {
        this.users = new ArrayList<>();
    }

    @Override
    public void sendMessage(String message, User user) {
        for (User u : users) {
            // 不将消息发送给自己
            if (u != user) {
                u.receive(message);
            }
        }
    }

    @Override
    public void addUser(User user) {
        this.users.add(user);
    }
}
  1. 定义同事类
abstract class User {
    protected ChatMediator mediator;
    protected String name;

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

    public abstract void send(String message);  // 发送消息
    public abstract void receive(String message);  // 接收消息
}
  1. 定义具体同事类
class ChatUser extends User {
    public ChatUser(ChatMediator mediator, String name) {
        super(mediator, name);
    }

    @Override
    public void send(String message) {
        System.out.println(this.name + " 发送消息: " + message);
        mediator.sendMessage(message, this);
    }

    @Override
    public void receive(String message) {
        System.out.println(this.name + " 收到消息: " + message);
    }
}
  1. 客户端代码
public class MediatorPatternDemo {
    public static void main(String[] args) {
        // 创建中介者(聊天室)
        ChatMediator chatRoom = new ChatRoom();

        // 创建用户
        User user1 = new ChatUser(chatRoom, "Hehe");
        User user2 = new ChatUser(chatRoom, "Bob");
        User user3 = new ChatUser(chatRoom, "Charlie");

        // 将用户添加到聊天室
        chatRoom.addUser(user1);
        chatRoom.addUser(user2);
        chatRoom.addUser(user3);

        // 用户发送消息
        user1.send("大家好!");
        user2.send("你好,Hehe!");
        user3.send("欢迎来到聊天室!");
    }
}

备忘录模式(Memento Design Pattern)

定义

它允许在不暴露对象实现细节的情况下保存和恢复对象的状态。该模式主要用于实现撤销(undo)操作。

备忘录模式的角色
  • 发起人(Originator):创建并恢复备忘录的对象。
  • 备忘录(Memento):存储发起人内部状态的快照,并防止其他对象访问备忘录。备忘录通常只有发起人可以访问其内容。
  • 负责人(Caretaker):负责管理备忘录,但不能查看或修改备忘录的内容。

使用备忘录模式来实现一个文本编辑器的撤销功能。

  1. 发起人(Originator)
public class TextEditor {
    private String content;

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

    public void type(String words) {
        content += words;
    }

    // 创建备忘录
    public Memento saveStateToMemento() {
        return new Memento(content);
    }

    // 从备忘录恢复状态
    public void getStateFromMemento(Memento memento) {
        this.content = memento.getContent();
    }

    public String getContent() {
        return content;
    }
}
  1. 备忘录(Memento)
public class Memento {
    private String content;

    // 私有构造函数,防止外部实例化
    private Memento(String content) {
        this.content = content;
    }

    public Memento(TextEditor originator) {
        this.content = originator.getContent();
    }

    public String getContent() {
        return content;
    }
}
  1. 负责人(Caretaker)
import java.util.ArrayList;
import java.util.List;

public class Caretaker {
    private List<Memento> mementoList = new ArrayList<>();

    public void add(Memento state) {
        mementoList.add(state);
    }

    public Memento get(int index) {
        return mementoList.get(index);
    }
}
public class Client {
    public static void main(String[] args) {
        TextEditor editor = new TextEditor("Hello");
        Caretaker caretaker = new Caretaker();

        editor.type(" world");
        caretaker.add(editor.saveStateToMemento());

        editor.type("!!!");
        System.out.println("Current Content: " + editor.getContent()); // Hello world!!!

        // 撤销到上一个状态
        editor.getStateFromMemento(caretaker.get(0));
        System.out.println("After Undo: " + editor.getContent()); // Hello world
    }
}

http://www.kler.cn/a/533435.html

相关文章:

  • solidity高阶 -- 调用接口合约
  • 【ArcGIS_Python】使用arcpy脚本将shape数据转换为三维白膜数据
  • 利用Muduo库实现简单且健壮的Echo服务器
  • 014-STM32单片机实现矩阵薄膜键盘设计
  • 怀旧经典:1200+款红白机游戏合集,Windows版一键畅玩
  • 【实践案例】基于大语言模型的海龟汤游戏
  • Unity扩展编辑器使用整理(一)
  • Vue Router如何配置404页面
  • Ansible在多台服务器上运行python脚本
  • PostgreSQL rownum实现方法
  • Spark--算子执行原理
  • 莱佛士设计之旅:四城巡讲,启发未来设计之路
  • spring security与gateway结合进行网关鉴权和授权
  • GAN(生成对抗网络,Generative Adversarial Network)
  • 【Java】MyBatis动态SQL
  • PostgreSQL / PostGIS:创建地理要素
  • 网络安全--边界安全
  • AI赋能生态学暨“ChatGPT+”多技术融合在生态系统服务中的实践技术应用与论文撰写
  • ArrayList和Araay数组区别
  • AI安全最佳实践:AI云原生开发安全评估矩阵(上)
  • Vue模板语法与常用指令深度解析
  • 【算法】【二分】acwing 算法基础 789. 数的范围
  • 力扣1022. 从根到叶的二进制数之和(二叉树的遍历思想解决)
  • 485网关数据收发测试
  • 防火墙安全策略作业
  • if let 与 let else 的使用指南