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

    模式介绍

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

    模式优点

    1、定义对象间的一种一对多的依赖关系,当对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
    2、观察者对象和目标对象是抽象低耦合的。

    模式缺点

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

    使用场景

    1、一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
    2、一个对象必须通知其他对象,而并不知道这些对象是谁。
    3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

    系统建模

    1、观察者模式使用三个类Subject、Observer和Client,实现进制转换。
    2、Subject对象带有绑定观察者到Client对象和从Client对象解绑观察者的方法。
    3、创建Subject类、Observer抽象类和扩展了抽象类Observer的实体类。

    系统实现

    import java.util.ArrayList;
    import java.util.List;
    /**
     * 目标对象
     */
    public class Subject {
       private List<Observer> observers = new ArrayList<Observer>();
       private int state;
     
       public int getState() {
          return state;
       }
     
       public void setState(int state) {
          this.state = state;
          notifyAllObservers();
       }
     
       public void attach(Observer observer){
          observers.add(observer);      
       }
     
       public void notifyAllObservers(){
          for (Observer observer : observers) {
             observer.update();
          }
       }  
    }
    
    /**
     * 观察者抽象类
     */
    public abstract class Observer {
       protected Subject subject;
       public abstract void update();
    }
    
    /**
     * 观察者
     */
    public class BinaryObserver extends Observer{ 
       public BinaryObserver(Subject subject){
          this.subject = subject;
          this.subject.attach(this);
       }
     
       @Override
       public void update() {
          System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) ); 
       }
    }
    
    /**
     * 观察者
     */
    public class OctalObserver extends Observer{
       public OctalObserver(Subject subject){
          this.subject = subject;
          this.subject.attach(this);
       }
     
       @Override
       public void update() {
         System.out.println( "Octal String: " + Integer.toOctalString( subject.getState() ) ); 
       }
    }
    
    /**
     * 观察者
     */
    public class HexaObserver extends Observer{
       public HexaObserver(Subject subject){
          this.subject = subject;
          this.subject.attach(this);
       }
     
       @Override
       public void update() {
          System.out.println( "Hex String: " + Integer.toHexString( subject.getState() ).toUpperCase() ); 
       }
    }
    
    /**
     * 客户端
     */
    public class ObserverPatternDemo {
       public static void main(String[] args) {
          Subject subject = new Subject(); 
          HexaObserver hexaObserver = new HexaObserver(subject);
          OctalObserver octalObserver = new OctalObserver(subject);
          BinaryObserver binaryObserver = new BinaryObserver(subject);
          System.out.println("First state change: 15");   
          subject.setState(15);
          System.out.println("Second state change: 10");  
          subject.setState(10);
       }
    }
    结果:
    First state change: 15
    Hex String: F
    Octal String: 17
    Binary String: 1111
    Second state change: 10
    Hex String: A
    Octal String: 12
    Binary String: 1010
    
  • 相关阅读:
    数列分段 II
    Best Cow Fences
    愤怒的牛
    linux 查看文件
    糖果传递
    BL刀片更换主板设置raid
    glance启停
    depot制作
    刀片服务器密码过期, console无法登录解决方案
    DP无法删除失效的多路径链路方法
  • 原文地址:https://www.cnblogs.com/feiqiangsheng/p/12239598.html
Copyright © 2011-2022 走看看