java设计模式-行为型:观察者、责任链、备忘录、命令、状态
责任链模式(Chain of Responsibility Pattern)
是行为型设计模式的一种。在责任链模式中,多个处理器都有机会处理请求,但是每个处理器都决定它是否可以处理该请求以及它是否应该将请求传递给链中的下一个处理器。
以下是一个简单的Java实现示例,其中我们创建了一个日志处理系统,其中消息可以被多个处理器处理:
// 抽象处理器
abstract class Handler {
protected Handler nextHandler;
public Handler setNext(Handler nextHandler) {
this.nextHandler = nextHandler;
return nextHandler; // 返回nextHandler以构建链
}
public abstract void handleRequest(String message);
}
// 具体处理器A
class ConcreteHandlerA extends Handler {
public void handleRequest(String message) {
if (message.contains("A")) {
System.out.println("ConcreteHandlerA handled request");
} else {
nextHandler.handleRequest(message);
}
}
}
// 具体处理器B
class ConcreteHandlerB extends Handler {
public void handleRequest(String message) {
if (message.contains("B")) {
System.out.println("ConcreteHandlerB handled request");
} else {
nextHandler.handleRequest(message);
}
}
}
// 使用责任链模式的示例
public class ChainOfResponsibilityPattern {
public static void main(String[] args) {
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
handlerA.setNext(handlerB); // 构建处理器链
handlerA.handleRequest("This is a message with A");
handlerA.handleRequest("This is a message with B");
handlerA.handleRequest("This is a regular message");
}
}
在这个例子中,我们定义了一个Handler抽象类和两个具体的处理器类ConcreteHandlerA和ConcreteHandlerB。
每个处理器都可以决定是否处理请求,如果不处理,它就会将请求传递给链中的下一个处理器。
在main方法中,我们创建了处理器的实例并设置了它们的后继处理器,
然后发送了几个不同的请求来查看责任链的行为。
备忘录(Memento)模式
是软件设计模式中的一种,其目的是保存一个对象的某个状态,以便在该对象以后的某个时间点恢复到这个状态。以下是一个简单的Java实现示例:
// 备忘录角色,用于存储Originator对象的状态
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) {
this.state = state;
}
public String getState() {
return state;
}
// 创建备忘录,保存当前状态
public Memento createMemento() {
return new Memento(state);
}
// 恢复备忘录的状态
public void restoreMemento(Memento memento) {
state = memento.getState();
}
}
// 看护人角色,负责保存备忘录对象,不应该对备忘录的内容进行操作和暴露
class Caretaker {
private Memento memento;
public void setMemento(Memento memento) {
this.memento = memento;
}
public Memento getMemento() {
return memento;
}
}
public class MementoPatternExample {
public static void main(String[] args) {
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
// 改变originator对象的状态
originator.setState("State #1");
System.out.println("Originator initial state: " + originator.getState());
// 创建并保存备忘录
caretaker.setMemento(originator.createMemento());
// 改变originator对象的状态
originator.setState("State #2");
System.out.println("Originator final state: " + originator.getState());
// 恢复原始状态
originator.restoreMemento(caretaker.getMemento());
System.out.println("Originator restored state: " + originator.getState());
}
}
在这个例子中,Originator类是原发器,它有一个状态需要被保存。Memento类是备忘录,用于保存Originator对象的状态。Caretaker类是看护人,负责保存备忘录,但不应该对其进行操作或暴露其内容。
观察者模式
运行这个例子会先输出原始状态,然后输出修改后的状态,最后恢复原始状态并输出恢复后的状态。
// 观察者模式示例:天气主题和观察者
// 观察者接口
interface Observer {
void update(float temp, float humidity, float pressure);
}
// 观察者实现:气象统计站
class WeatherStation implements Observer {
public void update(float temp, float humidity, float pressure) {
System.out.println("气象统计站记录了数据:");
System.out.println("温度:" + temp + " 湿度:" + humidity + " 压力:" + pressure);
}
}
// 主题接口
interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
// 主题实现:天气
class Weather implements Subject {
private List<Observer> observers;
private float temp;
private float humidity;
private float pressure;
public Weather() {
observers = new ArrayList<>();
}
public void setMeasurements(float temp, float humidity, float pressure) {
this.temp = temp;
this.humidity = humidity;
this.pressure = pressure;
notifyObservers();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(temp, humidity, pressure);
}
}
}
// 使用观察者模式示例
public class ObserverPatternExample {
public static void main(String[] args) {
Weather weather = new Weather();
WeatherStation station = new WeatherStation();
weather.registerObserver(station);
// 设置测量值,通知观察者
weather.setMeasurements(30, 65, 30.4f);
}
}
这个代码示例展示了如何在Java中实现观察者模式。
我们定义了Observer接口和Subject接口,然后分别用WeatherStation和Weather类实现它们。
Weather类作为主题,维护观察者列表,并在测量改变时通知它们。WeatherStation类作为观察者,实现了update方法来接收主题的通知。
最后在main方法中,我们创建了一个Weather实例并注册了一个WeatherStation观察者,然后设置了一些测量数据,观察者接收到通知并打印出数据。
命令模式
是一种行为设计模式,它允许你把请求封装成一个对象,从而可以使用不同的请求、队列或者日志请求、和支持撤销操作。
以下是一个简单的命令模式的Java代码实现:
// 命令接口
interface Command {
void execute();
}
// 接受者类
class Receiver {
public void open() {
System.out.println("Opening the receiver.");
}
public void close() {
System.out.println("Closing the receiver.");
}
}
// 具体命令类
class OpenCommand implements Command {
private Receiver receiver;
public OpenCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.open();
}
}
class CloseCommand implements Command {
private Receiver receiver;
public CloseCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.close();
}
}
// 调用者类
class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void setCommand(Command command) {
this.command = command;
}
public void action() {
command.execute();
}
}
// 测试代码
public class CommandPatternExample {
public static void main(String[] args) {
Receiver receiver = new Receiver();
OpenCommand openCommand = new OpenCommand(receiver);
CloseCommand closeCommand = new CloseCommand(receiver);
Invoker invoker = new Invoker(openCommand);
invoker.action(); // 打开接受者
invoker.setCommand(closeCommand);
invoker.action(); // 关闭接受者
}
}
在这个例子中,Receiver类是接受者,它知道如何执行一个请求。
OpenCommand和CloseCommand类是具体命令,它们实现了Command接口,并将一个请求封装为一个对象。
Invoker类是调用者,它接收命令对象并调用它的execute方法。
最后,在main方法中,我们创建了一个调用者,并给它传递了不同的命令来执行。
状态模式
// 状态接口
public interface State {
void doAction(Context context);
}
// 具体状态A
public class ConcreteStateA implements State {
@Override
public void doAction(Context context) {
// 处理状态A的逻辑
System.out.println("当前状态是状态A");
// 可能会根据某些条件改变状态
context.setState(new ConcreteStateB());
}
}
// 具体状态B
public class ConcreteStateB implements State {
@Override
public void doAction(Context context) {
// 处理状态B的逻辑
System.out.println("当前状态是状态B");
// 可能会根据某些条件改变状态
context.setState(new ConcreteStateA());
}
}
// 环境类
public class Context {
private State state;
public Context(State state) {
this.state = state;
}
public void setState(State state) {
this.state = state;
}
public void request() {
// 根据当前状态执行动作
state.doAction(this);
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
// 创建初始状态
State initialState = new ConcreteStateA();
// 创建环境类
Context context = new Context(initialState);
// 请求,将导致状态变化
context.request();
context.request();
context.request();
context.request();
}
}
这个简单的例子展示了状态模式的一个应用。Context类持有一个State对象的引用,并将所有与状态相关的行为委托给这个状态对象。
根据不同的状态,可以改变Context类的行为。这种模式在需要根据对象的不同状态改变其行为时特别有用。