所有设计模式传送门
本文将一起介绍学习下设计模式之观察者模式。观察者模式是关于多个对象想知道一个对象中数据变化情况的一种成熟的模式。观察者模式包括四种角色:
1、主题(Subject):主题是一个接口,该接口规定了具体主题需要实现的方法,比如添加、删除观察者以及通知观察者更新数据的方法。
2、观察者(Observer):观察者是一个接口,该接口规定了具体观察者用来更新数据的方法。
3、具体主题(ConcreteSubject): 具体主题是实现主题接口类的一个实例,该实例包含有可以经常发生变化的数据。具体主题实现一个集合,比如 ArrayList,存放观察者的引用,以便数据发生变化时,通知具体观察者。
4、具体观察者(ConcreteObserver): 具体观察者是实现 观察者接口类的一个实例.具体观察者包含有可以存放 具体主题引用的主题接口变量,以便具体观察者让具体主题将自己的引用 添加到具体主题的集合中,使自己成为它的观察者,或让这个具体主题将自己的引用从具体主题的集合中删除,使自己不再是它的观察者。
简单的例子:一家商店每天都发布打折商品的名字、原价和折扣后的价格,有两位顾客对此感兴趣,但是一位顾客只关心打折商品的名称,并不关心原价和折扣后的价格,而另一位顾客只关心商品的原价和打折后的价格,并不关心商品的名称。
/** * 主题接口类 */
public interface Subject {
public void addObserver(Observer o);
public void deleteObserver(Observer o);
public void notifyObservers();
}
/**
* 观察者接口
*/
public interface Observer {
public void update();
}
/**
* 具体主题-商店
*
* 商店并不清楚它的观察者是否对打折商品的全部信息都感兴趣,
* 所以采用拉数据方式通知顾客。
*/
public class ShopSubject implements Subject{
String goodsName; //商品名称
double oldPrice; //原价
double newPrice; //现价
ArrayList<Observer> customerList; //存放对观察者的引用
public ShopSubject() {
customerList = new ArrayList<Observer>();
}
public void addObserver(Observer o) {
if (!customerList.contains(o)) {
customerList.add(o);
}
}
public void deleteObserver(Observer o) {
if (customerList.contains(o)) {
customerList.remove(o);
}
}
public void notifyObservers() {
for (int i = 0; i < customerList.size(); i++) {
Observer observer = customerList.get(i);
observer.update();
}
}
/**
* 设置打折商品
* @param name 商品名称
* @param oldP 原价
* @param newP 现价
*/
public void setDiscountGoods(String name,double oldP,double newP) {
goodsName = name;
oldPrice = oldP;
newPrice = newP;
notifyObservers(); //通知所有观察者
}
//提供获取商品属性的方法
public String getGoodsName() {
return goodsName;
}
public double getOldPrice() {
return oldPrice;
}
public double getNewPrice() {
return newPrice;
}
}
/**
* 具体观察者
*
* 顾客1
*/
public class CustomerOne implements Observer{
Subject subject;
double oldPrice;
double newPrice;
String personName;
public CustomerOne(Subject subject,String personName) {
this.personName = personName;
this.subject = subject;
subject.addObserver(this);
}
public void update() {
if (subject instanceof ShopSubject) {
oldPrice = ((ShopSubject) subject).getOldPrice();
newPrice = ((ShopSubject) subject).getNewPrice();
System.out.println(personName + "只对商品价格感兴趣,");
System.out.println("原价是:" + oldPrice);
System.out.println("现价是:" + newPrice);
}
}
}
/**
* 具体观察者
*
* 顾客2
*/
public class CustomerTwo implements Observer{
Subject subject;
String goodsName;
String personName;
public CustomerTwo(Subject subject,String personName) {
this.subject = subject;
this.personName = personName;
subject.addObserver(this);
}
public void update() {
if (subject instanceof ShopSubject) {
goodsName = ((ShopSubject) subject).getGoodsName(); //调用具体主题提供的方法
System.out.println(personName + "只对打折的商品感兴趣:");
System.out.println("打折的商品是:" + goodsName);
}
}
}
**
* 观察者模式
*
* 拉数据方式的简单例子
*
* 一家商店每天都发布打折商品的名字、原价和折扣后的价格,有两位顾客对此感兴趣,
* 但是一位顾客只关心打折商品的名称,并不关心原价和折扣后的价格,而另一位顾客
* 只关心商品的原价和打折后的价格,并不关心商品的名称
*/
public class Application {
public static void main(String[] args) {
ShopSubject shop = new ShopSubject();
CustomerOne boy = new CustomerOne(shop,"小李");
CustomerTwo girl = new CustomerTwo(shop,"小红");
shop.setDiscountGoods("华为P20", 3788, 3698);
// /shop.setDiscountGoods("补水面膜", 68, 48);
}
}
运行结果:
参考书籍:《Java设计模式》