設計模式之觀察者模式

       設計模式是一套被反覆使用,多數人知曉,通過分類編目的,代碼設計的總結,也能夠說是前人的智慧結晶。學習設計模式能讓咱們對一些應用場景使用相同的套路達到很好的效果,我會不定時更新一些本身
  對設計模式的理解的文章,
從定義,實現,應用場景來講說設計模式,今天我要說的對象是觀察者模式
  一:定義
      觀察者模式是應用最爲普遍的設計模式之一
      觀察者模式定義以下: 觀察者模式(Observer Pattern):定義對象之間的一種一對多依賴關係,使得每當一個對象狀態發生改變時,其相關依賴對象皆獲得通知並被自動更新。觀察者模式的別名包括髮布-訂閱
  (Publish/Subscribe)模式、
模型-視圖(Model/View)模式、源-監聽器(Source/Listener)模式或從屬者(Dependents)模式。觀察者模式是一種對象行爲型模式。
      觀察者模式一般由一下4個成員組成
      1.抽象的主題(Subject),或者稱爲抽象的被觀察者,通常包含一個記錄全部觀察者對象的集合,一個添加觀察者的方法attach(),一個刪除觀察者的方法detach(),一個通知抽象的方法notify().
      2.具體的主題ConcreteSubject,或者被稱爲具體的被觀察者,實現notify方法,有的具體主題還要添加一個狀態
      3.抽象的觀察者Observer,主要提供一個抽象的update方法,有時候還須要和一個具體的主題實例相綁定
      4.具體的觀察者ConcreteObserver,實現update方法,當具體觀察者的狀態變化時,調用這個方法
      
  二:實現
          這裏以直播聊天室爲例子實現觀察者模式,在聊天室中,用戶,服務中心恰好至關於觀察者於觀察的關係,當服務中心的信息有變化的時候,須要通知到全部用戶,這裏以用戶上線和聊天聊個操做爲例子說明問題,
        這裏把用戶的發送和接收兩個操做分紅兩個抽象,被一個觀察者執行,好比用戶須要向服務檯發送登陸操做,發送成功後,其餘聊天室的成功觀察到服務檯的變化,須要進行相應。發送和接收的操做都抽象出來以後,
        後續添加新的功能,好比發送,接收語音
/**
* 抽象主題
*/
abstract class Subjects {

public static List<Observer> observerList = new ArrayList();

/**
* 添加觀察者
*/
public void attach(Observer observer) {
observerList.add(observer);
}

/**
* 移除觀察者
*/
protected void detach(Observer observer) {
observerList.remove(observer);
}

/**
* 通知
*/
public abstract void allNotify(String msg);

}

/**
* 上線操做
*/
class LoginSubject extends Subjects {
/**
* 添加觀察者
*/
@Override
public void attach(Observer observer) {
super.attach(observer);
String msg = observer.getName() + "上線了........";
allNotify(msg);

}

@Override
public void allNotify(String msg) {
LoginDispose loginDispose = new LoginDispose();
for (Observer observer : observerList) {
loginDispose.setMessage(observer.getName() + "收到信息:" + msg);
observer.update(loginDispose);
}
}
}



/**
* 聊天
*/
class ChatSubject extends Subjects {

@Override
public void allNotify(String msg) {
ChatDispose characterDispose = new ChatDispose();
for (Observer observer : observerList) {
characterDispose.setMessage(observer.getName() + "收到信息\n\t\t\t" + msg);
observer.update(characterDispose);
}
}
}


/**
* 抽象觀察者
*/
abstract class Observer {
public String name;
abstract void update(Dispose dispose);
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

/**
* 具體觀察者,用戶
*/
class UserObserver extends Observer {
public UserObserver(String name) {
super.name = name;
}
@Override
void update(Dispose dispose) {
dispose.operation();
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

/**
* 抽象用戶的接收操做
*/
abstract class Dispose {
public String message;

/**
* 抽象操做的方法
*/
abstract void operation();

public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}


/**
* 接收聊天操做的實現
*/
class ChatDispose extends Dispose {
@Override
void operation() {
System.out.println(this.message);
}
}

/**
* 接收接受登陸操做的實現
*/
class LoginDispose extends Dispose {
@Override
void operation() {
System.out.println(this.message);
}
}


/**
* 發送操做的抽象
*/
abstract class Handle {
protected UserObserver userObserver;

/**
* 抽象操做方法
*/
abstract void operation();
}

/**
* 發送聊天操做的實現
*/
class ChatHandle extends Handle {
private String message;

public ChatHandle(UserObserver userObserver, String message) {
this.userObserver = userObserver;
this.message = message;
}

@Override
void operation() {
this.message = userObserver.getName() + "說:" + this.message;
Subjects subject = new ChatSubject();
subject.allNotify(this.message);
}

}


/**
* 測試方法
*/
class test {
public static void main(String[] fdfd) {
/**
* 實例化登陸主題
*/
Subjects loginSubjects = new LoginSubject();
/**
* 歐陽鋒上線
*/
UserObserver ouyangfeng = new UserObserver("歐陽鋒");
loginSubjects.attach(ouyangfeng);

/**
* 洪七公上線
*/
UserObserver hongqigong = new UserObserver("洪七公");
loginSubjects.attach(hongqigong);

/**
* 黃藥師上線
*/
UserObserver huangyaos = new UserObserver("黃藥師");
loginSubjects.attach(huangyaos);

/**
* 一燈大師上線
*/
UserObserver yideng = new UserObserver("一燈大師");
loginSubjects.attach(yideng);

/**
* 歐陽鋒發言
*/
Handle chatHandle = new ChatHandle(ouyangfeng, "今年華山之上,和各位一爭高低");
chatHandle.operation();

}

}

    打印結果:
      

歐陽鋒收到信息:歐陽鋒上線了........
歐陽鋒收到信息:洪七公上線了........
洪七公收到信息:洪七公上線了........
歐陽鋒收到信息:黃藥師上線了........
洪七公收到信息:黃藥師上線了........
黃藥師收到信息:黃藥師上線了........
歐陽鋒收到信息:一燈大師上線了........
洪七公收到信息:一燈大師上線了........
黃藥師收到信息:一燈大師上線了........
一燈大師收到信息:一燈大師上線了........
歐陽鋒收到信息
歐陽鋒說:今年華山之上,和各位一爭高低
洪七公收到信息
歐陽鋒說:今年華山之上,和各位一爭高低
黃藥師收到信息
歐陽鋒說:今年華山之上,和各位一爭高低
一燈大師收到信息
歐陽鋒說:今年華山之上,和各位一爭高低設計模式


  三:應用場景

    在如下狀況下能夠考慮使用觀察者模式:
      (1) 一個抽象模型有兩個方面,其中一個方面依賴於另外一個方面,將這兩個方面封裝在獨立的對象中使它們能夠各自獨立地改變和複用。ide

            (2) 一個對象的改變將致使一個或多個其餘對象也發生改變,而並不知道具體有多少對象將發生改變,也不知道這些對象是誰學習

      (3) 須要在系統中建立一個觸發鏈,A對象的行爲將影響B對象,B對象的行爲將影響C對象……,可使用觀察者模式建立一種鏈式觸發機制。測試

相關文章
相關標籤/搜索