行为型设计模式主要关注对象之间的职责分配,即它们如何交互以及如何分配职责。这类模式不仅描述了如何在对象之间划分责任,还涉及算法的封装和实现。以下是几种常见的行为型设计模式及其简要说明:
1. 观察者模式(Observer Pattern)
- 目的:定义一种一对多的依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。
- 应用场景:事件处理系统、订阅发布机制。
示例:
import java.util.ArrayList;
import java.util.List;
// 主题接口
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 具体主题
class WeatherData implements Subject {
private List<Observer> observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList<>();
}
@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(temperature, humidity, pressure);
}
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
public void measurementsChanged() {
notifyObservers();
}
}
// 观察者接口
interface Observer {
void update(float temperature, float humidity, float pressure);
}
// 具体观察者
class CurrentConditionsDisplay implements Observer {
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
public void display() {
System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
}
}
2. 策略模式(Strategy Pattern)
- 目的:定义一系列算法,并将每一个算法封装起来,使它们可以相互替换(继承与实现接口)。策略模式让算法独立于使用它的客户端而变化。
- 应用场景:支付方式选择、排序算法的选择等。
示例:
// 策略接口
interface Strategy {
int doOperation(int num1, int num2);
}
// 具体策略
class OperationAdd implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
class OperationSubtract implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
// 上下文类
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2) {
return strategy.doOperation(num1, num2);
}
}
3. 模板方法模式(Template Method Pattern)
- 目的:定义一个操作中的算法骨架,而将一些步骤延迟到子类中去实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
- 应用场景:框架开发、通用功能定制。
示例:
// 抽象类
abstract class Game {
protected abstract void initialize();
protected abstract void startPlay();
protected abstract void endPlay();
// 模板方法
public final void play() {
// 初始化游戏
initialize();
// 开始游戏
startPlay();
// 结束游戏
endPlay();
}
}
// 具体类
class Cricket extends Game {
@Override
protected void initialize() {
System.out.println("Cricket Game Initialized! Start playing.");
}
@Override
protected void startPlay() {
System.out.println("Cricket Game Started. Enjoy the game!");
}
@Override
protected void endPlay() {
System.out.println("Cricket Game Finished!");
}
}
public class Main {
public static void main(String[] args) {
Game game = new Cricket();
game.play();
}
}
4. 命令模式(Command Pattern)
- 目的:将请求封装为对象,从而使用户可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
- 应用场景:GUI命令触发、事务处理。
示例:
// 命令接口
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 Light {
public void on() {
System.out.println("Light is ON");
}
public void off() {
System.out.println("Light is OFF");
}
}
// 调用者类
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
5. 迭代器模式(Iterator Pattern)
- 目的:提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露其内部表示。
- 应用场景:遍历集合、列表等数据结构。
示例:
import java.util.ArrayList;
import java.util.List;
// 聚合接口
interface Container {
Iterator getIterator();
}
// 具体聚合
class NameRepository implements Container {
private List<String> names = new ArrayList<>();
public NameRepository() {
names.add("Robert");
names.add("John");
names.add("Julie");
names.add("Lora");
}
@Override
public Iterator getIterator() {
return new NameIterator();
}
private class NameIterator implements Iterator {
private int index;
@Override
public boolean hasNext() {
if (index < names.size()) {
return true;
}
return false;
}
@Override
public Object next() {
if (this.hasNext()) {
return names.get(index++);
}
return null;
}
}
}
// 迭代器接口
interface Iterator {
boolean hasNext();
Object next();
}
6. 责任链模式(Chain of Responsibility Pattern)
- 目的:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
- 应用场景:审批流程、过滤器链。
示例:
// 抽象处理者
abstract class AbstractLogger {
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;
protected int level;
// 责任链中的下一个元素
protected AbstractLogger nextLogger;
public void setNextLogger(AbstractLogger nextLogger) {
this.nextLogger = nextLogger;
}
public void logMessage(int level, String message) {
if (this.level <= level) {
write(message);
}
if (nextLogger != null) {
nextLogger.logMessage(level, message);
}
}
abstract protected void write(String message);
}
// 具体处理者
class ConsoleLogger extends AbstractLogger {
public ConsoleLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Standard Console::Logger: " + message);
}
}
class ErrorLogger extends AbstractLogger {
public ErrorLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Error Console::Logger: " + message);
}
}
public class ChainPatternDemo {
private static AbstractLogger getChainOfLoggers() {
AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
AbstractLogger fileLogger = new ConsoleLogger(AbstractLogger.DEBUG);
AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);
errorLogger.setNextLogger(fileLogger);
fileLogger.setNextLogger(consoleLogger);
return errorLogger;
}
public static void main(String[] args) {
AbstractLogger loggerChain = getChainOfLoggers();
loggerChain.logMessage(AbstractLogger.INFO, "This is an information.");
loggerChain.logMessage(AbstractLogger.DEBUG, "This is a debug level information.");
loggerChain.logMessage(AbstractLogger.ERROR, "This is an error information.");
}
}
7. 备忘录模式(Memento Pattern)
- 目的:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后恢复到原先保存的状态。
- 应用场景:撤销操作、历史回退。
示例:
// Originator 类包含一些重要状态,并创建了一个 Memento 对象存储这些状态。
class Originator {
private String state;
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
// 保存当前状态到备忘录中
public Memento saveStateToMemento() {
return new Memento(state);
}
// 从备忘录中恢复状态
public void getStateFromMemento(Memento memento) {
state = memento.getState();
}
}
// Memento 类存储了 Originator 的内部状态。
class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
// CareTaker 类负责保持备忘录 Memento。
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);
}
}
8. 状态模式(State Pattern)
- 目的:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
- 应用场景:游戏状态管理、工作流引擎。
示例:
// 状态接口
interface State {
void doAction(Context context);
}
// 具体状态A
class StartState implements State {
@Override
public void doAction(Context context) {
System.out.println("Player is in start state");
context.setState(this);
}
@Override
public String toString() {
return "Start State";
}
}
// 具体状态B
class StopState implements State {
@Override
public void doAction(Context context) {
System.out.println("Player is in stop state");
context.setState(this);
}
@Override
public String toString() {
return "Stop State";
}
}
// 上下文类
class Context {
private State state;
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
}
9. 访问者模式(Visitor Pattern)
- 目的:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。
- 应用场景:编译器解析表达式树、XML文档解析。
示例:
// Element 接口声明了一个 `accept` 方法,它接收一个访问者对象作为参数。
interface ComputerPart {
void accept(ComputerPartVisitor computerPartVisitor);
}
// 具体的元素类
class Keyboard implements ComputerPart {
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
class Monitor implements ComputerPart {
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
// 访问者接口
interface ComputerPartVisitor {
void visit(Keyboard keyboard);
void visit(Monitor monitor);
}
// 具体的访问者类
class ComputerPartDisplayVisitor implements ComputerPartVisitor {
@Override
public void visit(Keyboard keyboard) {
System.out.println("Displaying Keyboard.");
}
@Override
public void visit(Monitor monitor) {
System.out.println("Displaying Monitor.");
}
}
public class VisitorPatternDemo {
public static void main(String[] args) {
ComputerPart computerPart = new Keyboard();
computerPart.accept(new ComputerPartDisplayVisitor());
computerPart = new Monitor();
computerPart.accept(new ComputerPartDisplayVisitor());
}
}
10. 中介者模式(Mediator Pattern)
- 目的:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式的相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
- 应用场景:聊天室实现、界面组件间通信。
示例:
// 中介者接口
interface Mediator {
void sendMessage(String message, Colleague colleague);
}
// 具体的中介者类
class ConcreteMediator implements Mediator {
private Colleague colleague1;
private Colleague colleague2;
public void setColleague1(Colleague colleague1) {
this.colleague1 = colleague1;
}
public void setColleague2(Colleague colleague2) {
this.colleague2 = colleague2;
}
@Override
public void sendMessage(String message, Colleague colleague) {
if (colleague == colleague1) {
colleague2.notify(message);
} else {
colleague1.notify(message);
}
}
}
// 同事接口
interface Colleague {
void send(String message);
void notify(String message);
}
// 具体的同事类
class ConcreteColleague1 implements Colleague {
private Mediator mediator;
public ConcreteColleague1(Mediator mediator) {
this.mediator = mediator;
}
@Override
public void send(String message) {
mediator.sendMessage(message, this);
}
@Override
public void notify(String message) {
System.out.println("Colleague1 gets message: " + message);
}
}
class ConcreteColleague2 implements Colleague {
private Mediator mediator;
public ConcreteColleague2(Mediator mediator) {
this.mediator = mediator;
}
@Override
public void send(String message) {
mediator.sendMessage(message, this);
}
@Override
public void notify(String message) {
System.out.println("Colleague2 gets message: " + message);
}
}
11. 解释器模式(Interpreter Pattern)
- 目的:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
- 应用场景:SQL解析、正则表达式匹配。
示例:
// 抽象表达式类
interface Expression {
boolean interpret(String context);
}
// 终结符表达式类
class TerminalExpression implements Expression {
private String data;
public TerminalExpression(String data) {
this.data = data;
}
@Override
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;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) || expr2.interpret(context);
}
}
class AndExpression implements Expression {
private Expression expr1;
private Expression expr2;
public AndExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) && expr2.interpret(context);
}
}
public class InterpreterPatternDemo {
// 规则:Robert 和 John 是男性
public static Expression getMaleExpression() {
Expression robert = new TerminalExpression("Robert");
Expression john = new TerminalExpression("John");
return new OrExpression(robert, john);
}
// 规则:Julie 是已婚女性或未婚女性
public static Expression getMarriedWomanExpression() {
Expression julie = new TerminalExpression("Julie");
Expression married = new TerminalExpression("Married");
return new AndExpression(julie, married);
}
public static void main(String[] args) {
Expression isMale = getMaleExpression();
Expression isMarriedWoman = getMarriedWomanExpression();
System.out.println("John is male? " + isMale.interpret("John"));
System.out.println("Julie is a married woman? " + isMarriedWoman.interpret("Married Julie"));
}
}
每种行为型设计模式都有其独特的目的和适用场景,正确地识别和应用这些模式可以帮助开发者创建更加灵活、可维护且易于扩展的软件系统。