首页 > 开发 > JAVA > 正文

java设计模式:区别对待的观察者模式

2016-04-17 21:52:12  来源:慕课网

观察者模式应用广泛,尤其是在一些网络社交应用的推送功能中的应用更是十分广泛;因为这种模式对于此类应用具有先天优势,它能很方便的进行广播;
使用场景主要有: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();
}
}

运行效果: