【重温设计模式】行为型设计模式之观察者模式,模板模式,策略模式
设计模式要干的事情就是解耦。
- 创建型模式是将创建和使用代码解耦,
- 结构型模式是将不同功能代码解耦,
- 行为型模式是将不同的行为代码解耦,具体到观察者模式,它是将观察者和被观察者代码解耦。
一、观察者模式
1、为什么使用观察者模式
在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。一般情况下,被依赖的对象叫作被观察者(Observable),依赖的对象叫作观察者。
同步阻塞观察者模式:被依赖对象变更逻辑和观察者逻辑在同一个线程执行。
异步非阻塞观察者模式:被依赖对象变更逻辑和观察者逻辑在不在同一个线程执行。(可通过线程池解耦,或通过队列+生产者+消费者解耦)
2、观察者模式案例
guava中的eventBus就是一个观察者模式的通用框架。
https://blog.csdn.net/u013087513/article/details/51839986(java常用的观察者模式接口)
二、模板模式
1、为什么使用模板模式
- 概念:模板方法模式在一个方法中定义一个算法骨架,并将某些步骤推迟到子类中实现。模板方法模式可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些步骤。这里的“算法”,我们可以理解为广义上的“业务逻辑”,并不特指数据结构和算法中的“算法”。这里的算法骨架就是“模板”,包含算法骨架的方法就是“模板方法”,这也是模板方法模式名字的由来。
- 作用:模板模式有两大作用:复用和扩展
模板模式的变种
- 同步回调:和模板模式比较相近,都是在算法骨架中扩展逻辑。
- 异步回调:类似观察者模式。
2、模板模式的案例
模板方法
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() { //... } @Override protected void method2() { //... } } public class ConcreteClass2 extends AbstractClass { @Override protected void method1() { //... } @Override protected void method2() { //... // } }
同步回调
public interface ICallback { void methodToCallback(); } public class BClass { public void process(ICallback callback) { //... callback.methodToCallback(); //... } }
异步回调
(Hook 比较经典的应用场景是 Tomcat 和 JVM 的 shutdown hook。接下来,我们拿 JVM 来举例说明一下。JVM 提供了 Runtime.addShutdownHook(Thread hook) 方法,可以注册一个 JVM 关闭的 Hook。当应用程序关闭的时候,JVM 会自动调用 Hook 代码)
public class ShutdownHookDemo { private static class ShutdownHook extends Thread { public void run() { System.out.println("I am called during shutting down."); } } public static void main(String[] args) { Runtime.getRuntime().addShutdownHook(new ShutdownHook()); } }
三、策略模式
1、为什么使用策略模式
概念
- 定义一族算法类,将每个算法分别封装起来,让它们可以互相替换。策略模式可以使算法的变化独立于使用它们的客户端(这里的客户端代指使用算法的代码)。我们知道,工厂模式是解耦对象的创建和使用,观察者模式是解耦观察者和被观察者。策略模式跟两者类似,也能起到解耦的作用,不过,它解耦的是策略的定义、创建、使用这三部分。
策略模式的应用
- 策略类的定义比较简单,包含一个策略接口和一组实现这个接口的策略类。
- 策略的创建由工厂类来完成,封装策略创建的细节。
- 策略模式包含一组策略可选,客户端代码如何选择使用哪个策略,有两种确定方法:编译时静态确定和运行时动态确定。其中,“运行时动态确定”才是策略模式最典型的应用场景。
2、策略模式的案例
策略的定义
public interface Strategy { void algorithmInterface(); } public class ConcreteStrategyA implements Strategy { @Override public void algorithmInterface() { //具体的算法... } } public class ConcreteStrategyB implements Strategy { @Override public void algorithmInterface() { //具体的算法...// } }
策略的创建
public class StrategyFactory { private static final Map strategies = new HashMap<>(); static { strategies.put("A", new ConcreteStrategyA()); strategies.put("B", new ConcreteStrategyB()); } public static Strategy getStrategy(String type) { if (type == null || type.isEmpty()) { throw new IllegalArgumentException("type should not be empty."); } return strategies.get(type); } }
策略的使用
基于客户端的传入,获取具体的策略,进行使用。