行为型设计模式关注对象之间的通信和责任分配,尤其是如何通过不同的方式使得对象间能够有效协作。这些模式描述了类和对象之间的交互模式,帮助解决在运行时如何灵活地分配责任、简化复杂的行为逻辑,并且增强代码的扩展性和可维护性。
1. 责任链模式 (Chain of Responsibility Pattern)
责任链模式使得多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些处理对象串成一条链,并沿着链传递请求,直到有一个对象处理它为止。
实现方式
定义一个处理请求的抽象类。
每个具体处理者类实现该抽象类,并定义自己的处理逻辑。
处理者对象通过链式传递请求。
Java实现
// 抽象处理者
abstract class Handler {
protected Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handleRequest(String request);
}
// 具体处理者A
class ConcreteHandlerA extends Handler {
public void handleRequest(String request) {
if (request.equals("A")) {
System.out.println("Handler A is handling the request.");
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
// 具体处理者B
class ConcreteHandlerB extends Handler {
public void handleRequest(String request) {
if (request.equals("B")) {
System.out.println("Handler B is handling the request.");
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
public class ChainOfResponsibilityDemo {
public static void main(String[] args) {
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
handlerA.setNextHandler(handlerB);
handlerA.handleRequest("A"); // 输出: Handler A is handling the request.
handlerA.handleRequest("B"); // 输出: Handler B is handling the request.
}
}
每个 Handler 可以根据请求的类型决定是否处理请求,或者将请求传递给下一个处理者。
通过责任链模式,可以灵活地处理复杂的请求流程。
2. 命令模式 (Command Pattern)
命令模式将请求封装成对象,从而使得可以用不同的请求、队列或日志来参数化其他对象。命令模式能够解耦请求的发送者和接收者,使得请求的执行可以在不直接暴露接收者的情况下进行。
实现方式
定义一个命令接口,声明执行请求的方法。
每个具体命令类实现该接口,封装特定的请求。
客户端通过调用命令对象的执行方法来触发操作。
Java实现
// 命令接口
interface Command {
void execute();
}
// 具体命令类
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.turnOn();
}
}
// 接收者类
class Light {
public void turnOn() {
System.out.println("Light is ON");
}
public void turnOff() {
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 CommandDemo {
public static void main(String[] args) {
Light light = new Light();
Command lightOn = new LightOnCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton(); // 输出: Light is ON
}
}
Command 接口封装了请求,LightOnCommand 是一个具体的命令对象,它调用 Light 类的方法。
客户端通过 RemoteControl 发出命令,而不直接与 Light 类打交道。
3. 解释器模式 (Interpreter Pattern)
解释器模式提供了评估语言的方式。该模式主要用于设计一个解释器,用于解释某种语言或表达式的文法。该模式通常用于构建一些复杂的计算机语言解释器、编译器等。
实现方式
定义一个表达式接口,所有的终结符和非终结符都实现这个接口。
每个表达式类代表文法规则的一部分。
Java实现
// 抽象表达式
interface Expression {
boolean interpret(String context);
}
// 终结符表达式
class TerminalExpression implements Expression {
private String data;
public TerminalExpression(String data) {
this.data = data;
}
public boolean interpret(String context) {
return context.contains(data);
}
}
// 非终结符表达式
class OrExpression implements Expression {
private Expression expr1;
private Expression expr2;
public OrExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
public boolean interpret(String context) {
return expr1.interpret(context) || expr2.interpret(context);
}
}
public class InterpreterDemo {
public static void main(String[] args) {
Expression isMale = new TerminalExpression("Male");
Expression isMarried = new TerminalExpression("Married");
Expression isMarriedMale = new OrExpression(isMale, isMarried);
System.out.println("Is Male? " + isMale.interpret("Male")); // 输出: true
System.out.println("Is Married? " + isMarried.interpret("Single")); // 输出: false
System.out.println("Is Married Male? " + isMarriedMale.interpret("Married")); // 输出: true
}
}
TerminalExpression 是终结符,检查字符串是否包含某个词语。
OrExpression 是非终结符,它结合两个表达式,并根据逻辑判断来决定是否满足条件。
4. 迭代器模式 (Iterator Pattern)
迭代器模式提供了一种方法来顺序访问一个集合对象中的元素,而又不暴露该对象的内部表示。它允许你以一致的方式访问不同的数据结构中的元素。
实现方式
定义一个迭代器接口,声明常见的操作方法。
每个集合类都提供一个迭代器来遍历自己的元素。
Java实现
// 迭代器接口
interface Iterator {
boolean hasNext();
Object next();
}
// 集合接口
interface Container {
Iterator getIterator();
}
// 具体集合类
class NameRepository implements Container {
private String[] names = {"John", "Jane", "Joe"};
public Iterator getIterator() {
return new NameIterator();
}
private class NameIterator implements Iterator {
int index;
public boolean hasNext() {
return index < names.length;
}
public Object next() {
if (this.hasNext()) {
return names[index++];
}
return null;
}
}
}
public class IteratorDemo {
public static void main(String[] args) {
NameRepository names = new NameRepository();
Iterator iterator = names.getIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
Iterator 接口定义了遍历方法,NameIterator 是具体的迭代器实现。
NameRepository 是集合类,提供了
getIterator()方法来获取其内部元素的迭代器。
5. 中介者模式 (Mediator Pattern)
中介者模式定义了一个对象来封装一组对象之间的交互,使得这些对象不需要显式地彼此交互,而是通过中介者对象来协调。通过这种方式,可以减少对象之间的依赖关系。
实现方式
定义一个中介者接口,所有的交互都通过它来进行。
具体的中介者类实现该接口,并协调不同的组件对象。
Java实现
// 中介者接口
interface Mediator {
void send(String message, Colleague colleague);
}
// 同事类接口
abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public abstract void receive(String message);
}
// 具体同事类
class ConcreteColleagueA extends Colleague {
public ConcreteColleagueA(Mediator mediator) {
super(mediator);
}
public void receive(String message) {
System.out.println("Colleague A received: " + message);
}
public void send(String message) {
mediator.send(message, this);
}
}
class ConcreteColleagueB extends Colleague {
public ConcreteColleagueB(Mediator mediator) {
super(mediator);
}
public void receive(String message) {
System.out.println("Colleague B received: " + message);
}
// 具体中介者类
class ConcreteMediator implements Mediator {
private ConcreteColleagueA colleagueA;
private ConcreteColleagueB colleagueB;
public void setColleagueA(ConcreteColleagueA colleagueA) {
this.colleagueA = colleagueA;
}
public void setColleagueB(ConcreteColleagueB colleagueB) {
this.colleagueB = colleagueB;
}
public void send(String message, Colleague colleague) {
if (colleague == colleagueA) {
colleagueB.receive(message);
} else if (colleague == colleagueB) {
colleagueA.receive(message);
}
}
}
public class MediatorDemo {
public static void main(String[] args) {
ConcreteMediator mediator = new ConcreteMediator();
ConcreteColleagueA colleagueA = new ConcreteColleagueA(mediator);
ConcreteColleagueB colleagueB = new ConcreteColleagueB(mediator);
mediator.setColleagueA(colleagueA);
mediator.setColleagueB(colleagueB);
colleagueA.send("Hello, B!"); // 输出: Colleague B received: Hello, B!
colleagueB.send("Hello, A!"); // 输出: Colleague A received: Hello, A!
}
}Mediator 接口定义了协调不同同事之间的交互的方法。
ConcreteMediator 负责管理和协调 ConcreteColleagueA 和 ConcreteColleagueB 之间的通信。
ConcreteColleagueA 和 ConcreteColleagueB 通过中介者发送和接收消息,避免了它们之间的直接依赖。
6. 备忘录模式 (Memento Pattern)
备忘录模式用于保存和恢复对象的状态。它能够在不暴露对象实现的情况下,记录对象的状态,并在需要时恢复该状态。
实现方式
定义一个备忘录类,负责存储对象的状态。
定义一个发起人类,保存和恢复自身的状态。
定义一个管理者类,负责备份和恢复发起人的状态。
Java实现
// 备忘录类
class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
// 发起人类
class Originator {
private String state;
public void setState(String state) {
System.out.println("Setting state to: " + state);
this.state = state;
}
public String getState() {
return state;
}
public Memento saveStateToMemento() {
return new Memento(state);
}
public void getStateFromMemento(Memento memento) {
state = memento.getState();
System.out.println("State after restoring: " + state);
}
}
// 管理者类
class Caretaker {
private List<Memento> mementoList = new ArrayList<>();
public void add(Memento memento) {
mementoList.add(memento);
}
public Memento get(int index) {
return mementoList.get(index);
}
}
public class MementoDemo {
public static void main(String[] args) {
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
originator.setState("State1");
caretaker.add(originator.saveStateToMemento());
originator.setState("State2");
caretaker.add(originator.saveStateToMemento());
originator.setState("State3");
System.out.println("Current State: " + originator.getState()); // 输出: Current State: State3
originator.getStateFromMemento(caretaker.get(0));
System.out.println("First saved State: " + originator.getState()); // 输出: First saved State: State1
}
}
Memento 类用于保存对象的状态。
Originator 类设置和获取对象的状态,并能够保存和恢复状态。
Caretaker 类负责管理多个备忘录,以便在需要时恢复状态。
7. 观察者模式 (Observer Pattern)
观察者模式定义了对象间一对多的依赖关系。多个观察者对象监听一个主题对象,当主题对象的状态发生变化时,它会通知所有的观察者对象。
实现方式
定义一个主题接口,声明添加、删除和通知观察者的方法。
观察者接口定义了响应更新的方法。
主题类维护观察者的列表,并在状态变化时通知它们。
Java实现
// 观察者接口
interface Observer {
void update(String message);
}
// 主题接口
interface Subject {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 具体观察者类
class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
public void update(String message) {
System.out.println(name + " received message: " + message);
}
}
// 具体主题类
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private String state;
public void setState(String state) {
this.state = state;
notifyObservers();
}
public String getState() {
return state;
}
public void addObserver(Observer observer) {
observers.add(observer);
}
public void removeObserver(Observer observer) {
observers.remove(observer);
}
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(state);
}
}
}
public class ObserverDemo {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
Observer observer1 = new ConcreteObserver("Observer 1");
Observer observer2 = new ConcreteObserver("Observer 2");
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.setState("State 1");
subject.setState("State 2");
}
}
ConcreteSubject 类存储主题的状态并通知所有观察者。
ConcreteObserver 类根据主题状态的变化作出反应。
8. 状态模式 (State Pattern)
状态模式允许一个对象在其内部状态发生改变时改变其行为。对象在某个状态下的行为与在其他状态下的行为不同,状态模式允许对象的状态变化成为一种可管理的过程。
实现方式
定义一个状态接口,声明不同状态下的行为。
为每个具体状态创建一个类,并实现状态接口。
上下文类持有当前状态,并根据状态变化执行不同的行为。
Java实现
// 状态接口
interface State {
void handle();
}
// 具体状态类A
class ConcreteStateA implements State {
public void handle() {
System.out.println("Handling request in State A.");
}
}
// 具体状态类B
class ConcreteStateB implements State {
public void handle() {
System.out.println("Handling request in State B.");
}
}
// 上下文类
class Context {
private State state;
public Context(State state) {
this.state = state;
}
public void setState(State state) {
this.state = state;
}
public void request() {
state.handle();
}
}
public class StateDemo {
public static void main(String[] args) {
Context context = new Context(new ConcreteStateA());
context.request(); // 输出: Handling request in State A.
context.setState(new ConcreteStateB());
context.request(); // 输出: Handling request in State B.
}
}
Context 类持有当前的状态,并调用状态对象来处理请求。
ConcreteStateA 和 ConcreteStateB 定义了不同的状态行为。
9. 策略模式 (Strategy Pattern)
策略模式将一系列算法封装起来,使它们可以互相替换。策略模式让算法可以独立于使用它的客户端而变化。
实现方式
定义一个策略接口,封装不同算法的执行方法。
具体策略实现类定义不同的算法逻辑。
上下文类持有策略接口的引用,通过设置不同策略来实现不同算法的切换。
Java实现
// 策略接口
interface Strategy {
int execute(int a, int b);
}
// 具体策略类:加法
class AddStrategy implements Strategy {
public int execute(int a, int b) {
return a + b;
}
}
// 具体策略类:减法
class SubtractStrategy implements Strategy {
public int execute(int a, int b) {
return a - b;
}
}
// 具体策略类:乘法
class MultiplyStrategy implements Strategy {
public int execute(int a, int b) {
return a * b;
}
}
// 上下文类
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int a, int b) {
return strategy.execute(a, b);
}
}
public class StrategyDemo {
public static void main(String[] args) {
Context context = new Context(new AddStrategy());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context.setStrategy(new SubtractStrategy());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
context.setStrategy(new MultiplyStrategy());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
不同的策略类实现了不同的算法操作。
上下文类通过切换策略对象,实现算法运行方式的动态改变。
10. 模板方法模式 (Template Method Pattern)
模板方法模式定义算法的骨架,并允许子类在不改变结构的情况下重定义其中的某些步骤。非常适合需要统一流程但部分步骤不同的场景。
实现方式
抽象类定义算法骨架(模板方法)和部分抽象步骤。
子类继承并实现具体步骤。
Java实现
// 抽象类:模板
abstract class Game {
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
// 模板方法
public final void play() {
initialize();
startPlay();
endPlay();
}
}
// 具体子类
class Football extends Game {
void initialize() {
System.out.println("Football Game Initialized!");
}
void startPlay() {
System.out.println("Football Game Started!");
}
void endPlay() {
System.out.println("Football Game Finished!");
}
}
public class TemplateDemo {
public static void main(String[] args) {
Game game = new Football();
game.play();
}
}
play() 是固定的流程框架,而具体步骤由子类决定。
11. 访问者模式 (Visitor Pattern)
访问者模式将数据结构与对结构的操作分离,使得在不改变类结构的情况下增加新的操作变得容易。
实现方式
定义访问者接口,声明 visit 方法。
对象结构类接受访问者对象,并调用访问者方法。
Java实现
// 元素接口
interface Element {
void accept(Visitor visitor);
}
// 访问者接口
interface Visitor {
void visit(Book book);
void visit(Computer computer);
}
// 具体元素
class Book implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
class Computer implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
// 具体访问者
class DisplayVisitor implements Visitor {
public void visit(Book book) {
System.out.println("Displaying a Book");
}
public void visit(Computer computer) {
System.out.println("Displaying a Computer");
}
}
public class VisitorDemo {
public static void main(String[] args) {
Element[] elements = {new Book(), new Computer()};
Visitor visitor = new DisplayVisitor();
for (Element element : elements) {
element.accept(visitor);
}
}
}
新增访问操作,只需要扩展访问者,而无需修改原来元素对象结构。