所有設計模式傳送門
本文將一起介紹學習下設計模式之觀察者模式。觀察者模式是關於多個對象想知道一個對象中數據變化情況的一種成熟的模式。觀察者模式包括四種角色:
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設計模式》