标签:this ini hand dex cat not stopwatch 通知 利用反射
观察者模式(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();
    }
}
标签:this ini hand dex cat not stopwatch 通知 利用反射
原文地址:https://www.cnblogs.com/yfy-/p/12157905.html