Java设计模式四 - 行为型模式

1. 策略模式(Strategy Pattern)

1.1 定义

策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

1.2 侧重点

定义一系列算法,使它们可以独立替换。 将算法的使用与算法的实现分离,客户可以选择所需的算法。

1.3 使用场景

需要在运行时选择算法时,可以使用策略模式。 需要避免暴露复杂的条件语句或多重分支时。

1.4 示例代码(Java)
interface PaymentStrategy {
    void pay(int amount);
}

class CreditCardPayment implements PaymentStrategy {
    private String cardNumber;

    public CreditCardPayment(String cardNumber) {
        this.cardNumber = cardNumber;
    }

    @Override
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via credit card " + cardNumber);
    }
}

class PayPalPayment implements PaymentStrategy {
    private String email;

    public PayPalPayment(String email) {
        this.email = email;
    }

    @Override
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via PayPal with email " + email);
    }
}

class ShoppingCart {
    private PaymentStrategy paymentStrategy;

    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }
}

2. 观察者模式(Observer Pattern)

2.2 定义

观察者模式定义了一种一对多的依赖关系,使得多个观察者对象同时监听某一个主题对象,当主题对象状态发生变化时,所有依赖于它的观察者都会得到通知并更新。

2.3 侧重点

定义了对象间的一对多依赖关系,以便一个对象的状态变化会影响其他对象。 主题对象(被观察者)状态变化时通知所有观察者。

2.4 使用场景

当一个对象的改变需要同时改变其他对象,而且不知道有多少对象有待改变时,可以使用观察者模式。

2.5 示例代码(Java)
import java.util.ArrayList;
import java.util.List;

interface Observer {
    void update(String message);
}

class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " received message: " + message);
    }
}

class Subject {
    private List<Observer> observers = new ArrayList<>();

    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

3. 命令模式(Command Pattern)

3.1 定义

命令模式将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。

3.2 侧重点

将请求封装为对象,以便支持命令排队、请求参数化、撤销操作等。 解耦发送者和接收者,使得发送者不需要知道接收者的具体操作。

3.3 使用场景

需要支持命令排队、请求参数化、撤销操作时,可以使用命令模式。 需要将发送者和接收者解耦时。

3.4 示例代码(Java)
interface Command {
    void execute();
}

class Light {
    public void on() {
        System.out.println("Light is on");
    }

    public void off() {
        System.out.println("Light is off");
    }
}

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 RemoteControl {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void pressButton() {
        command.execute();
    }
}

4. 迭代器模式(Iterator Pattern)

4.1 定义

迭代器模式提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节。

4.2 侧重点

提供一种统一的方法遍历容器对象,而无需暴露其内部结构。 封装遍历过程,使得遍历算法可以独立于集合类变化。

4.3 使用场景

当需要对容器对象遍历,但又不想暴露其内部结构时,可以使用迭代器模式。 需要多种遍历方式时。

4.4 示例代码(Java)
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

class ConcreteAggregate<T> implements Iterable<T> {
    private List<T> items = new ArrayList<>();

    public void addItem(T item) {
        items.add(item);
    }

    @Override
    public Iterator<T> iterator() {
        return items.iterator();
    }
}

public class IteratorExample {
    public static void main(String[] args) {
        ConcreteAggregate<String> aggregate = new ConcreteAggregate<>();
        aggregate.addItem("Item 1");
        aggregate.addItem("Item 2");
        aggregate.addItem("Item 3");

        Iterator<String> iterator = aggregate.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

5. 责任链模式(Chain of Responsibility Pattern)

5.1 定义

责任链模式为请求创建了一个接收者对象的链,使得多个接收者对象都有机会处理该请求,将请求沿着链传递,直到有一个接收者处理它。

5.2 侧重点

将请求和处理者解耦,使得处理者不需知道下一个处理者。 允许动态添加新的处理者,改变处理链。

5.3 使用场景

当有多个对象可以处理一个请求,但不希望显式指定处理者时。 需要动态指定可以处理请求的对象集合时。

5.4 示例代码(Java)
class Request {
    private int amount;

    public Request(int amount) {
        this.amount = amount;
    }

    public int getAmount() {
        return amount;
    }
}

interface Handler {
    void setNextHandler(Handler handler);
    void processRequest(Request request);
}

class ConcreteHandler implements Handler {
    private Handler nextHandler;

    @Override
    public void setNextHandler(Handler handler) {
        this.nextHandler = handler;
    }

    @Override
    public void processRequest(Request request) {
        // Process the request
    }
}

public class ChainOfResponsibilityExample {
    public static void main(String[] args) {
        Handler handler1 = new ConcreteHandler();
        Handler handler2 = new ConcreteHandler();

        handler1.setNextHandler(handler2);

        Request request = new Request(100);
        handler1.processRequest(request);
    }
}

6. 备忘录模式(Memento Pattern)

6.1 定义

备忘录模式用于保存对象的内部状态,以便在以后可以将对象恢复到这个状态。

6.2 侧重点

封装了对象的状态,允许将对象恢复到先前的状态。 保持封装性,不暴露对象的内部状态。

6.3 使用场景

需要保存和恢复对象状态的场景,比如撤销操作、版本历史等。

6.4 示例代码(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) {
        this.state = state;
    }

    public String getState() {
        return state;
    }

    public Memento saveToMemento() {
        return new Memento(state);
    }

    public void restoreFromMemento(Memento memento) {
        state = memento.getState();
    }
}

public class MementoExample {
    public static void main(String[] args) {
        Originator originator = new Originator();
        originator.setState("State 1");

        Memento memento = originator.saveToMemento();

        originator.setState("State 2");

        System.out.println("Current state: " + originator.getState());

        originator.restoreFromMemento(memento);

        System.out.println("Restored state: " + originator.getState());
    }
}

7. 状态模式(State Pattern)

7.1 定义

状态模式允许一个对象在其内部状态改变时改变其行为,对象看起来似乎修改了其类。

7.2 侧重点

将对象的状态封装成独立的类,使得状态的变化可以独立于对象的变化。 允许对象在其内部状态改变时改变其行为。

7.3 使用场景

当对象的行为取决于其状态,并且可以在运行时根据状态改变时。 需要将复杂的条件语句替换为基于对象的状态时。

7.4 示例代码(Java)
interface State {
    void doAction(Context context);
}

class ConcreteState1 implements State {
    @Override
    public void doAction(Context context) {
        System.out.println("State 1: Performing action");
        context.setState(new ConcreteState2());
    }
}

class ConcreteState2 implements State {
    @Override
    public void doAction(Context context) {
        System.out.println("State 2: Performing action");
        context.setState(new ConcreteState1());
    }
}

class Context {
    private State state;

    public Context() {
        this.state = new ConcreteState1();
    }

    public void setState(State state) {
        this.state = state;
    }

    public State getState() {
        return state;
    }

    public void performAction() {
        state.doAction(this);
    }
}

8.访问者模式(Visitor Pattern)

8.1 定义

访问者模式将数据结构和数据操作分离,允许在不改变数据结构的前提下定义数据操作。

8.2 侧重点

分离数据结构和数据操作。 新操作的增加相对较容易,不需要修改现有的数据结构。

8.3 使用场景

需要在不同对象上进行操作,但不希望污染这些对象的类时。 需要对对象的结构和数据分离时。

8.4 示例代码(Java)
interface Visitor {
    void visit(ElementA element);
    void visit(ElementB element);
}

class ConcreteVisitor implements Visitor {
    @Override
    public void visit(ElementA element) {
        System.out.println("Visitor visits ElementA");
    }

    @Override
    public void visit(ElementB element) {
        System.out.println("Visitor visits ElementB");
    }
}

interface Element {
    void accept(Visitor visitor);
}

class ElementA implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

class ElementB implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

9. 模板方法模式(Template Method Pattern)

9.1 定义

模板方法模式定义了一个操作中的算法框架,而将一些步骤延迟到子类中实现。

9.2 侧重点

定义一个算法的骨架,而将一些步骤的实现延迟到子类。 子类可以对算法的特定步骤进行重定义。

9.3 使用场景

需要在不同子类中共享算法框架,但允许子类实现特定步骤时。

9.4 示例代码(Java)
abstract class AbstractClass {
    public final void templateMethod() {
        step1();
        step2();
        step3();
    }

    protected abstract void step1();
    protected abstract void step2();
    protected abstract void step3();
}

class ConcreteClass1 extends AbstractClass {
    @Override
    protected void step1() {
        System.out.println("ConcreteClass1: Step 1");
    }

    @Override
    protected void step2() {
        System.out.println("ConcreteClass1: Step 2");
    }

    @Override
    protected void step3() {
        System.out.println("ConcreteClass1: Step 3");
    }
}

class ConcreteClass2 extends AbstractClass {
    @Override
    protected void step1() {
        System.out.println("ConcreteClass2: Step 1");
    }

    @Override
    protected void step2() {
        System.out.println("ConcreteClass2: Step 2");
    }

    @Override
    protected void step3() {
        System.out.println("ConcreteClass2: Step 3");
    }
}

10. 解释器模式(Interpreter Pattern)

10.1 定义

解释器模式定义了一个语言的文法,并提供了解释语言中句子的解释器。

10.2 侧重点

定义语言的文法规则,以及解释这些规则的解释器。 允许灵活地扩展语言解释器。

10.3 使用场景

当需要解释并执行特定语言的语句时。 需要实现编译器或解释器时。

10.4 示例代码(Java)
import java.util.HashMap;
import java.util.Map;

interface Expression {
    int interpret(Map<String, Integer> variables);
}

class Number implements Expression {
    private int number;

    public Number(int number) {
        this.number = number;
    }

    @Override
    public int interpret(Map<String, Integer> variables) {
        return number;
    }
}

class Variable implements Expression {
    private String name;

    public Variable(String name) {
        this.name = name;
    }

    @Override
    public int interpret(Map<String, Integer> variables) {
        if (variables.containsKey(name)) {
            return variables.get(name);
        }
        return 0;
    }
}

class Plus implements Expression {
    private Expression leftOperand;
    private Expression rightOperand;

    public Plus(Expression leftOperand, Expression rightOperand) {
        this.leftOperand = leftOperand;
        this.rightOperand = rightOperand;
    }

    @Override
    public int interpret(Map<String, Integer> variables) {
        return leftOperand.interpret(variables) + rightOperand.interpret(variables);
    }
}

以上是行为型模式的详解和示例代码。每种模式都有其特定的用途和适用场景,根据具体的开发需求选择合适的模式来提高代码质量。

版权声明: 闲者 发表于 2024-08-07
转载请注明: Java设计模式四 - 行为型模式 | Java设计模式四 - 行为型模式 - 无界文档,Java设计模式四 - 行为型模式

评论区

暂无评论...