设计模式:行为型(Behavioral)

发布时间 2023-04-18 16:11:51作者: 夏末-LateSummer

责任链模式(Chain of Responsibility Pattern)

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它用于将请求的发送者和接收者解耦,从而可以让多个对象都有机会处理请求,形成一条处理请求的责任链。在责任链模式中,每个处理者对象都可以处理请求,如果当前处理者不能处理请求,则将请求传递给下一个处理者,直到有一个处理者能够处理请求或者请求到达链的末端。

责任链模式主要解决的问题是在一个对象链中,解耦请求的发送者和接收者,使得多个对象都有机会处理请求,并且可以动态地改变请求的处理顺序。责任链模式可以避免将请求的处理逻辑硬编码在一个对象中,使得代码更加灵活、可扩展和可维护。

责任链模式的核心组件包括抽象处理者(Handler)、具体处理者(ConcreteHandler)和客户端(Client)三部分。抽象处理者定义了处理请求的接口和责任链的下一个处理者的引用,具体处理者实现了抽象处理者的接口并负责处理请求,客户端创建责任链并将请求发送给第一个处理者。

以下是一个简单的责任链模式的例子,假设有三个处理者分别用于处理低级、中级和高级的请求:

 1 // 抽象处理者
 2 abstract class Handler {
 3     protected Handler nextHandler; // 下一个处理者
 4 
 5     public void setNextHandler(Handler nextHandler) {
 6         this.nextHandler = nextHandler;
 7     }
 8 
 9     public abstract void handleRequest(int level);
10 }
11 
12 // 具体处理者
13 class ConcreteHandler1 extends Handler {
14     @Override
15     public void handleRequest(int level) {
16         if (level <= 10) {
17             System.out.println("ConcreteHandler1处理了请求");
18         } else if (nextHandler != null) {
19             nextHandler.handleRequest(level);
20         }
21     }
22 }
23 
24 class ConcreteHandler2 extends Handler {
25     @Override
26     public void handleRequest(int level) {
27         if (level > 10 && level <= 20) {
28             System.out.println("ConcreteHandler2处理了请求");
29         } else if (nextHandler != null) {
30             nextHandler.handleRequest(level);
31         }
32     }
33 }
34 
35 class ConcreteHandler3 extends Handler {
36     @Override
37     public void handleRequest(int level) {
38         if (level > 20) {
39             System.out.println("ConcreteHandler3处理了请求");
40         } else if (nextHandler != null) {
41             nextHandler.handleRequest(level);
42         }
43     }
44 }
45 
46 // 客户端
47 public class Client {
48     public static void main(String[] args) {
49         Handler handler1 = new ConcreteHandler1();
50         Handler handler2 = new ConcreteHandler2();
51         Handler handler3 = new ConcreteHandler3();
52 
53         handler1.setNextHandler(handler2);
54         handler2.setNextHandler(handler3);
55 
56         // 发送请求
57         handler1.handleRequest(5);
58         handler1.handleRequest(15);
59         handler1.handleRequest(25);
60     }
61 }
View Code

在上面的例子中,三个具体处理者分别处理了不同范围的请求,如果一个处理者无法处理请求,它会将请求传递给下一个处理者,直到有一个处理者能够处理请求或者请求到达责任链的末端。

在这个例子中,ConcreteHandler1处理低级的请求(level <= 10),ConcreteHandler2处理中级的请求(10 < level <= 20),ConcreteHandler3处理高级的请求(level > 20)。客户端通过设置处理者的nextHandler形成了一条责任链,并通过调用handleRequest方法发送请求到责任链的起始处,从而实现了请求的处理。

责任链模式在实际应用中可以用于处理请求的多级处理场景,例如在Web应用中的请求过滤器链、日志记录链、权限验证链等场景中都可以使用责任链模式。它可以帮助将处理逻辑解耦,使得系统更加灵活、可扩展和易于维护。

命令模式(Command Pattern)

命令模式是一种行为型设计模式,用于将请求发送者和请求接收者解耦,将请求封装成一个独立的对象,从而允许请求的发送者在不知道具体请求接收者的情况下,通过调用请求对象来间接地执行请求。

命令模式包含以下角色:

  1. Command(命令):定义了执行请求的接口,通常包含一个execute()方法,用于执行具体的请求。

  2. ConcreteCommand(具体命令):实现了Command接口,负责实现具体的请求逻辑,并持有一个接收者对象,用于执行具体的操作。

  3. Receiver(接收者):负责具体的请求处理逻辑,实现了请求的实际执行。

  4. Invoker(调用者):负责调用命令对象来执行请求,持有命令对象的引用。

  5. Client(客户端):负责创建具体的命令对象并设置其接收者,同时将命令对象传递给调用者。

命令模式的核心思想是将请求封装成一个对象,从而实现请求发送者和请求接收者的解耦,使得请求的发送者只需要与抽象的命令接口进行交互,而不需要了解具体的请求接收者和其处理逻辑。这样可以实现请求的参数化和动态化,提高系统的灵活性和可维护性。

一个简单的命令模式的例子是电视遥控器,遥控器上的按钮相当于请求发送者,遥控器的每个按钮对应一个具体的命令对象,命令对象负责封装具体的操作(例如打开电视、关闭电视、切换频道等)和接收者(电视对象),遥控器持有命令对象的引用并通过调用命令对象的execute()方法来间接地执行具体的操作。这样,遥控器和电视之间解耦,遥控器不需要直接调用电视对象的方法来控制电视的操作,而是通过命令对象来间接地执行。

 1 // Command(命令):定义了执行文本编辑器操作的接口,例如 Command 接口。
 2 public interface Command {
 3     void execute();
 4 }
 5 
 6 // ConcreteCommand(具体命令):实现了 Command 接口,负责具体的文本编辑器操作,例如 CopyCommand、CutCommand、PasteCommand 等。
 7 public class CopyCommand implements Command {
 8     private TextEditor textEditor;
 9 
10     public CopyCommand(TextEditor textEditor) {
11         this.textEditor = textEditor;
12     }
13 
14     @Override
15     public void execute() {
16         textEditor.copy();
17     }
18 }
19 
20 public class CutCommand implements Command {
21     private TextEditor textEditor;
22 
23     public CutCommand(TextEditor textEditor) {
24         this.textEditor = textEditor;
25     }
26 
27     @Override
28     public void execute() {
29         textEditor.cut();
30     }
31 }
32 
33 public class PasteCommand implements Command {
34     private TextEditor textEditor;
35 
36     public PasteCommand(TextEditor textEditor) {
37         this.textEditor = textEditor;
38     }
39 
40     @Override
41     public void execute() {
42         textEditor.paste();
43     }
44 }
45 
46 // Receiver(接收者):负责实际执行文本编辑器操作的类,例如 TextEditor 类。
47 public class TextEditor {
48     public void copy() {
49         System.out.println("执行复制操作");
50     }
51 
52     public void cut() {
53         System.out.println("执行剪切操作");
54     }
55 
56     public void paste() {
57         System.out.println("执行粘贴操作");
58     }
59 }
60 
61 // Invoker(调用者):负责调用命令对象来执行请求的类,例如 TextEditorInvoker 类。
62 public class TextEditorInvoker {
63     private Command command;
64 
65     public void setCommand(Command command) {
66         this.command = command;
67     }
68 
69     public void executeCommand() {
70         command.execute();
71     }
72 }
73 
74 // Client(客户端):负责创建具体的命令对象并设置其接收者,同时将命令对象传递给调用者,例如 Client 类。
75 public class Client {
76     public static void main(String[] args) {
77         // 创建接收者
78         TextEditor textEditor = new TextEditor();
79 
80         // 创建具体命令对象并设置其接收者
81         Command copyCommand = new CopyCommand(textEditor);
82         Command cutCommand = new CutCommand(textEditor);
83         Command pasteCommand = new PasteCommand(textEditor);
84 
85         // 创建调用者并设置命令对象
86         TextEditorInvoker invoker = new TextEditorInvoker();
87         invoker.setCommand(copyCommand);
88         invoker.executeCommand();
89 
90         invoker.setCommand(cutCommand);
91         invoker.executeCommand();
92 
93         invoker.setCommand(pasteCommand);
94         invoker.executeCommand();
95     }
96 }
View Code

迭代器模式(Iterator Pattern)

迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供一种方法来遍历集合对象中的元素,而不需要暴露集合的内部结构。通过使用迭代器模式,可以让客户端在不了解集合内部结构的情况下,遍历集合中的元素。

迭代器模式的主要角色包括:

  1. 抽象迭代器(Iterator):定义了访问和遍历集合中元素的接口,包括 hasNext() 方法判断是否还有下一个元素,和 next() 方法返回下一个元素。

  2. 具体迭代器(Concrete Iterator):实现了抽象迭代器接口,负责实现对具体集合的遍历逻辑。

  3. 抽象集合(Aggregate):定义了集合对象的接口,包括创建迭代器的方法 createIterator()。

  4. 具体集合(Concrete Aggregate):实现了抽象集合接口,负责创建具体迭代器对象,实现对集合的遍历。

迭代器模式的核心思想是将遍历集合的责任封装到迭代器对象中,从而实现了集合和遍历算法的解耦。客户端只需要通过迭代器对象来访问集合中的元素,而不需要关心集合的内部结构。

以下是一个简单的迭代器模式的示例,假设有一个存储了字符串的集合对象,可以使用迭代器模式来遍历并访问这些字符串:

 1 // 抽象迭代器
 2 interface Iterator {
 3     boolean hasNext();
 4     String next();
 5 }
 6 
 7 // 具体迭代器
 8 class StringIterator implements Iterator {
 9     private String[] strings;
10     private int index;
11 
12     public StringIterator(String[] strings) {
13         this.strings = strings;
14         this.index = 0;
15     }
16 
17     @Override
18     public boolean hasNext() {
19         return index < strings.length;
20     }
21 
22     @Override
23     public String next() {
24         if (hasNext()) {
25             return strings[index++];
26         }
27         return null;
28     }
29 }
30 
31 // 抽象集合
32 interface Aggregate {
33     Iterator createIterator();
34 }
35 
36 // 具体集合
37 class StringCollection implements Aggregate {
38     private String[] strings;
39 
40     public StringCollection(String[] strings) {
41         this.strings = strings;
42     }
43 
44     @Override
45     public Iterator createIterator() {
46         return new StringIterator(strings);
47     }
48 }
View Code

 为什么使用迭代器遍历元素?

  1. 封装集合内部结构:使用迭代器模式可以将集合的内部结构封装起来,使客户端无需了解集合的实现细节,只需要通过迭代器对象进行遍历操作。

  2. 统一遍历接口:迭代器模式定义了统一的遍历接口,包括 hasNext() 和 next() 方法,使得客户端在遍历不同类型的集合时可以使用相同的接口,不需要针对不同的集合类型编写不同的遍历逻辑。

  3. 简化客户端代码:使用迭代器模式可以简化客户端的代码,避免了显式的使用索引或者循环来遍历集合,提供了一种更加简洁和直观的方式来访问集合中的元素。

  4. 支持多种遍历方式:迭代器模式可以实现多种不同的遍历方式,例如顺序遍历、逆序遍历、跳跃遍历等,而且可以在运行时动态地切换遍历方式,从而灵活地满足不同的需求。

中介者模式(Mediator Pattern)

中介者模式(Mediator Pattern)是一种行为型设计模式,用于减少多个对象之间的直接依赖关系,通过引入一个中介者对象来协调和管理这些对象之间的通信和交互。中介者模式可以帮助对象之间的解耦,从而降低系统的复杂性。

中介者模式的核心思想是将对象之间的交互逻辑封装到中介者对象中,使得各个对象只需要与中介者对象进行通信,而不需要直接与其他对象通信。这样可以避免对象之间的紧耦合关系,使得系统更加灵活、可扩展和易于维护。

中介者模式通常包含以下几个角色:

  1. 中介者(Mediator):负责协调和管理各个对象之间的通信和交互。通常包含一些公共方法,用于接收和发送消息,并根据消息的内容和类型来决定如何处理。

  2. 同事类(Colleague):包含一些业务逻辑,需要与其他同事类进行通信和交互。各个同事类之间不直接通信,而是通过中介者来进行间接通信。

中介者模式的优点包括:

  1. 减少了对象之间的直接依赖关系,使得系统更加灵活和可扩展。

  2. 将交互逻辑封装到中介者对象中,使得系统的结构更加清晰,易于维护和理解。

  3. 可以集中管理和控制对象之间的通信和交互,提供了一种集中式的方式来处理复杂的交互逻辑。

 1 // 中介者接口
 2 public interface ChatRoomMediator {
 3     void sendMessage(String message, User user);
 4     void addUser(User user);
 5 }
 6 
 7 // 具体中介者
 8 public class ChatRoom implements ChatRoomMediator {
 9     private List<User> users = new ArrayList<>();
10 
11     @Override
12     public void sendMessage(String message, User user) {
13         for (User u : users) {
14             if (u != user) {
15                 u.receiveMessage(message);
16             }
17         }
18     }
19 
20     @Override
21     public void addUser(User user) {
22         users.add(user);
23     }
24 }
25 
26 // 同事类
27 public class User {
28     private String name;
29     private ChatRoomMediator mediator;
30 
31     public User(String name, ChatRoomMediator mediator) {
32         this.name = name;
33         this.mediator = mediator;
34     }
35 
36     public void sendMessage(String message) {
37         System.out.println(name + " sends message: " + message);
38         mediator.sendMessage(message, this);
39     }
40 
41     public void receiveMessage(String message) {
42         System.out.println(name + " receives message: " + message);
43     }
44 }
45 
46 // 客户端使用示例
47 public class Client {
48     public static void main(String[] args) {
49         ChatRoomMediator mediator = new ChatRoom();
50         User user1 = new User("User1", mediator);
51         User user2 = new User("User2", mediator);
52         User user3 = new User("User3", mediator);
53 
54         mediator.addUser(user1);
55         mediator.addUser(user2);
56         mediator.addUser(user3);
57 
58         user1.sendMessage("Hello, everyone!");
59         user2.sendMessage("Hi, User1!");
60     }
61 }
View Code

观察者模式(Observer Pattern)

观察者模式(Observer Pattern)是一种行为型设计模式,用于在对象之间建立一种一对多的依赖关系,当一个对象的状态发生变化时,其依赖的多个对象都会得到通知并自动更新。

观察者模式包含以下几个角色:

  1. Subject(主题):被观察者,它是一个抽象类或接口,定义了被观察者的一些基本方法,如添加、删除和通知观察者等。

  2. ConcreteSubject(具体主题):具体的被观察者实现类,它维护着一组观察者对象,并在状态发生变化时通知观察者。

  3. Observer(观察者):观察者,它是一个抽象类或接口,定义了观察者的一些基本方法,如更新状态等。

  4. ConcreteObserver(具体观察者):具体的观察者实现类,它实现了观察者的更新方法,以便在接收到被观察者通知时进行相应的处理。

观察者模式的核心思想是通过抽象的主题(被观察者)和观察者之间的关联关系,实现了对象之间的松耦合,使得主题和观察者可以独立地演化和扩展,而不会相互影响。当主题的状态发生变化时,会自动通知所有的观察者进行更新,从而实现了对象之间的一对多依赖关系。

 1 import java.util.ArrayList;
 2 import java.util.List;
 3 
 4 // 主题(被观察者)
 5 interface Subject {
 6     void registerObserver(Observer observer); // 注册观察者
 7     void unregisterObserver(Observer observer); // 取消注册观察者
 8     void notifyObservers(String news); // 通知观察者
 9 }
10 
11 // 观察者
12 interface Observer {
13     void update(String news); // 更新方法
14 }
15 
16 // 具体主题(具体被观察者)
17 class NewsPublisher implements Subject {
18     private List<Observer> observers = new ArrayList<>();
19     private String news;
20 
21     @Override
22     public void registerObserver(Observer observer) {
23         observers.add(observer);
24     }
25 
26     @Override
27     public void unregisterObserver(Observer observer) {
28         observers.remove(observer);
29     }
30 
31     @Override
32     public void notifyObservers(String news) {
33         this.news = news;
34         for (Observer observer : observers) {
35             observer.update(news);
36         }
37     }
38 }
39 
40 // 具体观察者
41 class NewsSubscriber implements Observer {
42     private String name;
43 
44     public NewsSubscriber(String name) {
45         this.name = name;
46     }
47 
48     @Override
49     public void update(String news) {
50         System.out.println(name + " 收到了新闻:" + news);
51     }
52 }
53 
54 public class ObserverPatternExample {
55     public static void main(String[] args) {
56         NewsPublisher publisher = new NewsPublisher(); // 创建新闻发布者
57 
58         Observer subscriber1 = new NewsSubscriber("Subscriber 1"); // 创建订阅者1
59         Observer subscriber2 = new NewsSubscriber("Subscriber 2"); // 创建订阅者2
60 
61         publisher.registerObserver(subscriber1); // 注册订阅者1
62         publisher.registerObserver(subscriber2); // 注册订阅者2
63 
64         publisher.notifyObservers("Breaking News: COVID-19 Vaccine Released!"); // 发布新闻
65 
66         publisher.unregisterObserver(subscriber1); // 取消注册订阅者1
67 
68         publisher.notifyObservers("Latest News: Economic Growth Forecast Revised!"); // 发布新闻
69 
70     }
71 }
View Code

 

备忘录模式(Memento Pattern)

状态模式(State Pattern)

策略模式(Strategy Pattern)

模板模式(Template Pattern)

访问者模式(Visitor Pattern)

解释器模式(Interpreter Pattern)