Java 中观察者模式的使用

 在一对多依赖的对象关系中, 如果这个'一'对象状态发生了变化,那么它所有依赖的'多'对象都应该被通知,然后做相应的变化,这就是观察者模式.  就如同'多'对象一直在观察'一'对象的状态变化一样.

      在观察者模式中最重要的俩个对象分别是:Observable和Observer对象.它们的关系可总结如下:

1. Observable和Observer对象是一对多的关系,也就是说一旦Observable对象状态变化,它就要负责通知所有和它有关系的Observer对象,然后做相应的改变.

1. Observable对象不会主动去通知各个具体的Observer对象其状态发生了变化,而是提供一个注册接口供Observer对象使用,任何一个Observer对象如果想要被通知,则可以使用这个接口来注册.

3. 在Observable中有一个集合和一个状态控制开关,所有注册了通知的Observer对象会被保存在这个集合中.这个控制开关就是用来控制Observable是否发生了变化,一旦发生了变化,就通知所有的Observer对象更新状态.

 

在java  api中分别提供了Observable对象:java.util.Observable和Observer接口:java.util.Observer. 下面用实例来实现一下观察者模式: 股票系统

所有的类如下:

 

StockData     (Observable对象,也就是所股票数据发生了变化,它就要通知所有和它有关系的交易实体做相应的变化)

BigBuyer       (Observer对象, 实现了Observer接口)

TradingFool   (Observer对象, 实现了Observer接口)

StockQuote   测试类

在这个例子中一旦StockData对象的状态发生了变化,那BigBuyer和TradingFool都应该受到通知:

 

StockData.java:

 

Java代码   收藏代码
  1. import java.util.Observable;  
  2.   
  3. public class StockData extends Observable  
  4.     {  
  5.     private String symbol;  
  6.     private float close;  
  7.     private float high;  
  8.     private float low;  
  9.     private long volume;  
  10.   
  11.     public StockData()  
  12.         {}  
  13.   
  14.     public String getSymbol()  
  15.         {  
  16.         return symbol;  
  17.         }  
  18.   
  19.     public float getClose()  
  20.         {  
  21.         return close;  
  22.         }  
  23.   
  24.     public float getHigh()  
  25.         {  
  26.         return high;  
  27.         }  
  28.   
  29.     public float getLow()  
  30.         {  
  31.         return low;  
  32.         }  
  33.   
  34.     public long getVolume()  
  35.         {  
  36.         return volume;  
  37.         }  
  38.   
  39.     public void sendStockData()  
  40.         {  
  41.         setChanged();  
  42.         notifyObservers();  
  43.         }  
  44.   
  45.     public void setStockData(String symbol,float close,float high,float low,long volume)  
  46.         {  
  47.         this.symbol = symbol;  
  48.         this.close = close;  
  49.         this.high = high;  
  50.         this.low = low;  
  51.         this.volume = volume;  
  52.         sendStockData();  
  53.         }  
  54.     }  

 

BigBuyer.java:

Java代码   收藏代码
  1. public class BigBuyer implements Observer  
  2.     {  
  3.     private String symbol;  
  4.     private float close;  
  5.     private float high;  
  6.     private float low;  
  7.     private long volume;  
  8.   
  9.     public BigBuyer(Observable observable)  
  10.         {  
  11.         observable.addObserver(this); //注册关系  
  12.         }  
  13.   
  14.     public void update(Observable observable,Object args)  
  15.         {  
  16.         if(observable instanceof StockData)  
  17.             {  
  18.             StockData stockData = (StockData)observable;  
  19.             this.symbol = stockData.getSymbol();  
  20.             this.close = stockData.getClose();  
  21.             this.high = stockData.getHigh();  
  22.             this.low = stockData.getLow();  
  23.             this.volume = stockData.getVolume();  
  24.             display();  
  25.             }  
  26.         }  
  27.   
  28.     public void display()  
  29.         {  
  30.         DecimalFormatSymbols dfs = new DecimalFormatSymbols();  
  31.         DecimalFormat volumeFormat = new DecimalFormat("###,###,###,###",dfs);  
  32.         DecimalFormat priceFormat = new DecimalFormat("###.00",dfs);  
  33.         System.out.println("Big Buyer reports... ");  
  34.         System.out.println("\tThe lastest stock quote for " + symbol + " is:");  
  35.         System.out.println("\t$" + priceFormat.format(close) + " per share (close).");  
  36.         System.out.println("\t$" + priceFormat.format(high) + " per share (high).");  
  37.         System.out.println("\t$" + priceFormat.format(low) + " per share (low).");  
  38.         System.out.println("\t" + volumeFormat.format(volume) + " shares traded.");  
  39.         System.out.println();  
  40.         }  
  41.     }  

 

 TradingFool.java:

Java代码   收藏代码
  1. public class TradingFool implements Observer  
  2.     {  
  3.     private String symbol;  
  4.     private float close;  
  5.   
  6.     public TradingFool(Observable observable)  
  7.         {  
  8.         observable.addObserver(this);//注册关系  
  9.         }  
  10.   
  11.     public void update(Observable observable,Object args)  
  12.         {  
  13.         if(observable instanceof StockData)  
  14.             {  
  15.             StockData stockData = (StockData)observable;  
  16.             this.symbol = stockData.getSymbol();  
  17.             this.close = stockData.getClose();  
  18.             display();  
  19.             }  
  20.         }  
  21.   
  22.     public void display()  
  23.         {  
  24.         DecimalFormatSymbols dfs = new DecimalFormatSymbols();  
  25.         DecimalFormat priceFormat = new DecimalFormat("###.00",dfs);  
  26.         System.out.println("Trading Fool says... ");  
  27.         System.out.println("\t" + symbol + " is currently trading at $" + priceFormat.format(close) + " per share.");  
  28.         System.out.println();  
  29.         }  
  30.     }  

 

StokeQuote.java

Java代码   收藏代码
  1. public class StockQuotes  
  2.     {  
  3.     public static void main(String[] args)  
  4.         {  
  5.         System.out.println();  
  6.         System.out.println("-- Stock Quote Application --");  
  7.         System.out.println();  
  8.   
  9.         StockData stockData = new StockData();  
  10.   
  11.         // register observers...  
  12.         new TradingFool(stockData);  
  13.         new BigBuyer(stockData);  
  14.   
  15.         // generate changes to stock data...  
  16.         stockData.setStockData("JUPM",16.10f,16.15f,15.34f,(long)481172);  
  17.         stockData.setStockData("SUNW",4.84f,4.90f,4.79f,(long)68870233);  
  18.         stockData.setStockData("MSFT",23.17f,23.37f,23.05f,(long)75091400);  
  19.         }  
  20.     }  

 

在测试类中我们可以看到俩个Observer对象都注册了Observable对象,而当Observable对象发生改变时,这俩个Observable对象就会做相应的更新了, 运行结果如下:

Java代码   收藏代码
  1. Big Buyer reports...   
  2.     The lastest stock quote for JUPM is:  
  3.     $16.10 per share (close).  
  4.     $16.15 per share (high).  
  5.     $15.34 per share (low).  
  6.     481,172 shares traded.  
  7.   
  8. Trading Fool says...   
  9.     JUPM is currently trading at $16.10 per share.  
  10.   
  11. Big Buyer reports...   
  12.     The lastest stock quote for SUNW is:  
  13.     $4.84 per share (close).  
  14.     $4.90 per share (high).  
  15.     $4.79 per share (low).  
  16.     68,870,233 shares traded.  
  17.   
  18. Trading Fool says...   
  19.     SUNW is currently trading at $4.84 per share.  
  20.   
  21. Big Buyer reports...   
  22.     The lastest stock quote for MSFT is:  
  23.     $23.17 per share (close).  
  24.     $23.37 per share (high).  
  25.     $23.05 per share (low).  
  26.     75,091,400 shares traded.  
  27.   
  28. Trading Fool says...   
  29.     MSFT is currently trading at $23.17 per share.  

我们通过Observable源码可以看到,其实Observable对象不关心具体的Observer的实例类型. 只要是实现了Observer接口的Observer对象都可以得到通知,这就为我们如果想要对模型进行扩展提供了方便,使Observable对象和Observer对象实现了松耦合. 如果我们需要添加一个新的Observer对象时,我们只要注册一下,当Observable对象发生变化时就可以得到通知,而不要做其他任何改变,非常方便.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
观察者模式是一种常见的设计模式,它的主要思想是在对象之间建立一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 在Java观察者模式的实现需要定义两个角色:Subject(主题)和Observer(观察者)。Subject负责维护一组观察者对象,以及通知它们状态的变化;而Observer则负责接收Subject的通知,并做出相应的处理。 下面是一个简单的Java实现: ```java import java.util.ArrayList; import java.util.List; // 主题接口 interface Subject { void attach(Observer observer); // 添加观察者 void detach(Observer observer); // 移除观察者 void notifyObservers(); // 通知所有观察者 } // 观察者接口 interface Observer { void update(); // 更新状态 } // 具体主题类 class ConcreteSubject implements Subject { private List<Observer> observers = new ArrayList<>(); public void attach(Observer observer) { observers.add(observer); } public void detach(Observer observer) { observers.remove(observer); } public void notifyObservers() { for (Observer observer : observers) { observer.update(); } } // 主题状态的变化 public void changeState() { // do something notifyObservers(); // 通知所有观察者 } } // 具体观察者类 class ConcreteObserver implements Observer { private String name; public ConcreteObserver(String name) { this.name = name; } public void update() { System.out.println(name + " has received the update."); } } // 测试 public class ObserverPatternDemo { public static void main(String[] args) { Subject subject = new ConcreteSubject(); Observer observer1 = new ConcreteObserver("Observer1"); Observer observer2 = new ConcreteObserver("Observer2"); Observer observer3 = new ConcreteObserver("Observer3"); subject.attach(observer1); subject.attach(observer2); subject.attach(observer3); ((ConcreteSubject) subject).changeState(); subject.detach(observer2); ((ConcreteSubject) subject).changeState(); } } ``` 在这个例子,我们定义了Subject和Observer两个接口,以及它们的具体实现类ConcreteSubject和ConcreteObserver。其ConcreteSubject负责维护一组观察者对象,并在状态变化时通知它们;而ConcreteObserver则负责接收Subject的通知,并做出相应的处理。 在测试代码,我们创建了一个ConcreteSubject对象,并向它添加了三个ConcreteObserver观察者。然后我们调用changeState()方法改变主题的状态,这会触发ConcreteSubject通知所有观察者。最后我们移除了一个观察者,并再次调用changeState()方法,这时只有两个观察者会收到通知。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值