設計模式 - 觀察者模式 (Behavioral Patterns - Observer Pattern)
前言
觀察者(Observer Pattern) 定義
- 創造一對多的連結(Subject-Observer),當被綁定的物件狀態變動的話,則通知其他物件
- 可以保護物件不做內部破壞去通知其他物件執行功能,可以透過觀察者封裝此物件執行通知
我們只要設想,觀察者就是一個廣播機制,Subject是負責廣播的而和他同個頻道(Observer)都可以接收到他的廣播,在Observer Pattern使用物件導向(多形、封裝)的方法去實踐他
類別圖
- 創建Subject介面負責和Observer關聯
- Observer主要透過Subject的觸發,接收更動的訊息
範例
英雄遊戲中適合使用Observer Pattern(觀察者模式),非遊戲地圖莫屬。我們現在的遊戲業務內容是,每一張地圖都需要排隊,玩家可以訂閱此地圖(若是當地圖開放的時候(沒人在裡面)就會通知玩家)
- 設計MapSubject負責發送通知的內容
- 將地圖繼承MapSubject擴充發送通知的方法
- 設計UserObserver負責接收通知內容
- 將User繼承UserObserver擴充收通知的方法
import java.util.ArrayList;
import java.util.List;
abstract class MapSubject {
private String mapId;
public MapSubject(String mapId) {
this.mapId = mapId;
}
private List<MapObserver> observers = new ArrayList<>();
public void addObserver(MapObserver mapObserver) {
observers.add(mapObserver);
}
public void notifyChange() {
for (MapObserver mapObserver : observers) {
mapObserver.update(mapId);
}
};
}
class MapDetail extends MapSubject {
public MapDetail(String mapId) {
super(mapId);
}
public void openMap() {
notifyChange();
}
}
abstract class MapObserver {
abstract void update(String mapId);
}
class UserMapObserver extends MapObserver {
private User user = null;
public UserMapObserver(User user) {
this.user = user;
}
@Override
public void update(String mapId) {
user.joinMap(mapId);
}
}
class User {
String name = null;
public User(String name) {
this.name = name;
}
public void joinMap(String map) {
System.out.println(name + " get a notify from : " + map + " map");
}
}
public class Observer {
public static void main(String[] args) {
User userA = new User("UserA");
User userB = new User("UserB");
UserMapObserver userMapObserver = new UserMapObserver(userA);
UserMapObserver userMapObserverB = new UserMapObserver(userB);
MapDetail map = new MapDetail("Jungle");
map.addObserver(userMapObserver);
map.addObserver(userMapObserverB);
map.notifyChange();
}
}
結論
- Observer Pattern(觀察者模式)用途在於若有一項物件,再更改狀態時可以通知需要被知道的物件
- 透果兩種抽象物件之間的方法做通知(Subject & Observer)
留言
張貼留言