ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

观察者模式

2020-01-06 19:03:53  阅读:207  来源: 互联网

标签:String observer notified void 观察者 模式 new public


一、定义:

观察者模式(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();
    }
}

标签:String,observer,notified,void,观察者,模式,new,public
来源: https://www.cnblogs.com/yfy-/p/12157905.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有