icql

行为型设计模式概述

用来描述一些常用行为的设计模式



观察者模式

定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅模式

观察者模式和生产消费者模型的区别:

观察者:一对多,订阅者不存在竞争关系 生产者消费者:多对多,一般消费者之间存在竞争关系,只会有一个消费者可以收到消息

/**
 * 具体被观察者
 */
public class ConcreteObservable extends Observable {

    public void sendMsg(String msg) {
        setChanged();
        notifyObservers(msg);
    }
}

/**
 * 具体的观察者1
 */
public class ConcreteObserver1 implements Observer {

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("观察者1-收到消息:" + arg);
    }
}

/**
 * 具体的观察者2
 */
public class ConcreteObserver2 implements Observer {

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("观察者2-收到消息:" + arg);
    }
}

/**
 * 观察者模式
 */
public class ObserverClient {

    public static void main(String[] args) {
        //java提供了Observer接口和Observable类来作为观察者模式的抽象层
        //我们只需要自定义具体观察者类和具体观察目标类即可实现观察者模式
        ConcreteObservable observable = new ConcreteObservable();
        observable.addObserver(new ConcreteObserver1());
        observable.addObserver(new ConcreteObserver2());
        observable.sendMsg("测试消息");
    }
}



模板模式

模板方法模式在一个方法中定义一个算法骨架,并将某些步骤推迟到子类中实现。模板方法模式可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些步骤

作用:

(1)复用 java-io中 InputStream,OutputStream,Reader,Writer等,InputStream 的 read 方法 Java AbstractList,addAll(int index, Collection<? extends E> c) 方法 -> add(int index, E element) (2)扩展 HttpServlet中的service()方法是一个模板方法,它实现了整个 HTTP 请求的执行流程,doGet()、doPost() 是模板中可以由子类来定制的部分

回调机制:同步回调(和模板方法模式作用相似),异步回调

public abstract class AbstractClass {

    public final void templateMethod() {
        //...
        method1();
        //...
        method2();
        //...
    }

    protected abstract void method1();

    protected abstract void method2();
}

public class ConcreteClass1 extends AbstractClass {

    @Override
    protected void method1() {
        System.out.println("ConcreteClass1.method1");
    }

    @Override
    protected void method2() {
        System.out.println("ConcreteClass1.method2");
    }
}

public class ConcreteClass2 extends AbstractClass {

    @Override
    protected void method1() {
        System.out.println("ConcreteClass2.method1");
    }

    @Override
    protected void method2() {
        System.out.println("ConcreteClass2.method2");
    }
}

/**
 * 模板方法模式
 */
public class TemplateClient {

    public static void main(String[] args) {
        AbstractClass demo1 = new ConcreteClass1();
        demo1.templateMethod();

        AbstractClass demo2 = new ConcreteClass2();
        demo2.templateMethod();
    }
}



策略模式

定义一组算法类,将每个算法分别封装起来,让它们可以互相替换。策略模式可以使算法的变化独立于使用它们的客户端

场景:

使用策略模式一般借助工厂模式封装策略 取消if else分支

/**
 * 策略接口定义
 */
public interface Strategy {

    void operation();
}

/**
 * 具体的策略A
 */
public class ConcreteStrategyA implements Strategy {

    @Override
    public void operation() {
        System.out.println("具体的策略A");
    }
}

/**
 * 具体的策略B
 */
public class ConcreteStrategyB implements Strategy {

    @Override
    public void operation() {
        System.out.println("具体的策略B");
    }
}

/**
 * 策略使用工厂
 */
public class StrategyFactory {

    private static final Map<String, Strategy> STRATEGY_BY_TYPE = new HashMap<>();

    static {
        STRATEGY_BY_TYPE.put("A", new ConcreteStrategyA());
        STRATEGY_BY_TYPE.put("B", new ConcreteStrategyB());
    }

    public Strategy getStrategy(String type) {
        //校验type
        return STRATEGY_BY_TYPE.get(type);
    }
}

public class StrategyClient {

    public static void main(String[] args) {
        StrategyFactory factory = new StrategyFactory();
        Strategy strategyA = factory.getStrategy("A");
        strategyA.operation();
    }
}



职责链模式

将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止

经典应用:Servlet Filter,Spring Interceptor

//(1)数组实现
public interface IHandler {

    boolean handle(Object o);
}

public class HandlerA implements IHandler {

    @Override
    public boolean handle(Object o) {
        boolean handled = false;
        //...
        return handled;
    }
}

public class HandlerB implements IHandler {

    @Override
    public boolean handle(Object o) {
        boolean handled = false;
        //...
        return handled;
    }
}

public class HandlerChain {

    private List<IHandler> handlers = new ArrayList<>();

    public void addHandler(IHandler handler) {
        this.handlers.add(handler);
    }

    public void handle(Object o) {
        for (IHandler handler : handlers) {
            boolean handled = handler.handle(o);
            if (handled) {
                break;
            }
        }
    }
}

//(2)链表实现
public abstract class Handler {

    protected Handler successor = null;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public final void handle(Object o) {
        boolean handled = doHandle(o);
        if (successor != null && !handled) {
            successor.handle(o);
        }
    }

    protected abstract boolean doHandle(Object o);
}

public class HandlerA extends Handler {

    @Override
    protected boolean doHandle(Object o) {
        boolean handled = false;
        //...
        return handled;
    }
}

public class HandlerB extends Handler {

    @Override
    protected boolean doHandle(Object o) {
        boolean handled = false;
        //...
        return handled;
    }
}

public class HandlerChain {

    private Handler head = null;
    private Handler tail = null;

    public void addHandler(Handler handler) {
        handler.setSuccessor(null);
        if (head == null) {
            head = handler;
            tail = handler;
            return;
        }
        tail.setSuccessor(handler);
        tail = handler;
    }

    public void handle(Object o) {
        if (head != null) {
            head.handle(o);
        }
    }
}

/**
 * 职责链模式
 * 2种实现方式:链表和数组,数组相对简单易用
 */
public class ChainOfResponsibilityClient {

    public static void main(String[] args) {
        HandlerChain chain = new HandlerChain();
        chain.addHandler(new HandlerA());
        chain.addHandler(new HandlerB());
        chain.handle(new Object());
    }
}



状态模式

状态机(有限状态机)的常用表示法有 分支判断,查表,状态模式



迭代器模式



访问者模式



备忘录模式



命令模式



解释器模式



中介模式