Java设计模式之--观察者模式(strategy)
概念:
观察者模式是关于多个对象想知道一个对象中数据变化情况的一种成熟模式。观察者模式中有一个称作“主题”的对象和若干个称作“观察者”的对象,“主题”和“观察者”之间是一种一对多的依赖关系。当“主题”的状态发生变化时,所有“观察者”都得到通知。
场景:
类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时,经常会看到RSS图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知你。其实,简单来讲就一句话:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系。
案例,某购物平台,某品牌奶粉,被多个顾客添加关注(降低通知)当商品价格发生变化将受到通知
AbstractSubject类中定义着需要监控的对象列表,可以对其进行修改:增加或删除被监控对象,且当它的子类变化时,负责通知在列表内存在的对象
先来看看类图:
Observer 接口:
public interface Observer {
public void update(String goods,double d);
}
Customer 类
public class Customer implements Observer { public Customer(String name) { setName(name); } public String getName() { return name; } public void setName(String name) { this.name = name; } private String name; @Override public void update(String goods, double d) { System.out.println(String.format("Customer %s received that %s new price:%s", getName(), goods, d)); } }
Subject 接口 管理观察者
public interface Subject { public Subject add(Observer observer); public void remove(Observer observer); public void notifyObservers(); public void change(double value); }
抽象类AbstractSubject 部分实现Subject 接口
public abstract class AbstractSubject implements Subject { private List<Observer> list = new ArrayList<Observer>(); @Override public Subject add(Observer observer) { list.add(observer); return this; } @Override public void remove(Observer observer) { list.remove(observer); } @Override public void notifyObservers() { for (Observer observer : list) { observer.update(getName(), getPrice()); } } public abstract String getName(); public abstract double getPrice(); }
子类商品:
public class Goods extends AbstractSubject { public Goods(String name, double price) { this.name = name; this.price = price; } public void setPrice(double price) { this.price = price; notifyObservers(); } private String name; private double price; @Override public String getName() { return name; } @Override public double getPrice() { return price; } @Override public void change(double value) { setPrice(value); } }
测试类:
public class WorkClass { public void test() { Subject subject = new Goods("某品牌奶粉", 200.0); subject.add(new Customer("李雷")).add(new Customer("韩梅梅")); subject.change(188.0); } }
输出结果:
Customer 李雷 received that 某品牌奶粉 new price:188.0 Customer 韩梅梅 received that 某品牌奶粉 new price:188.0