zoukankan      html  css  js  c++  java
  • 观察者模式

    观察者模式

    当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

    优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。

    缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

    注意事项: 1、JAVA 中已经有了对观察者模式的支持类。 2、避免循环引用。 3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

    步骤 1

    创建被观察类 Subject 类。

    import java.util.ArrayList;
    import java.util.List;
    
    //被观察者
    public class Subject {
    
        //需要观察者观察的东西
        public static Integer number = 3;
    
        //观察者名单
        private static List<Observer> observers =  new ArrayList<Observer>();
    
        public static void addObserver(Observer observer){
            observers.add(observer);
        }
    
        //遍历观察者名单执行观察者类中的方法
        public void outNumber(){
            for (Observer observer : observers) {
                //创建线程来执行
                Thread thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        observer.update();
                    }
                });
                thread.start();
    
            }
        }
    
    }

    步骤 2

    创建观察者父类 Observer抽象类。

    public abstract class Observer {
        //被观察者对象
        public Subject subject;
        //观察者对象们,需要共同干的事
        public abstract void update();
    }

    步骤 3

    创建实体观察者类。

    //观察者1号
    public class Observer1 extends Observer{
    
        //有参构造
        public Observer1(Subject subject){
    
            //对继承的对象变量赋值
            this.subject = subject;
    
            //执行继承的对象变量中的方法
            this.subject.addObserver(this);
        }
    
        //实现父类的方法
        @Override
        public void update() {
            //添加异常
            Integer a = 1/0;
    
            System.out.println("观察者1号:"+subject.number);
        }
    }
    //观察者2号
    public class Observer2 extends Observer{
    
        //有参构造
        public Observer2(Subject subject){
    
            //对继承的对象变量赋值
            this.subject = subject;
    
            //执行继承的对象变量中的方法
            this.subject.addObserver(this);
        }
    
        //实现父类的方法
        @Override
        public void update() {
            System.out.println("观察者2号:"+subject.number);
        }
    }

    步骤 4

    测试。

    public class Test {
        public static void main(String[] args) {
            //创建被观察实例
            Subject subject = new Subject();
    
            //创建观察者实例
            new Observer1(subject);
            new Observer2(subject);
    
            //执行被观察者方法
            subject.outNumber();
    
        }
    }

    结果

     从结果可以看出,用异步方式来执行观察者的方法,可以避免卡壳,如果不用异步观察者2号将不会打印

  • 相关阅读:
    SQLServer之数据库行锁
    SQLServer之锁定数据库表
    SQLServer之锁简介
    SQLServer之删除函数
    CMD命令行合并多个txt文件到一个txt文件
    CMD命令搜索有某文本文件的内容
    Oracle表结构修改触发视图无法正常使用问题
    java中final关键字
    SQL Server Url Decode函数
    使用SQL SERVER PIVOT实现行列转置
  • 原文地址:https://www.cnblogs.com/bigbigxiao/p/13098617.html
Copyright © 2011-2022 走看看