• 观察者模式


    一、定义:

    观察者模式(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();
        }
    }
    
    
  • 相关阅读:
    一个喜欢研究车的80后开车人,自己的经验和感受
    35岁前务必成功的12级跳(男女通用) 转
    如何注册ocx文件
    plsql连接oracle数据库
    float过后 高度无法自适应的解决方法
    Mysql 中文中繁杂的字 插入报错的 解决方案
    power designer 教程
    表单文本框输入时提示文字消失
    diskpart分盘代码
    linux svn 中文 https://my.oschina.net/VASKS/blog/659236
  • 原文地址:https://www.cnblogs.com/yfy-/p/12157905.html
Copyright © 2020-2023  润新知