您的位置:首页 > 其它

5.偏头痛杨的常见设计模式入门系列之观察者模式篇

2017-10-25 18:08 232 查看
前戏

我超级无敌喜欢京东上的一款耳机,但就是太贵了,我想再等等,等到降价,于是我关注了这款耳机,当耳机降价时,
京东会主动给我发短信或邮件,而不用我每天都登录去查看是否降价了,我是被动方,京东是主动方,

我是观察者,被动接受通知。
耳机是被观察者,主动发送通知给观察者。

什么是观察者模式
观察者模式分为两种角色,观察者&被观察者。
一个&多个观察者对象同时监听&观察一个被观察者对象(主题&目标)对象。
被观察者对象的状态上发生变化时,会通知所有观察者对象,使他们能够自动更新。

实现观察者模式
观察者侧需要有接受通知的功能,而被观察者侧则有注册&注销观察者、通知观察者的功能。

观察者接口,或使用java.util.Observer

public interface Observer {
    /**
     * 被通知
     * @param arg
     */
    public void
notify(Object arg);
}

邮件观察者

public class MailObserver
implements Observer{
    @Override
    public void notify(Object arg) {
        System.out.println("mail已经知道了变动..."+arg);
    }
}

手机观察者

public class PhoneObserver
implements Observer
{
    @Override
    public void notify(Object arg) {
        System.out.println("phone已经知道了变动..."+arg);
    }
}

被观察者父类(如果没有父类则需要每个被观察者都写这些方法,或使用java.util.Observable线程安全)

 public class Observable {
    /**
     *
观察者列表,以后可以改造成这个list放在缓存里等等
     */
    List<Observer>
observerList
= new ArrayList<Observer>();
    /**
     *
注册观察者
     */
    public void
registerObserver(Observer observer){
        observerList.add(observer);
    }
    /**
     *
注销观察者
     */
    public void
unRegisterObeserver(Observer observer){
        observerList.remove(observer);
    }
    /**
     *
通知所有观察者
     */
    public void
notifyObservers(Object arg){
        for(Observer observer : observerList){
            observer.notify(arg);
        }
    }
}

被观察者

public class Product
extends Observable{
    private double price;
    private String name;
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
       
//通知观察者们的trigger。
        super.notifyObservers(price);
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
        super.notifyObservers(name);
    }
}

测试主函数

public static void main(String[] args) {
        //实例化被观察者
        Product p = new Product();
        //实例化2个观察者
        PhoneObserver phoneObserver = new PhoneObserver();
        MailObserver mailObserver = new MailObserver();
        // 注册观察者,这个步骤可以放到Product的构造中去,或者抽出去,不用每个对象每次都注册。
        p.registerObserver(phoneObserver);
        p.registerObserver(mailObserver);
        p.setName("张三");
        //触发价格变动通知
        p.setPrice(15);
        // 注销观察者
        p.unRegisterObeserver(mailObserver);
        System.out.println("------------删除观察者之后--------------------");
        p.setName("张三");
        //触发价格变动通知
        p.setPrice(15);
        // 好处是我可以动态的增加&删除观察者。不用强依赖,强耦合,随时增删观察者。。。
    }

我可以动态的增加&删除观察者。“观察”并不是直接调用,不用强依赖,强耦合,随时增删观察者。
观察者不用主动去轮询被观察者有没有变动,而是被动响应。

总结
观察者模式与消息队列中的生产者与消费者是不是似曾相似呢?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: