观察者模式应用广泛,尤其是在一些网络社交应用的推送功能中的应用更是十分广泛;因为这种模式对于此类应用具有先天优势,它能很方便的进行广播;
使用场景主要有:1.一种对象的操作依赖于另一方面的变化
2.更改一个对象是连带需要更改其一些他对象
一句话来说就是广播模型。
java本身内置了观察者模式的接口(java.util下),但在更为复杂的环境中,我们往往要自定义接口,以满足多样的需求。
同时,一个观察者,有时需要观察多个对象,当然,这个是要根据问题具体情况;
以下的demo是个一个观察者观察两个对象--天气,商品,同时通过标记来区别对待观察者
public interface WeatherSubject { public static final int QING = 4; public static final int YU = 1; public static final int QING2YU = 2; public static final int FENG = 3; public static final int ERROR = 0; public void attach(WeatherObserver observer); public void detach(WeatherObserver observer); public void notifyWeatherObserver(); } public interface WeatherObserver { public void updateWeather(WeatherSubject subject); public boolean isInWeatherFlags(int f); } public interface ShopSubject { public static final int ERROR=0; public static final int FOOD=1; public static final int TOOL=2; public static final int BED=3; public void attach(ShopObserver observer); public void detach(ShopObserver observer); public void notifyShopObserver(); } public interface ShopObserver { public void updateShop(ShopSubject subject); public boolean isInShopFlags(int f); } public class ChinaWeatherSubject implements WeatherSubject { List<WeatherObserver> observers = new ArrayList<WeatherObserver>(); String weatherContent; int flag = ERROR; private String calculateWeather() { Random random = new Random(); switch(random.nextInt(5)) { case 1: flag = QING; return "今天,天气晴好"; case 2: flag = YU; return "今天,狂风暴雨"; case 3: flag = QING2YU; return "雨夹雪转晴"; case 4: flag = FENG; return "今天下午,6级大风"; } flag = ERROR; return "获取天气失败"; } public String getWeatherContent() { return weatherContent; } public void setWeatherContent() { this.weatherContent = calculateWeather(); notifyWeatherObserver(); } public void attach(WeatherObserver observer) { observers.add(observer); } public void detach(WeatherObserver observer) { observers.remove(observer); } public void notifyWeatherObserver() { for(WeatherObserver o : observers) { if(o.isInWeatherFlags(flag)) o.updateWeather(this); } } } public class TianMaoShopSubject implements ShopSubject { List<ShopObserver> observers = new ArrayList<ShopObserver>(); String shopContent; int flag = ERROR; private String calculateShop() { Random random = new Random(); switch(random.nextInt(4)) { case 1: flag = BED; return "床上用品"; case 2: flag = FOOD; return "食物"; case 3: flag = TOOL; return "日用工具"; } flag = ERROR; return "获取商品失败"; } public void attach(ShopObserver observer) { observers.add(observer); } public void detach(ShopObserver observer) { observers.remove(observer); } public void notifyShopObserver() { for(ShopObserver o : observers) { if(o.isInShopFlags(flag)) o.updateShop(this); } } public String getShopContent() { return shopContent; } public void setShopContent() { this.shopContent = calculateShop(); notifyShopObserver(); } } public class AppObserver implements WeatherObserver,ShopObserver { String username; List<Integer> weatherFlags = new ArrayList<Integer>(); List<Integer> shopFlags = new ArrayList<Integer>(); public AppObserver(String uname,int[] wFlag,int[] sFlag) { username = uname; setWeatherFlags(wFlag); setShopFlags(sFlag); } public void setWeatherFlags(int[] wFlag) { for(int i=0;i<wFlag.length;i++) { weatherFlags.add(wFlag[i]); } } public void setShopFlags(int[] sFlag) { for(int i=0;i<sFlag.length;i++) { shopFlags.add(sFlag[i]); } } public boolean isInWeatherFlags(int f) { return weatherFlags.contains(f); } public boolean isInShopFlags(int f) { return shopFlags.contains(f); } public void updateWeather(WeatherSubject subject) { System.out.println(username+"收到天气消息 ; 天气情况是:"+((ChinaWeatherSubject)subject).getWeatherContent()); } public void updateShop(ShopSubject subject) { System.out.println(username+"收到商店消息 ; 货物情况是:"+((TianMaoShopSubject)subject).getShopContent()); } } public class ObserverTest { public static void main(String[] args) { ChinaWeatherSubject subject = new ChinaWeatherSubject(); TianMaoShopSubject subject0 = new TianMaoShopSubject(); AppObserver o1 = new AppObserver("凌风",new int[]{ WeatherSubject.FENG, },new int[]{ ShopSubject.BED, }); AppObserver o2 = new AppObserver("雪情",new int[]{ WeatherSubject.QING2YU, },new int[]{ ShopSubject.FOOD, }); AppObserver o3 = new AppObserver("莎莎",new int[]{ WeatherSubject.YU, WeatherSubject.QING2YU, WeatherSubject.QING, WeatherSubject.FENG, },new int[]{ ShopSubject.BED, ShopSubject.FOOD, ShopSubject.TOOL, }); subject.attach(o1); subject.attach(o2); subject.attach(o3); subject0.attach(o1); subject0.attach(o2); subject0.attach(o3); subject.setWeatherContent(); subject0.setShopContent(); } }
运行效果: