觀察者設計模式定義了對象間的一種一對多的組合關系,以便一個對象的狀態發生變化時,所有依賴於它的對象都得到通知並自動刷新。
發布者發布信息,訂閱者獲取信息,訂閱了就能收到信息,沒訂閱就收不到信息。
- 抽象被觀察者角色:也就是一個抽象主題,它把所有對觀察者對象的引用保存在一個集合中,每個主題都可以有任意數量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者角色。一般用一個抽象類和接口來實現。
- 抽象觀察者角色:為所有的具體觀察者定義一個接口,在得到主題通知時更新自己。
- 具體被觀察者角色:也就是一個具體的主題,在集體主題的內部狀態改變時,所有登記過的觀察者發出通知。
- 具體觀察者角色:實現抽象觀察者角色所需要的更新接口,一邊使本身的狀態與制圖的狀態相協調。
java實現:
抽象被觀察者(抽象主題):Observable.java
抽象被觀察者的具體實現(主題服務):ObservableImpl.java
抽象觀察者(用戶(訂閱者)的抽象):Observer.java
抽象觀察者的具體實現(用戶(訂閱者)具體實現):User.java
Observable.java(被訂閱服務的實現)
/** * @ClassName Observerable 被觀察者(被訂閱的對象抽象) * @Description TODO * @author jxd * @Date 2018年9月11日 上午10:15:33 * @version 1.0.0 */ public interface Observable { //注冊用戶 public void registerUser(Observer observer); //移除用戶 public void removeUser(Observer observer); //通知觀察者 public void notifyObserver(); } |
ObservableImpl.java(被訂閱服務的實現)
/** * @ClassName ObservableImpl 抽象被觀察者(主題服務)的具體實現 * @Description TODO * @author jxd * @Date 2018年9月11日 下午1:58:42 * @version 1.0.0 */ public class ObservableImpl implements Observable { private List<Observer> userList = new ArrayList<>();; private String message; @Override public void registerUser(Observer observer) { // TODO Auto-generated method stub userList.add(observer); } @Override public void removeUser(Observer observer) { // TODO Auto-generated method stub if (observer != null && userList != null && userList.size() > 0) { userList.remove(observer); } } @Override public void notifyObserver() { // TODO Auto-generated method stub userList.forEach(x -> { x.getTopicNotification(message); }); } public void setInformation(String str){ this.message=str; notifyObserver(); } } |
Observer.java(訂閱者的抽象)
/** * @ClassName Observer 抽象觀察者(需要訂閱主題的用戶) * @Description TODO * @author jxd * @Date 2018年9月11日 上午10:16:49 * @version 1.0.0 */ public interface Observer { /** * @Description (得到主題(訂閱對象)返回的通知) * @param message */ public void getTopicNotification(String message); } |
User.java(訂閱對象的實現)
public class User implements Observer { private String name; private String message; public User(String name) { this.name = name; } @Override public void getTopicNotification(String message) { // TODO Auto-generated method stub this.message = message; read(); } public void read() { System.out.println(name + ":" + "收到消息內為:" + message); } } |
測試。。。。。。。。。。
public static void main(String[] args) { Observer z=new User("jinxudong"); Observer s = new User("jinxudong1"); Observer e = new User("jinxudong2"); ObservableImpl wechatServer=new ObservableImpl(); wechatServer.registerUser(s); wechatServer.registerUser(z); wechatServer.registerUser(e); wechatServer.setInformation("發布第一次消息..."); System.out.println("-------------------測試取消關注 -------"); wechatServer.removeUser(z); wechatServer.setInformation("發布第二次消息..."); } 測試結果: jinxudong1:收到消息內為:發布第一次消息... jinxudong:收到消息內為:發布第一次消息... jinxudong2:收到消息內為:發布第一次消息... -------------------測試取消關注 ------- jinxudong1:收到消息內為:發布第二次消息... jinxudong2:收到消息內為:發布第二次消息... |