zoukankan      html  css  js  c++  java
  • 设计模式总结1--observer pattern

    <!-- 设计模式 -->
    <!--是一套被反复使用、多数人知
    晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了
    可重用代码、让代码更容易被他人理解、保证代 码可靠性 -->
    -------------------------------------------------------------
    <!-- 观察者模式 observer patterns-->

    <!-- 对于天气预报的举例,首先这是常规的方法 -->

    public class WeatherData {
        
        private int low;
        private int height;
        private String weather;
        
        
        public int getLow() {
            return low;
        }
        public int getHeight() {
            return height;
        }
        public String getWeather() {
            return weather;
        }
        
        public void setData(int low,int height,String weather){
            this.low = low;
            this.height = height;
            this.weather = weather;
            
            change();
        }
        private void change() {
    
            Xiaomi xiaomi = new Xiaomi();
            xiaomi.disPlay(getLow(),getHeight(),getWeather());
            
            Chuizi chuizi = new Chuizi();
            chuizi.disPlay(getLow(),getHeight(),getWeather());
        }
        
    }
    public class Xiaomi {
    
        public void disPlay(int low, int height, String weather) {
            System.out.println(low + ":" + height + ":" + weather);
        }
    
    }
    public class Chuizi {
        public void disPlay(int low, int height, String weather) {
            System.out.println(low + ":" + height + ":" + weather);
        }
    }


    但是这是有问题的,不够灵活,有的厂商想加上这个功能,有的厂商想去掉这个功能
    就像报纸
    出版社的任务就是出报纸
    你订阅了出版社的报纸,出版社就会将新的报纸给你送
    你不需要该出版社的报纸,可以取消订阅
    只要出版社还在,就会一直有很多人取消或订阅报纸

    观察者模式
    定义了对象间一对多的依赖,这样一来,当一个对象的状态改变时,
    它的所有依赖都会自动收到通知并自动更新
    报社是主题,订阅者是观察者对象



    /*定义一个主题接口*/
    public interface Subject {
        
        public void addObserver(Observer observer);
        public void removeObserver(Observer observer);
        public void notifyObserver();
        
    }
    /*主题要继承自主题接口,用于添加一些对观察者操作的几个方法*/
    public class WeatherData implements Subject{
        
        private int low;
        private int height;
        private String weather;
        //定义一个list,用于存放所有观察者,方便下面进行通知
        private List<Observer> list = new ArrayList<Observer>();
        public int getLow() {
            return low;
        }
        public int getHeight() {
            return height;
        }
        public String getWeather() {
            return weather;
        }
        
        public void setData(int low,int height,String weather){
            this.low = low;
            this.height = height;
            this.weather = weather;
            //通知观察者
            notifyObserver();
            
        }
    
        
        //对观察者进行添加
        @Override
        public void addObserver(Observer observer) {
            if(observer == null){
                return;
            }
            if(!list.contains(observer)){
                list.add(observer);
            }
            
        }
        //通知所有观察者
        @Override
        public void notifyObserver() {
            for(Observer o : list){
                o.update(getLow(), getHeight(), getWeather());
            }
        }
        //删除观察者
        @Override
        public void removeObserver(Observer observer) {
            list.remove(observer);
        }
        
        
        
        
    }
    /*定义一个观察者接口,观察者在继承之后要实现他的方法用于更新数据*/
    public interface Observer {
        
        public void update(int low,int height,String weather);
    }
    public class Xiaomi implements Observer{
        
        /**
         * 对于观察者,我希望做到不管是添加该业务还是取消,主题端是不管的,所以
         * 定义构造方法,new出来这个对象的时候自动加入到被通知列(成为观察者),
         * 同时还设有取消该业务
         */
        
        
        
        
        private Subject subject;
        
        public Xiaomi(Subject subject){
            this.subject = subject;
            subject.addObserver(this);
        }
        public void cancle(){
            subject.removeObserver(this);
        }
        
    
        public void disPlay(int low, int height, String weather) {
            System.out.println(low + ":" + height + ":" + weather);
        }
    
        @Override
        public void update(int low, int height, String weather) {
            disPlay(low,height,weather);
        }
    
    }
    public class Chuizi implements Observer{
    
    
            private Subject subject;
            
            public Chuizi(Subject subject){
                this.subject = subject;
                subject.addObserver(this);
            }
            public void cancle(){
                subject.removeObserver(this);
            }
            
        
            public void disPlay(int low, int height, String weather) {
                System.out.println(low + ":" + height + ":" + weather);
            }
    
            @Override
            public void update(int low, int height, String weather) {
                disPlay(low,height,weather);
            }
            
        
        
        
    }

    测试运行

    public class test {
        public static void main(String[] args) {
            WeatherData data = new WeatherData();
            
            <!-- 加入该业务 -->
            Xiaomi xiaomi = new Xiaomi(data);
            Chuizi chuizi = new Chuizi(data);
            <!-- 两个都通知 -->
            data.setData(1, 10, "晴朗");
            <!-- 取消该业务 -->
            xiaomi.cancle();
            <!-- 只通知一个 -->
            data.setData(2, 12, "晴朗");
            
        }
    }


    ======================================================================
    ======================================================================
    ======================================================================
    java中内置的观察者模式
    在这里不是实现了而是继承

    public class WeatherData extends Observable {
    
        private int low;
        private int height;
        private String weather;
        
        
        public int getLow() {
            return low;
        }
        public int getHeight() {
            return height;
        }
        public String getWeather() {
            return weather;
        }
        
        public void setData(int low,int height,String weather) {
            this.low = low;
            this.height = height;
            this.weather = weather;
            change();
        }
        
        public void change() {
        /*Observable,可以点击进入Observable看里面的方法,首先setChanged()将changed属性改为true
            代表有改变*/
            setChanged();
            /* 通知观察者 */
            <!-- 方式1 -->
            notifyObservers();
            <!-- 方式2 -->
            notifyObservers(new Object[]{getLow(),getHeight(),getWeather()});
        }
        
    }
                
    import java.util.Observable;
    import java.util.Observer;
    
    public class Htc implements Observer{
    /*构造方法,将自己加入通知列*/
        private Observable observable;
        public Htc(Observable observable) {
            this.observable = observable;
            observable.addObserver(this);
        }
        /*取消该业务 */
        public void cancel() {
            observable.deleteObserver(this);
        }
        
        
        public void display(int low,int height,String weather) {
            System.out.println("HTC 最低温度:" + low + " 最高温度:" + height + " 天气:" + weather);
        }
    
        @Override
        public void update(Observable o, Object arg) {
            /*
            拉模式:当要使用的时候再获取
            对应上面的方式1 当创建weatherdata的时候会执行父类的构造方法 这个o是从父类中
            传过来的(传的是this),所以这个o指的是weatherdata本身,强制转换*/
            WeatherData wd = (WeatherData) o;
            display(wd.getLow(), wd.getHeight(), wd.getWeather());
            
            
            /*
            推模式:不管你用不用,我先给你
            对应上面的方式2 当使用notifyObservers(new Object[]{getLow(),getHeight(),getWeather()});
                arg不为null*/
            if(arg != null) {
            Object[] array = (Object[]) arg;
            display(Integer.parseInt(array[0].toString()), Integer.parseInt(array[1].toString()), array[2].toString());
            }
            
            
            
        }
        
                
    }

    测试

    public class Test {
    
        public static void main(String[] args) {
            
            WeatherData wd = new WeatherData();
            
            Htc htc = new Htc(wd);
            
            wd.setData(2, 8, "晴天");
            
            
        }
    }

    ----------------------------------------------------------------------
    ----------------------------------------------------------------------
    对于要使用自己写的还是java内置的?
    java中的主题是要继承的而不是实现的,所以当他已经有了父类的时候就不能再继承其他类

    Observable是一个类,主题类只能继承该类,如果主题类已经有
    了父类,则无法完成观察者模式,因为Java不支持多继承。

     

    关于观察者模式
    该模式定义了对象之间一对多的关系
    主题用一个共同的接口来更新观察者
    主题和观察者之间用松耦合的方式结合,主题不知道观察者的细节,只知道观察者实现了观察者接口
    java中内置了观察者模式
    知道使用Java中内置观察者模式的缺点
    如有必要,尽量自己实现观察者模式,而不是使用Java中内置的

  • 相关阅读:
    Oracle之:Function :dateToNumber()
    Oracle之:Function :getcurrdate()
    Oracle之:Function :getdate()
    Hadoop-No.15之Flume基于事件的数据收集和处理
    Hadoop-No.14之文件传输的特点
    Hadoop-No.13之数据源系统以及数据结构
    Hadoop-No.12之数据采集的时效性
    Hadoop-No.11之元数据
    Hadoop-No.10之列簇
    Hadoop-No.9之表和Region
  • 原文地址:https://www.cnblogs.com/itliucheng/p/4226624.html
Copyright © 2011-2022 走看看