设计模式之观察者模式

一、概述

1、作用
  • 将观察者和被观察者解耦
2、定义
  • 定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,所有依赖于它的对象都会得到通知并被自动更新
3、使用场景
  • 可拆分的关联行为场景
  • 事件多级触发场景
  • 跨系统的消息交换场景,如消息队列、事件总线的处理机制
4、UML类图:

设计模式之观察者模式

  • Subject(Observable): 目标(接口或抽象类
  • ConcreteSubject: 具体目标
  • Observer: 观察者(接口或抽象类
  • ConcreteObserver: 具体观察者

二、实现

  • 场景:A、B、C三人在书店订阅了同一本杂志,当该杂志上架的时候,会通知他们杂志上架的信息(包括杂志的期数、最新价格),让他们过来购买。
1、建立被观察者接口
        public interface Observerable { 
            public void registerObserver(Observer o); 
            public void removeObserver(Observer o); 
            public void notifyObservers(); 
        }
2、建立观察者接口
        public interface Observer {
            public void update(int edition,float cost);
        }
3、实现被观察者接口(实现观察者的注册、解注册和通知方法
        public class MagazineData implements Observerable { 
            private List<Observer> mObservers;    //观察者列表
            private int edition; private float cost;
            
            public MagazineData() {
                mObservers = new ArrayList<>(); 
            } 
            
            //注册
            @Override 
            public void registerObserver(Observer o) { 
                mObservers.add(o); 
            } 
            
            //解注册
            @Override 
            public void removeObserver(Observer o) { 
                int i = mObservers.indexOf(o);
                if(i >= 0) 
                    mObservers.remove(i); 
            } 
            
            //通知
            @Override 
            public void notifyObservers() { 
                for(int i = 0; i < mObservers.size(); i++){
                    Observer observer = mObservers.get(i); 
                    observer.update(edition, cost); 
                } 
            }
            
            public void setInfomation(int edition,float cost){     
                this.edition = edition;
                this.cost = cost; 
                
                //信息更新完毕,通知所有观察者 
                notifyObservers(); 
                
            } 
        }

4、实现观察者接口
        public class Customer implements Observer { 
            private String name;
            private int edition;
            private float cost;
            
            public Customer(String name){ 
                this.name = name; 
            } 
            
            @Override 
            public void update(int edition, float cost) { 
                this.edition = edition; 
                this.cost = cost; buy();
            } 
                
            public void buy(){   
                System.out.println(name+"购买了第"+edition+"期的杂志,花费了"+cost+"元。"); 
            } 
            
        }
5、Test
        public class Test { 
            public static void main(String[] args) { 
                //创建被观察者 
                MagazineData magazine = new MagazineData(); 
                //创建三个不同的观察者 
                Observer customerA = new Customer("A"); 
                Observer customerB = new Customer("B");
                Observer customerC = new Customer("C"); 
            
                //将观察者注册到被观察者中 
                magazine.registerObserver(customerA); 
                magazine.registerObserver(customerB); 
                magazine.registerObserver(customerC);
                
                //更新被观察者中的数据,当数据更新后,会自动通知所有已注册的观察者 
                magazine.setInfomation(5, 12); 
            } 
        }

  • 输出
        A购买了第五期杂志,花费了12.0元。
        B购买了第五期杂志,花费了12.0元。
        C购买了第五期杂志,花费了12.0元。