今天你訂閱了一個喜歡的 YouTube 頻道,這個頻道一旦有新影片發布,你就會收到通知。不需要你反覆檢查頻道是否有新內容,所有更新自動發送到你手上。在軟體開發中,我們常常需要處理這樣的情境,當一個物件的狀態發生變化時,其他相關物件需要自動更新,並做出相應的回應。這種情境下我們就可以運用觀察者模式 Observer Pattern。
什麼是觀察者模式?
觀察者模式是一種行為設計模式,它定義了一種一對多的依賴關係,當一個物件(被觀察者)發生改變時,所有依賴它的物件(觀察者)都會自動收到通知並更新自己。這讓系統中的物件之間能夠鬆散耦合,保持靈活性和可維護性。
觀察者模式在 YouTube 訂閱的應用
在這個範例中,我們將 YouTube 頻道視為「被觀察者」,訂閱該頻道的使用者則是「觀察者」。當頻道有新影片上傳時,所有訂閱者都會自動收到通知。讓我們用 C++ 來實踐這個概念。
我們定義一個 Observer
介面,所有的觀察者(訂閱者)都要實作這個介面。1
2
3
4
5class Observer {
public:
virtual void update(const std::string& videoTitle) = 0;
virtual ~Observer() = default;
};
接著我們定義一個 Subject
介面,讓被觀察者(YouTube 頻道)管理觀察者的訂閱和通知。1
2
3
4
5
6
7class Subject {
public:
virtual void addObserver(std::shared_ptr<Observer> observer) = 0;
virtual void removeObserver(std::shared_ptr<Observer> observer) = 0;
virtual void notifyObservers() = 0;
virtual ~Subject() = default;
};
接下來我們實作一個具體的 YouTubeChannel
類別,這個類別代表 YouTube 頻道,當有新影片發布時,它會通知所有的訂閱者。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25class YouTubeChannel : public Subject {
private:
std::list<std::shared_ptr<Observer>> subscribers;
std::string latestVideo;
public:
void addObserver(std::shared_ptr<Observer> observer) override {
subscribers.push_back(observer);
}
void removeObserver(std::shared_ptr<Observer> observer) override {
subscribers.remove(observer);
}
void notifyObservers() override {
for (const auto& observer : subscribers) {
observer->update(latestVideo);
}
}
void uploadNewVideo(const std::string& videoTitle) {
latestVideo = videoTitle;
notifyObservers();
}
};
最後我們可以定義多個觀察者來代表不同的訂閱者,他們會在接收到新影片通知時,顯示影片的標題。1
2
3
4
5
6
7
8
9
10
11
12class Subscriber : public Observer {
private:
std::string name;
public:
Subscriber(const std::string& name) : name(name) {}
void update(const std::string& videoTitle) override {
std::cout << name << " received notification: "
<< videoTitle << std::endl;
}
};
當我們將 Subscriber
加入 YouTubeChannel
的訂閱者清單時,頻道一旦上傳新影片,所有的訂閱者都會自動收到通知。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15int main() {
YouTubeChannel channel;
std::shared_ptr<Subscriber> alice = std::make_shared<Subscriber>("Alice");
std::shared_ptr<Subscriber> bob = std::make_shared<Subscriber>("Bob");
channel.addObserver(alice);
channel.addObserver(bob);
channel.uploadNewVideo("First Video");
channel.removeObserver(bob);
channel.uploadNewVideo("Second Video");
return 0;
}
執行上述程式碼,我們會得到以下輸出:1
2
3Alice received notification: First Video
Bob received notification: First Video
Alice received notification: Second Video
這個範例中使用了觀察者模式來模擬 YouTube 訂閱系統。當 YouTube 頻道上傳新影片時,所有的訂閱者都會自動收到通知。這讓我們的系統能夠更靈活地應對訂閱和通知的需求。
觀察者模式的優點
以這個例子來說,使用觀察者模式降低了耦合度,訂閱者和 YouTube 頻道之間的關係是鬆散的,YouTube 頻道不需要知道實際上是誰訂閱了它,它只需要通知所有訂閱者,這讓系統更容易擴展跟維護。
同時也具備擴展性,你可以輕鬆地新增或移除訂閱者,而不需要修改 YouTube 頻道的程式碼。
總結
觀察者模式是一種常見的設計模式,能有效處理多個物件之間的通知和更新需求。在我們生活中無所不在,例如:股票價格變化時,關注該股票的投資者都會收到通知,天氣變化時,訂閱天氣服務的使用者都會收到更新,電子報發布時,訂閱的讀者也會收到信件。下次你在設計系統時,如果遇到一對多的依賴關係,並且希望它們能夠自動更新的情況,不妨試試觀察者模式!