标签:
GOF:定义了对象之间的“一对多”的依赖关系,这样,当一个对象的状态发生变化时,所有依赖于这个对象的相关对象都被通知并自动更新。
关键:一对多的依赖关系是这个模式的关键,能使多个Observer(观察者)观察到Subject(主题,即被观察者)的变化。这样解决了相互协作的类中间双耦合的问题,Subject不需要知道有哪些Observer存在,而Observer之间也不需要知道对方的存在。
代码(摘自《漫谈设计模式》):
package 设计模式; import static java.lang.Math.abs; import java.util.ArrayList; import java.util.List; /* 定义了对象之间“一对多”的关系,当一个对象发生变化,其他依赖该对象的相关 * 对象都会被通知并自动更新 * Java也提供了观察者模式:java.util.Observable Observer */ public class 观察者模式 { public static void main(String[] args) { Stock stock = new Stock(19f); InstitutionalInvester institutionalInvester = new InstitutionalInvester("Company A", 20f, 18.5f, stock); PrivateInvestor privateInvestor = new PrivateInvestor("John", 20f, 18.9f, stock); stock.setPrice(19.0224f); System.out.println(); stock.setPrice(20.923f); System.out.println(); stock.setPrice(18.823f); System.out.println(); stock.setPrice(19.923f); } } interface StockBuyer { void update(float price); } class Stock { private float price = 0.0f; private float maxGainAndLoss = 0.0f; List<StockBuyer> buyers; public Stock(float price) { this.price = price; buyers = new ArrayList<StockBuyer>(); } public void addBuyer(StockBuyer stockBuyer) { buyers.add(stockBuyer); } public void notifyBuyer() { for (StockBuyer buyer : buyers) buyer.update(price); } public void setPrice(float newPrice) { if(newPrice < 0) { throw new IllegalArgumentException("Price can not be negative"); } float oldPrice = price; price = newPrice; float gainAndLoss = (newPrice-oldPrice) / oldPrice; System.out.printf("Previous price: %g. Current price: %g. Loss/Gain: %g%%. \n", oldPrice, newPrice, gainAndLoss*100); if(abs(gainAndLoss) > maxGainAndLoss) { notifyBuyer(); } } } class InstitutionalInvester implements StockBuyer { private String name; private float maxPrice; private float minPrice; public InstitutionalInvester(String name, float maxPrice, float minPrice, Stock stock) { this.name = name; this.maxPrice = maxPrice; this.minPrice = minPrice; stock.addBuyer(this); } @Override public void update(float price) { if(price > maxPrice) { System.out.printf("%s is selling 100000 stocks...\n", name); } if(price < minPrice) { System.out.printf("%s is buying 20000 shares....\n", name); } } } class PrivateInvestor implements StockBuyer { private String name; private float maxPrice; private float minPrice; public PrivateInvestor(String name, float maxPrice, float minPrice, Stock stock) { this.name = name; this.maxPrice = maxPrice; this.minPrice = minPrice; stock.addBuyer(this); } @Override public void update(float price) { if(price > maxPrice) { System.out.printf("%s is buying 500 stocks...\n", name); } if(price < minPrice) { System.out.printf("%s is selling 1000 shares....\n", name); } } }
其实有两种信息推送的方法,(1)Push方式:Subject发送信息给所有Observer;(2)Pull方式:Observer主动获取Subject的信息。
Java标准库中有java.util.Observable类和java.util.Observer接口来实现观察者模式:
java.util.Observable方法:
PS.一定要先setChanged才能notifyObservers
java.util.Observer只有一个方法:
利用上述两个工具实现代码如下:
package 设计模式; import static java.lang.Math.abs; import java.util.ArrayList; import java.util.List; import java.util.Observable; import java.util.Observer; /* 定义了对象之间“一对多”的关系,当一个对象发生变化,其他依赖该对象的相关 * 对象都会被通知并自动更新 * Java也提供了观察者模式:java.util.Observable Observer */ public class 观察者模式 { public static void main(String[] args) { Stock stock = new Stock(19f); InstitutionalInvester institutionalInvester = new InstitutionalInvester("Company A", 20f, 18.5f, stock); PrivateInvestor privateInvestor = new PrivateInvestor("John", 20f, 18.9f, stock); stock.setPrice(19.0224f); System.out.println(); stock.setPrice(20.923f); System.out.println(); stock.setPrice(18.823f); System.out.println(); stock.setPrice(19.923f); } } class Stock extends Observable{ private float price = 0.0f; private float maxGainAndLoss = 0.0f; public Stock(float price) { super(); this.price = price; } public void setPrice(float newPrice) { if(newPrice < 0) { throw new IllegalArgumentException("Price can not be negative"); } float oldPrice = price; price = newPrice; float gainAndLoss = (newPrice-oldPrice) / oldPrice; System.out.printf("Previous price: %g. Current price: %g. Loss/Gain: %g%%. \n", oldPrice, newPrice, gainAndLoss*100); if(abs(gainAndLoss) > maxGainAndLoss) { setChanged(); notifyObservers(price); } } } class InstitutionalInvester implements Observer { private String name; private float maxPrice; private float minPrice; public InstitutionalInvester(String name, float maxPrice, float minPrice, Stock stock) { this.name = name; this.maxPrice = maxPrice; this.minPrice = minPrice; stock.addObserver(this); } @Override public void update(Observable o, Object arg) { float price = (Float)arg; if(price > maxPrice) { System.out.printf("%s is selling 100000 stocks...\n", name); } if(price < minPrice) { System.out.printf("%s is buying 20000 shares....\n", name); } } } class PrivateInvestor implements Observer { private String name; private float maxPrice; private float minPrice; public PrivateInvestor(String name, float maxPrice, float minPrice, Stock stock) { this.name = name; this.maxPrice = maxPrice; this.minPrice = minPrice; stock.addObserver(this); } @Override public void update(Observable o, Object arg) { float price = (Float)arg; if(price > maxPrice) { System.out.printf("%s is buying 500 stocks...\n", name); } if(price < minPrice) { System.out.printf("%s is selling 1000 shares....\n", name); } } }
标签:
原文地址:http://www.cnblogs.com/programmer-kaima/p/4377119.html