设计模式之观察者模式

148 阅读2分钟

当对象之间存在一对多的关系时,一个对象改变,会主动过通知依赖它的对象,依赖它的对象得到通知并作出相应的修改,观察者模式属于行为型模式。这种模式有时候又被称为发布-订阅模式,模型-视图模式。Spring的事件驱动模型是观察者模式很经典的一个应用。

观察者模式常有几个角色,主题Subject角色,它用来保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的方法;观察者Observer角色,有更新自己的方法,收到主题角色的通知后会调用这个方法;事件,一般用来更新主题的数据。

模拟一个场景:一个商店,分别销售苹果和华为的手机,是为subject角色,观察者就是想要买苹果或者华为手机的用户,当手机到货后,subjecct角色改变,分情况通知用户手机到货了。

首先定义一个观察者接口Observe,其中有一个方法buy(),表示手机到货了,可以购买了。

public interface Observer {
    void buy(Subject subject);
}

之后定义一个主题,其中有一个包含许多观察者的list,增加观察者的方法,删除观察者的方法以及通知观察者的方法。这里使用CopyOnWriteArrayList保证线程安全。

public interface Subject {
    List<Observer> list = new CopyOnWriteArrayList<>();

    void addObserve(Observer observer);

    void removeObserve(Observer observer);

    void notifyObserve(Observer observer);
}

定义一个具体的主题,在这个例子里是一个商店,当华为或者苹果手机到货后,通知所有的观察者。

public class Shop implements Subject{
    private int apple;
    private int huawei;

    Shop(int apple, int huawei) {
        this.apple = apple;
        this.huawei = huawei;
    }

    public int getApple() {
        return apple;
    }

    public int getHuawei() {
        return huawei;
    }

    @Override
    public void addObserve(Observer observer) {
        list.add(observer);
    }

    @Override
    public void removeObserve(Observer observer) {
        if (list.size() > 0) {
            list.remove(list.size() - 1);
        }
    }

    @Override
    public void notifyObserve() {
        for (Observer observer : list) {
            observer.buy(this);
        }
    }
}

定义两个观察者,一个是想买苹果的用户,一个是想买华为的用户,收到通知后,可以主动拉取商店的信息。

public class AppleObserver implements Observer{
    @Override
    public void buy(Subject subject) {
        Shop shop = (Shop) subject;
        if (shop.getApple() > 0) {
            System.out.println("苹果用户:又有苹果手机到货啦");
        } else {
            System.out.println("苹果用户:还是没有苹果手机啊");
        }
    }
}

public class HuaweiObserver implements Observer{
    @Override
    public void buy(Subject subject) {
        Shop shop = (Shop) subject;
        if (shop.getHuawei() > 0) {
            System.out.println("华为用户:可以买华为手机啦!");
        } else {
            System.out.println("华为用户:还是没有华为手机啊");
        }
    }
}

测试:

public static void main(String[] args) {
    Shop shop = new Shop(0, 1);
    AppleObserver appleObserver = new AppleObserver();
    HuaweiObserver huaweiObserver = new HuaweiObserver();
    shop.addObserve(appleObserver);
    shop.addObserve(huaweiObserver);
    shop.notifyObserve();
}

7461652376751_.pic.jpg

可以看到,两个观察者都收到了被观察者的通知,并做出相应的行为。