--- tags: Behavioral Patterns --- # 觀察者模式 Observer "定義了物件之間的一對多關係,當一個物件改變狀態,其他相依者都會收到通知並自動被更新。" *Define a "one-to-many" dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.* 觀察者模式的設計守則: 1. 設計時,盡量讓需要互動的物件之間關係鬆綁。 2. 主題只知道觀察者有實作特定介面 (也就是 Observer 介面)。 3. 任何時候都可以加入新的觀察者。 4. 有新型態的觀察者出現時, 主題的程式碼不用修改。 5. 片面改變主題或觀察者,並不會影響另一方。  ### **程式說明** 以下為主題介面 ```java= pubilc interface Subject { public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObservers(); } ``` 以下為觀察者介面 ```java= public interface Observer { public void update(String content); } ``` 以下為報社去實作主題介面 ```java= public class NewspaperOffice implements Subject() { // 使用 List 來記錄所有訂閱者 List mObservers; // 報紙內容 String mContent; public NewspaperOffice() { mObservers = new ArrayList(); mContent = ""; } public void sendNewspaper(String content) { mContent = content; notifyObservers(); } @Override public void registerObserver(Observer o) { mObservers.add(o); } @Override public void removeObserver(Observer o) { int i = mObservers.indexOf(0); if(i > 0) mObservers.remove(i); } @Override public void notifyObservers() { for(int i = 0; i < mObservers.size(); i++) { Observer o = mObservers.get(i); o.update(mContent); } } } ``` 以下為顧客去實作觀察者介面 ```java= public class Customer implements Observer { // 訂閱者名稱 String mName; public Customer(String name) { mName = name; } @Override public void update(String content) { System.out.println(name + "get newspaper: " + content); } } ``` 從Main方法中可以輕易地看出"一旦主題有改變時,可以用來通知所有觀察者"。 ```java= public class Test { public static void main(String[] args) { // 建立報社 NewspaperOffice office = new NewspaperOffice(); // 訂閱者 Tom Customer Tom = new Customer("Tom"); // 訂閱者 Peter Customer Peter = new Customer("Peter"); // 訂閱者訂報紙 office.registerObserver(Tom); office.registerObserver(Peter); // 報社送報紙囉 office.sendNewspaper("Newspaper 1..."); // Tom 不想訂報紙了 office.removeObserver(Tom); office.sendNewspaper("Newspaper 2..."); } } ``` > [name=YuanChangLee]
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up