设计模式(三)

行为型模式:责任链/命令/迭代器/中介/备忘录/观察者/访问者/策略/状态/模板

观察者模式

定义对象间一种一对多的依赖关系,使得每当一个对象发生改变时,所有依赖于
他的对象都会得到通知并被自动更新

使用场景

  1. 关联行为场景(关联行为可拆分,不是组合关系)
  2. 事件多级触发场景
  3. 跨系统的消息交换场景(如消息队列、事件总线的处理机制)

观察者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//实现Observer接口
class Coder implements Observer {
private String name;
public Coder(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
System.out.println("用户名:" + name + ",发布内容" + arg);
}
}

被观察的角色

1
2
3
4
5
6
7
8
9
10
//继承Observable类
class Poster extends Observable {
public void post(String content) {
// 标识状态或者内容发生改变
setChanged();
// 通知所有观察者
notifyObservers(content);
}
}

具体main方法

1
2
3
4
5
6
7
8
9
10
// 被观察角色
Poster poster = new Poster();
// 观察者
Coder bob = new Coder("Bob");
Coder jack = new Coder("Jack");
// 注册观察者列表
poster.addObserver(bob);
poster.addObserver(jack);
// 发布消息
poster.post("发布新的内容了!");

责任链模式

使多个对象都有机会处理请求,从而避免了请求的发送者和和接收者之间的耦合关系
将这些对象连成一条链,并沿着这条链传递请求,直到有对象处理他为止

使用场景

  1. 多个对象可以处理同一个请求,但具体哪个对象则在处理中动态决定
  2. 在请求处理者不明确的情况下向多个对象中的一个提交一个请求
  3. 需要动态指定一组对象处理请求

抽象处理者

1
2
3
4
5
6
public abstract class Handler {
// 下一结点的处理者
protected Handler successor;
// 请求处理
public abstract void handleRequest(String condition);
}

具体处理者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//具体处理者1
class ConcreteHandler1 extends Handler {
@Override
public void handleRequest(String condition) {
if(condition.equals("ConcreteHandler1")) {
System.out.println("ConcreteHandler1 Handled");
return;
}else{
//交付下一结点的处理者
successor.handleRequest(condition);
}
}
}
//具体处理者2
class ConcreteHandler2 extends Handler {
@Override
public void handleRequest(String condition) {
if(condition.equals("ConcreteHandler2")) {
System.out.println("ConcreteHandler2 Handled");
return;
}else{
//交付下一结点的处理者
successor.handleRequest(condition);
}
}
}

具体main方法

1
2
3
4
5
6
ConcreteHandler1 handler1 = new ConcreteHandler1();
ConcreteHandler2 handler2 = new ConcreteHandler2();
//handler1的下一结点
handler1.successor = handler2;
//处理请求
handler1.handleRequest("ConcreteHandler2");

命令模式

将一个请求封装成一个对象,从而让用户使用不同的请求把客户端参数化
对请求排队或者记录请求日志,以及支持可撤销的操作

使用场景

  1. 需要抽象出待执行的操作,然后以参数的形式提供出来
  2. 在不同的时刻指定、排序和执行请求
  3. 需要执行取消操作、支持修改日志功能、需要支持事务操作

抽象命令接口

1
2
3
4
public interface Command {
//具体执行操作的命令
void execute();
}

接收者类

1
2
3
4
5
6
class Receiver {
//真正执行具体逻辑命令的方法
public void action() {
System.out.println("执行具体操作");
}
}

具体命令类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ConcreteCommand implements Command {
//持有一个对接收者对象的引用
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
//调用接收者相关方法来执行具体逻辑
receiver.action();
}
}

请求者类

1
2
3
4
5
6
7
8
9
10
11
12
class Invoker {
//持有一个对命令对象的引用
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void action() {
//调用具体命令对象的相关方法,执行具体指令
command.execute();
}
}

具体main方法

1
2
3
4
Receiver receiver = new Receiver();
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker(command);
invoker.action();