java设计模式:观察者模式

观察者模式(View Pattern)对象之间多对一依赖的一种解决方案,被依赖的对象称之为Subject,依赖的对象称之为Observer,Subject通知Observer变化。

观察者模式就相当于咱们现实生活中的订牛奶业务以及订报纸业务等,用户就是那个Observer,牛奶公司或者报纸公司就是那个Subject,属于多对一的依赖关系。

Subject提供登记注册、移除、通知的方法

Observer负责接收输入


为了方便理解,这里就用订牛奶的业务来演示观察者模式的原理

1、Subject接口

public interface Subject {
    void addObserver(Observer observer); //登记
    void deleteObserver(Observer observer); //删除
    void notifyObservers(); //通知(拉取的方式,只通知Observer有更新,具体数据由Observer自己拉取)
    void notifyObservers(Object object); //通知(推送的方式,将具体数据推送给用户)
}

2、Observer接口

public interface Observer {
    void update(Object object);
}

3、Subject实现类(牛奶公司)

public class MilkEnterprise implements Subject {

    private Milk milk;
    private Set<Observer> set = new HashSet<>();

    @Override
    public void addObserver(Observer observer) {
        if(!set.contains(observer))
            set.add(observer);
    }

    @Override
    public void deleteObserver(Observer observer) {
        if(set.contains(observer))
            set.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : set) {
            observer.update(null);
        }
    }

    @Override
    public void notifyObservers(Object object) {
        Milk milk = (Milk) object;
        for (Observer observer : set) {
            observer.update(milk);
        }
    }

    //设置更新数据
    public void setData(Object object) {
        this.milk = (Milk) object;
        notifyObservers(this.milk);
    }

}

4、Observer实现类(用户)

public class User1 implements Observer {

    @Override
    public void update(Object object) {
        System.out.println("-----user1获取到更新----------");

        Milk milk = (Milk) object;
        //获取牛奶公司推送来的消息(这里只做简单的展示)
        System.out.println("最新牛奶品种:" +milk.getType());
        System.out.println("最新牛奶价格:" +milk.getPrice());
    }
}
public class User2 implements Observer {
    @Override
    public void update(Object object) {
        System.out.println("-----user2获取到更新----------");

        Milk milk = (Milk) object;
        //获取牛奶公司推送来的消息(这里只做简单的展示)
        System.out.println("最新牛奶品种:" +milk.getType());
        System.out.println("最新牛奶价格:" +milk.getPrice());
    }
}

5、数据实体类(牛奶)

public class Milk {
    private String type;    //牛奶品种
    private float price;    //牛奶价格

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public Milk(String type, float price) {
        this.type = type;
        this.price = price;
    }
}

6、测试类

public class MainTest {
    public static void main(String[] args){
        MilkEnterprise enterprise = new MilkEnterprise();
        enterprise.addObserver(new User1()); //登记用户1到牛奶公司
        enterprise.addObserver(new User2());//登记用户2到牛奶公司
        enterprise.setData(new Milk("酸奶",66.0f)); //牛奶公司有新牛奶出品
    }
}

输出结果:

-----user2获取到更新----------
最新牛奶品种:酸奶
最新牛奶价格:66.0
-----user1获取到更新----------
最新牛奶品种:酸奶
最新牛奶价格:66.0


由此结果我们可以看出观察者模式中,添加的顺序和最终通知的顺序是先进后出即类似栈的方式。


java中也有自己内置的观察者模式,Observable(class类,即被依赖者Subject),Observer(接口,即依赖者Observer),可是该内置的观察者模式有缺陷,即Observable不是接口而是class类,这就有java单继承的限制,所以具体使用时需具体分析场景灵活使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值