观察者模式

一、定义:

观察者模式(Observer)又叫做发布-订阅模式(Publish/Subscribe),定义了一种一对多的依赖模式,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。

二、示例代码:

package com.pattern.observer;

import java.util.LinkedHashSet;

/*通知类*/
public class Notified {

    /*用linkedHashSet防止有重复的订阅者*/
    LinkedHashSet<SubscrSuper> list = new LinkedHashSet();

    String message;

    public void addSubscription(SubscrSuper subscriber) {
        list.add(subscriber);
    }

    public void removeSubscription(SubscrSuper subscriber) {
        list.remove(subscriber);
    }

    public void setMessage(String s) {
        this.message = s;
    }

    public void notif() {
        for (SubscrSuper subscriber : list
        ) {
            subscriber.update();
        }
    }
}
package com.pattern.observer;
/*抽象观察类*/
public abstract class SubscrSuper {
    protected String name;
    protected Notified notified;

    public SubscrSuper(String name,Notified notified) {
        this.name = name;
        this.notified=notified;
    }

    abstract   void update();
}
package com.pattern.observer;

public class Subscriber extends SubscrSuper {

    public Subscriber(String name, Notified notified) {
       super(name,notified);
    }

    @Override
    void update() {
        System.out.println(notified.message+" "+name+" turn down");

    }
}
package com.pattern.observer;

public class Subscrier2 extends SubscrSuper{

    public Subscrier2(String name,Notified notified) {
        super(name,notified);
    }

    @Override
    public void update() {
        System.out.println( notified.message+" "+name+" play basketball");
    }
}
package com.pattern.observer;

public class Client {

    public static void main(String[] args) {

        /*通知类*/
        Notified notified = new Notified();
        /*订阅类*/
        SubscrSuper subscriber =new Subscriber("Stoner",notified);
        SubscrSuper subscriber2 = new Subscrier2("Vienna",notified);
       /* 设置通知消息*/
        notified.setMessage("notify boos come ");

        /*给通知类添加订阅者*/
        notified.addSubscription(subscriber);
        notified.addSubscription(subscriber2);

       /* 发出通知*/
        notified.notif();

    }
}

三、利用委托类实现

上述例子的问题在于。通知类依赖于抽象观察类,但是当观察类所用的方法不一样,提取不出一个通用抽象的观察类。

package com.pattern.observer;


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/*事件类*/
public class Event {

    /*调用的对象*/
    private Object object;
    /*方法名*/
    private String methodName;
    /*方法的参数*/
    private Object[] params;
    /*方法的参数类型*/
    private Class[] paramTypes;

    public Event(Object object, String methodName, Object... objects ) {
        this.object = object;
        this.methodName = methodName;
        this.params = objects ;
        initParamTypes(this.params);
    }

    /*初始化参数类型*/
    private void initParamTypes(Object[] params) {
        if (params==null){
            return;
        }
        this.paramTypes = new Class[params.length];
        for (int i = 0; i < params.length; i++) {
            this.paramTypes[i] = params[i].getClass();
        }
    }


    /*利用反射调用对象*/
    public void invoke() {
        try {
            Method method = object.getClass().getMethod(methodName, paramTypes);
            if (method == null) {
                return;
            }
            else {
                method.invoke(object, params);
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
package com.pattern.observer;

import java.util.ArrayList;
import java.util.List;
/*事件管理类*/
public class EventHandler {

    /*事件列表*/
    public List<Event> objects;

    public EventHandler() {
        this.objects = new ArrayList<Event>();
    }
    /*添加事件*/
    public void addEvent(Object object, String methodName, Object... args) {

        objects.add(new Event(object, methodName, args));

    }

    /*通知*/
    public void notifyx(){
        for (Event event:objects){
            event.invoke();
        }
    }
}
package com.pattern.observer;
/*抽象通知者*/
public abstract class Notifier {

    private  EventHandler eventHandler = new EventHandler();

    public EventHandler getEventHandler() {
        return eventHandler;
    }


    /*增加观察者*/
    public  void addListener(Object object, String methodName, Object... args){
        eventHandler.addEvent(object, methodName, args);
    }

    /*发出通知*/
    public abstract void notifyx();
}
package com.pattern.observer;
/*具体通知者*/
public class ConcreteNotifier extends Notifier {

    @Override
    public void notifyx() {
        System.out.println("开始发出通知");
        this.getEventHandler().notifyx();
    }

}
package com.pattern.observer;
/*具体的观察类*/
import java.util.Date;

public class PlayingListener {

    public void PlayingListener() {
        System.out.println("playing games");
    }

    public void shutDownGames(Date date) {
        System.out.println("shut down games" + date);
    }
}
package com.pattern.observer;
/*具体的观察类*/
import java.util.Date;

public class WatchingListener {

    public void WatchingListener() {
        System.out.println("watching tv");
    }
    public void stopWatchingTV(Date date) {
        System.out.println("stopWatching tv"+date);
    }
}
package com.pattern.observer;

import java.util.Date;

public class Client {

    public static void main(String[] args) {

        /*通知类*/
        Notifier notifier = new ConcreteNotifier();

        WatchingListener watchingListener = new WatchingListener();
        PlayingListener playingListener = new PlayingListener();
        notifier.addListener(watchingListener,"stopWatchingTV",new Date());
        notifier.addListener(playingListener,"shutDownGames",new Date());
        notifier.notifyx();
    }
}
上一篇:MobX 在 hook 中的使用


下一篇:案例分析:设计模式与代码的结构特性