设计模式 -- 观察者模式

2018-11-18  本文已影响0人  tom_xin

什么是观察者模式

    定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。


使用场景

  1. 解耦:当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
  2. 可扩展性:当一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变。
  3. 当一个对象必须通知其他对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合。

观察者模式的结构

    


image.png

Subject(目标)
当它的状态发生改变时,向它的各个观察者发出通知。
Observer(观察者)
实现Observer的更新接口以使自身状态与目标状态一致。


观察者模式的优缺点

优点

  1. 目标和观察者的抽象耦合:一个目标所知道仅仅是它有一系列观察者,每个都符合抽象的Observer类的简单接口。
  2. 支持广播通信:目标对象并不关心到底有多少对象对自己感兴趣,它唯一的职责就是通知它的各观察者。
    缺点:
  3. 意外更新:如果依赖准则的定义和维护不当,常常会引起错误的更新,这种错误通常很难捕获。

观察者模式的实现

先来看一个典型的实例:

/**
 * 定义抽象的目标类
 *
 * @author tomxin
 * @date 2018-11-18
 * @since v1.0.0
 */
public interface Subject {

    /**
     * 发送消息
     */
    void publish(String message);
}
/**
 * 定义一个具体的目标类
 *
 * @author tomxin
 * @date 2018-11-18
 * @since v1.0.0
 */
public class ConcreteSubject implements Subject {

    List<Observer> observerList = new ArrayList<>();

    /**
     * 添加观察者
     * 
     * @param observer
     */
    public void addObserver(Observer observer) {
        observerList.add(observer);
    }

    /**
     * 发送消息
     *  
     * @param message
     */
    @Override
    public void publish(String message) {
        for (Observer observer : observerList) {
            observer.handler(message);
        }
    }
}

/**
 * 自定义观察者
 *
 * @author tomxin
 * @date 2018-11-18
 * @since v1.1.0
 */
public interface Observer {

    /**
     * 处理消息
     *
     * @param message
     */
    void handler(String message);
}

/**
 * 创建实例观察者
 *
 * @author tomxin
 * @date 2018-11-18
 * @since v1.0.0
 */
public class ConcreteObserver implements Observer {

    /**
     * 处理消息
     *
     * @param message
     */
    @Override
    public void handler(String message) {
        System.out.println(this.getClass());
        System.out.println(message);
    }
}

/**
 * 创建实例观察者
 * 
 * @author tomxin
 * @date 2018-11-18
 * @since v1.0.0
 */
public class ConcreteObserver1 implements Observer {

    /**
     * 处理消息类
     *
     * @param message
     */
    @Override
    public void handler(String message) {
        System.out.println(this.getClass() + ",message : " + message);
    }
}

/**
 * Main函数
 * 
 * @author tomxin
 * @date 2018-11-18
 * @since v1.0.0
 */
public class ObserverMain {

    public static void main(String[] args) {
        // 实例化目标类
        Subject subject = new ConcreteSubject();
        // 定义观察者
        Observer observer1 = new ConcreteObserver();
        Observer observer2 = new ConcreteObserver1();

        ((ConcreteSubject) subject).addObserver(observer1);
        ((ConcreteSubject) subject).addObserver(observer2);
        // 发送消息
        subject.publish("notify message");
    }
}

Observer + Mediator 模式结合实现观察者模式,实现Observer与Mediator解耦。

/**
 * 观察者接口
 *
 * @author tomxin
 * @date 2018-11-18
 * @since v1.0.0
 */
public interface MediatorObserver {

    /**
     * 处理消息的接口
     *
     * @param message
     */
    void handler(String message);
}

/**
 * @author tomxin
 * @date 2018-11-18
 * @since v1.0.0
 */
public class ObserverInstance implements MediatorObserver {

    public ObserverInstance() {
        // 在构造函数中
        MediatorInstance.register(this);
    }

    /**
     * 处理消息
     *
     * @param message
     */
    @Override
    public void handler(String message) {
        System.out.println(message);
    }
}

/**
 * 定义目标类
 *
 * @author tomxin
 * @date 2018-11-18
 * @since v1.0.0
 */
public class MediatorSubject {

    /**
     * 消息通知
     *
     * @param message
     */
    public void notify(String message) {
        MediatorInstance.publish(message);
    }
}

/**
 * 中介者实体类
 *
 * @author tomxin
 * @date 2018-11-18
 * @since v1.0.0
 */
public class MediatorInstance {

    /**
     * 观察者列表
     */
    private static Set<Object> observerList = new HashSet<>(16);

    /**
     * 注册观察者
     *
     * @param observer
     */
    public static void register(Object observer) {
        observerList.add(observer);
    }

    /**
     * 发送消息
     *
     * @param message
     */
    public static void publish(String message) {
        try {
            for (Object observer : observerList) {
                Class<?> observerClazz = observer.getClass();
                Class[] classes = new Class[1];
                classes[0] = String.class;
                Method method = observerClazz.getMethod("handler", classes);
                Object result = method.invoke(observer, message);
            }
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }
}

/**
 * Main方法
 *
 * @author tomxin
 * @date 2018-11-17
 * @since v1.0.0
 */
public class MediatorObserverMain {

    public static void main(String[] args) {
        // 实例化观察者
        ObserverInstance observerInstance = new ObserverInstance();
        // 实例化目标类
        MediatorSubject mediatorSubject = new MediatorSubject();
        // 发送消息通知
        mediatorSubject.notify("message");
    }
}

有兴趣的同学,可以看一下Guava中EventBus的实现。

上一篇 下一篇

猜你喜欢

热点阅读