Mẫu thiết kế - Hướng dẫn nhanh về mẫu Observer.

Mẫu quan sát là một mẫu rất được sử dụng. Trong thực tế, nó phổ biến đến mức đang được chuẩn hóa trong nhiều ngôn ngữ / thư viện lập trình. Trong Java, nó tồn tại tiêmava.util.Observer (không dùng nữa trong Java 9). Trong Python nó gần giống như apip cài đặt trình quan sát mẫu. Trong C ++, đôi khi chúng ta có thể sử dụng thư viện boost, chính xác hơn là #include . Tuy nhiên, nó được sử dụng rộng rãi trong công nghiệp như một giải pháp tùy chỉnh. Để có thể sử dụng nó một cách chính xác và hiểu được sự phức tạp của nó, chúng ta cần phải đi sâu vào và khám phá nó.

Mẫu quan sát được phân loại trong số các mẫu thiết kế hành vi. Các mẫu thiết kế hành vi được quan tâm cụ thể nhất với giao tiếp giữa các lớp / đối tượng. [bởi Mẫu thiết kế giải thích đơn giản]

Một mô hình quan sát là gì? Ngoài một màn hình đi bộ phát sóng truyền hình tương tự (như trong hình). Mục đích của mô hình là nhằm xác định mối quan hệ một-nhiều để khi một đối tượng thay đổi trạng thái, các đối tượng khác sẽ được thông báo và cập nhật tự động. Chính xác hơn, nó muốn được thông báo về các sự kiện xảy ra trong hệ thống. Hãy đặt các mảnh của câu đố với nhau trong ba bước.

Bước 1 - Từ khóa

Xác định từ khóa là công thức bí mật trong loạt hướng dẫn nhanh này. Phương pháp này đã giúp tôi thực sự hiểu các mẫu thiết kế, mã hóa chúng trong tâm trí và hiểu được sự khác biệt giữa các mẫu thiết kế khác.

  1. Chủ đề: Nó được coi là người giữ thông tin, dữ liệu hoặc logic kinh doanh.
  2. Đăng ký / Đính kèm: Người quan sát tự đăng ký vào chủ đề vì họ muốn được thông báo khi có thay đổi.
  3. Sự kiện: Các sự kiện đóng vai trò kích hoạt trong chủ đề sao cho tất cả các quan sát viên được thông báo.
  4. Thông báo: Tùy thuộc vào cách triển khai, đối tượng có thể đẩy thông tin của người dùng đến các nhà quan sát, hoặc, người quan sát có thể kéo kéo ra nếu họ cần thông tin từ đối tượng.
  5. Cập nhật: Người quan sát cập nhật trạng thái của họ một cách độc lập với người quan sát khác tuy nhiên trạng thái của họ có thể thay đổi tùy thuộc vào sự kiện được kích hoạt.

Bước 2 - Sơ đồ

Hãy chia thiết kế này thành các lớp khác nhau để đơn giản hóa điều này một chút.

  • ConcreteObservers là các lớp chứa thông tin cụ thể cho thể hiện hiện tại. Hàm cập nhật được gọi bởi hoạt động chủ đề notify notify (). Các nhà quan sát cập nhật độc lập dựa trên trạng thái hiện tại của họ.
  • Người quan sát là lớp cha của người quan sát cụ thể. Nó chứa một ví dụ chủ đề. Khi một người quan sát được khởi tạo, nó đăng ký / tự gắn vào đối tượng.
  • Lớp Chủ đề có một danh sách hoặc một tập hợp các quan sát viên. Khi một sự kiện được kích hoạt, nó gọi hoạt động notify () lặp qua tất cả các trình quan sát bằng cách gọi hàm cập nhật của chúng.

Bước 3 - Mã theo ví dụ

Tôi sẽ đề nghị sao chép lớp mã theo lớp từ kho lưu trữ git của tôi nó để quan sát đầu ra. Sau đó đọc các bình luận hoặc mô tả dưới đây. Hãy dành thời gian của bạn, đọc nó kỹ lưỡng (có nghĩa là một phút, không ít hơn và không nhiều hơn).

Ví dụ: Hãy xem xét một trò chơi bóng đá. Nhiều người ủng hộ đang theo dõi trận đấu. Chúng tôi chia những người ủng hộ thành hai loại theo độ tuổi, trẻ và già. Khi nhóm của họ ghi được một mục tiêu, những người ủng hộ phản ứng khác nhau tùy theo độ tuổi và mức độ phấn khích của họ.
Bây giờ, hãy để nói chuyện với các thuật ngữ được sử dụng cho mẫu người quan sát:

  • Trò chơi là chủ đề và những người ủng hộ là những người quan sát.
  • Tất cả các quan sát viên được đính kèm / đăng ký vào chủ đề và họ được thông báo khi đội bóng đá của họ ghi bàn (sự kiện kích hoạt là nếu đội của họ ghi bàn).
  • Các nhà quan sát cập nhật hành vi của họ tùy thuộc vào thông báo nhận được.

Môn học
Đối với lớp học này, chúng tôi cần truy cập vào một danh sách các nhà quan sát. Khi các nhà quan sát sắp đăng ký, họ gọi hàm theattach (cái này) để tự thêm vào danh sách có sẵn (đây là ví dụ của người quan sát). Khi một sự kiện được kích hoạt wenotify () tất cả các nhà quan sát để cập nhật độc lập trạng thái của họ. Trong ví dụ này, kích hoạt là nếu đội bóng đá quan sát viên ghi bàn.

#inc loại 
#include 
sử dụng không gian tên std;
Lớp học {
    vector  quan sát viên;
    bool ghi bàn; // kích hoạt, sự kiện
công cộng:
    // đăng ký quan sát viên
    void đính kèm (Người quan sát * obs) {
        observers.push_back (obs);
    }
   
   // Đây là SỰ KIỆN
   // đặt if nếu được ghi và thông báo cho TẤT CẢ người quan sát
   void setScored (bool Score) {
      điểm = Điểm;
      thông báo ();
   }
bool getScored () {
      trả lại điểm;
   }
   // thông báo hiện thực là tiếp tục xuống
   // để tập lệnh biên dịch và chạy
   void thông báo ();
};

Người quan sát
Lớp này phụ thuộc vào chủ đề mà nó được đăng ký. Khi các quan sát viên cụ thể được khởi tạo, họ sẽ tự gắn vàoSubject. Trong ví dụ này, trạng thái của mỗi người quan sát là sự phấn khích của anh ấy.

quan sát lớp
{
    Chủ đề * subj;
    int phấn khíchLevel; // tiểu bang
  công cộng:
    Người quan sát (Chủ đề * mod, int excLevel)
    {
        subj = mod;
        phấn khíchLevel = excLevel;
        // Người quan sát đăng ký / đính kèm với Chủ đề
        subj-> đính kèm (này);
    }
    cập nhật khoảng trống ảo () = 0;
  được bảo vệ:
    Chủ đề * getSubject () {
       trả lại subj;
    }
    void setExcitementLevel (int excLevel) {
       phấn khíchLevel = excLevel;
    }
    int getExcitementLevel () {
       trở lại phấn khíchLevel;
    }
};

Đây là khai báoSubject :: notify () và như chúng tôi đã đề cập trước khi công việc của nó là thông báo cho tất cả các nhà quan sát để cập nhật trạng thái của họ.

void Tiêu đề :: notify () {
  for (int i = 0; i  update ();
}

Quan sát bê tông
Các quan sát viên cụ thể kế thừa từ lớp Người quan sát và tất cả chúng phải có chức năng cập nhật. Trong ví dụ này, các nhà quan sát cụ thể được phân biệt giữa những người ủng hộ trẻ và già. Nếu mức độ phấn khích của họ quá cao, những người ủng hộ lớn tuổi có nguy cơ bị đau tim và những người trẻ tuổi có nguy cơ uống rượu và lái xe. Trạng thái của họ cập nhật độc lập vì chúng tôi sẽ chứng minh trong chức năng chính bên dưới.

class Old_ConcittleObserver: Public Observer
{
   công cộng:
     // Gọi hàm tạo cha mẹ để đăng ký với chủ đề
     Old_ConcittleObserver (Chủ đề * mod, int div)
        : Người quan sát (mod, div) {}
     // Dành cho người lớn tuổi, nếu mức độ phấn khích
     // là hơn 150 họ có nguy cơ bị đau tim
     cập nhật khoảng trống ()
     {
        bool points = getSubject () -> getScored ();
        setExcitementLevel (getExcitementLevel () + 1);
        if (đã ghi && getExcitementLevel ()> 150)
        {
          cout << "Đội của Old Observer đã ghi bàn !!"
               << "Mức độ phấn khích của anh ấy là"
               << getExcitementLevel ()
               << "coi chừng đau tim!" << kết thúc;
        } khác {
          cout << "Đội không ghi bàn. Yeeeih không có gì phải lo lắng cả"
               << kết thúc;
        }
    } // cập nhật kết thúc ()
};
class Young_ConcittleObserver: Public Observer
{
   công cộng:
     // Gọi hàm tạo cha mẹ để đăng ký với chủ đề
     Young_ConcittleObserver (Chủ đề * mod, int div)
       : Người quan sát (mod, div) {}
     // Dành cho người lớn tuổi, nếu mức độ phấn khích
     // là hơn 100 họ có nguy cơ bị đau tim
     cập nhật khoảng trống ()
     {
        bool points = getSubject () -> getScored ();
        setExcitementLevel (getExcitementLevel () + 1);
        if (đã ghi && getExcitementLevel ()> 100)
        {
          cout << "Đội của Young Observer đã ghi bàn !!"
               << "Mức độ phấn khích của anh ấy là"
               << getExcitementLevel ()
               << "không uống và lái xe !!" << kết thúc;
        } khác {
          cout << "Đội không ghi bàn. Yeeh không có gì phải lo lắng cả"
               << kết thúc;
       }
    } // cập nhật kết thúc ()
};

Chức năng chính
Các quan sát viên cụ thể tự đăng ký vào thể hiệnSubject. Trạng thái của họ là mức độ phấn khích là tham số thứ hai. Khi sự kiện được kích hoạt, subj.setScored (true), thìSubject :: notify () được gọi để cập nhật các quan sát viên đã đăng ký. Trong kịch bản dưới đây, chúng tôi có ba người quan sát, youngObs1is quá mức và có nguy cơ uống rượu và lái xe, oldObs1is cũng thể hiện quá mức một nguy cơ khác nhau (đau tim). Cuối cùng, youngObs2, người cũng trẻ như người đầu tiên, không có gì phải lo lắng vì anh ta không quá mức.

Điều quan trọng cần lưu ý là ba nhà quan sát được cập nhật độc lập dựa trên trạng thái của họ (mức độ phấn khích) và loại của họ (trẻ hay già).
int chính () {
   Chủ đề phụ;
   Young_ConcittleObserver youngObs1 (& subj, 100);
   Old_ConcittleObserver oldObs1 (& subj, 150);
   Young_ConcittleObserver youngObs2 (& subj, 52);
   subj.setScored (đúng);
}
// Đầu ra
// Đội của Young Observer đã ghi bàn !! Mức độ phấn khích của anh ấy là 101
// không uống và lái xe !!
// Đội của Old Observer đã ghi bàn !! Mức độ phấn khích của anh ấy là 151 chiếc
// hết đau tim! Đội không ghi bàn.
// Yeeh không có gì phải lo lắng

Có một vài lợi ích cho việc sử dụng mẫu Observer và một vài điểm cần lưu ý khi mẫu này được tiếp cận [Học các mẫu thiết kế Python].

  • Mẫu Observer cung cấp một thiết kế trong đó Chủ thể và Người quan sát được ghép lỏng lẻo. Chủ đề không cần biết về lớp ConcreteObserver. Bất kỳ Observer mới có thể được thêm vào bất cứ lúc nào. Không cần sửa đổi Chủ đề khi Người quan sát mới được thêm vào. Người quan sát và chủ thể không bị trói buộc và độc lập với nhau, do đó, những thay đổi trong Chủ thể hoặc Người quan sát sẽ không ảnh hưởng lẫn nhau.
  • Không có tùy chọn cho thành phần, vì giao diện Observer có thể được khởi tạo.
  • Nếu Observer bị sử dụng sai, nó có thể dễ dàng thêm độ phức tạp và dẫn đến các vấn đề về hiệu suất.
  • Thông báo có thể không đáng tin cậy và có thể dẫn đến tình trạng chủng tộc hoặc sự không nhất quán.

Blog tiếp theo sẽ là một hướng dẫn nhanh về mẫu thiết kế Cầu. Đó là một mẫu thiết kế cấu trúc được sử dụng khá nhiều trong ngành. Đừng quên thích / vỗ tay vào bài đăng trên blog của tôi và theo dõi tài khoản của tôi. Điều này là để mang lại cho tôi sự hài lòng khi tôi giúp một số nhà phát triển đồng nghiệp và thúc đẩy tôi tiếp tục viết. Nếu có một mẫu thiết kế cụ thể mà bạn muốn tìm hiểu thì hãy cho tôi biết để tôi có thể cung cấp cho bạn trong tương lai.

Hướng dẫn nhanh khác về các mẫu thiết kế:

  1. Mẫu thiết kế - Hướng dẫn nhanh về Nhà máy trừu tượng.
  2. Mẫu thiết kế - Hướng dẫn nhanh về Mẫu cầu.
  3. Mẫu thiết kế - Hướng dẫn nhanh về Mẫu xây dựng.
  4. Mẫu thiết kế - Hướng dẫn nhanh về Mẫu trang trí.
  5. Mẫu thiết kế - Hướng dẫn nhanh về Mẫu mặt tiền.
  6. Mẫu thiết kế - Hướng dẫn nhanh về Mẫu quan sát.
  7. Mẫu thiết kế - Hướng dẫn nhanh về Mẫu đơn.