> For the complete documentation index, see [llms.txt](https://jen-hsuan-hsieh.gitbook.io/design-pattern/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jen-hsuan-hsieh.gitbook.io/design-pattern/chapter2_guan_cha_zhe_mo_shi__observer_pattern.md).

# Chapter2: 觀察者模式 (Observer Pattern)

## This section contain the following items:

* 1.Observer Pattern
* 2.Observer Pattern Example: ItemController

## 1.Observer Pattern

* 觀察者模式要解決的問題:
  * 1.資料使用者或資料顯示者必須定期去取得最新資料, 而不是資料更新時通知更新
  * 2.實作上, 每當有新的項目要取得就必須改寫code
  * 3.實作上, 是針對具體物件實踐而不是介面
  * 4.在runtime時也無法新增或移除顯示項目
* 因此要如何解決以上問題呢? 就是利用觀察者模式
  * 主題 + 觀察者 = 觀察者模式 (以下圖片引用<深入淺出設計模式>)

![](/files/-M4M0Ln7qF99Pkj21Rev)

* 每當觀察者所定閱的主題有更新, 觀察者就會收到該物鍵的最新狀態
  * 當主題更新時觀察者們都會被通知, 彼此之間是被訂閱者與訂閱者的關係, 也就是說當被訂閱者改變狀態，其他訂閱者都會收到通知並自動被更新
* 一旦訂閱者解除訂閱便不會再收到通知
  * 示意圖如下 (以下圖片引用<深入淺出設計模式>)

![](/files/-M4M0Ln9dcNIBlHnrXTn)

* 角色(以下圖片引用<深入淺出設計模式>)
  * 主題物件 (Subject): 須實作以下功能
    * registerOberver()
    * removeOberver()
    * notifyOberver()
  * 觀察者 (Observer): 須實作以下功能
    * update()

![](/files/-M4M0LnBto7S6fXnJRPQ)

* 觀察者模式的優點
  * 1.們可在任何時間加入觀察者
  * 2.當加入/移除觀察者時不需要修改主題物件
  * 3.主題物件及觀察者皆是可以被重複使用的
  * 4.主題物件及觀察者的改變皆不會影響到彼此

    **2.Observer Pattern Example: ItemController**
* 1.需求
  * ItemController是MOXA Auto E-test Program的一環
  * 如下圖所示, ItemController為整個program的stage 1
  * 為滿足產品開發時的功能測試,stage 1要能達到以下的需求:

    * 1.可以遠端測試機器 (remote control)
    * 2.可以讓使用者編輯/擴充test case
    * 3.可以排程, 依序進行每個test case
    * 4.server端及client端皆可以產生簡單的test report並回傳

    ![](/files/-M4M0LnDdDMFAkFEUkGz)
* 2.軟體架構設計
  * ItemController的設計, 會在每一個test case的測試上都會喚起server, client
  * server, client即是Subject Object, 每一次test case的測試結束後所產生的report將會傳送給Observers
  * 因此架構中
    * 有一個IUser
      * Server, Client必須implement IUser
    * 有一個IOberver
      * Observer必須implement IObserver

![](/files/-M4M0LnFfz6whhM8_nw-)

* 3.程式碼解析
  * 當程式一執行, 會create Server, Client兩個物件, 並將TestItem.ini裡面所記載的觀察者名單依序註冊
  * IOberser

    ```
    public interface IObserver
    {
      string DefaultDrive { get; set; }
      string DefaultFolder { get; set; }
      string IP { get; set; }
      string Name { get; set; }
      string Password { get; set; }
      int GetTestReport(IUser user);
    ```

    }
  * IUser

    ```
    public interface IUser
    {
      string DefaultDrive{get;set;}
      string DefaultFolder { get; set; }
      string IP { get; set; }
      string Name { get; set; }
      string Password { get; set; }
      string TimeStamp { get; set; }
      string LogFileName { get; set; }
      string MachineName { get; set; }
      int returnValue { get; set; }
      List<string> TestReportsName { get; set; }
      List<string> TestItems { get; set; }
      List<string> Script { get; set; }
      int SetTestItems(ref List<string> testItems);
      int RunTestScript(int testItemNumber);
      void StartThread(object data);
      int WaitThread();
      int RegisterObserver(IObserver observer);
      int RemoveObserver(IObserver observer);
      int NotifyObservers();
    ```

    }


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://jen-hsuan-hsieh.gitbook.io/design-pattern/chapter2_guan_cha_zhe_mo_shi__observer_pattern.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
