Mở đầu

Trong nội dung bài viết trước, mình đã giới thiệu khá cụ thể về kiến thiết Pattern cùng rất 2 lấy ví dụ như về Factory Pattern. Ở nội dung bài viết này bọn họ cùng tiếp tục mày mò về 1 pattern khá phổ biến trong PHP chính là Observer

Observer là gì?

Định nghĩa

Mình xin được trích dẫn 1 đoạn trong biểu lộ của Wikipedia về observer

The observer pattern is a software design pattern in which an object, called the subject, maintains a menu of its dependents, called observers, và notifies them automatically of any state changes, usually by calling one of their methods.

Bạn đang xem: Observer là gì

Có thể hiểu Observer thuộc nhóm pattern Behavioral là một trong mẫu thiết kế dành cho việc một đối tượng người dùng khi biến đổi trạng thái của phiên bản thân nó thì các đối tượng đính kèm theo cũng trở thành được thông báo. Vào trường hòa hợp của EDP, một đối tượng người tiêu dùng phát nổ (trigger) lên một sự kiện, thì các listener được lắp kèm đã lắng nghe và thực hiện (nếu có).

Tưởng tượng giống như việc 1 đo lường và thống kê hay 1 ông công ty gửi thông tin cho nhân viên của chính mình làm gì đó, giỏi điều gì đấy tương tự chũm và tất nhiên vị đo lường này cũng có thể "nghỉ chơi" hoặc điều thêm một nhân viên, cũng rất có thể là "cho đi nghỉ mát" toàn thể (facepalm).Chúng ta sẽ tò mò kỹ rộng qua ví dụ dưới đây.

Cấu trúc

*

Sơ vật dụng 1 mẫu mã Observer

Mô hình cơ bạn dạng của 1 chủng loại Observer thường bao gồm 4 nguyên tố sau.

Subject

Ở trên đây subject được phát âm như "ông chủ" mà tôi đã đề cập, 1 interface với các phương thức

attach điều thêm một nhân viên mang lại làm việc (attach observer object)detach rút 1 nhân viên cấp dưới đi địa điểm khác (detach observer object)notify thông báo cho toàn cục nhân viên có tác dụng 1 câu hỏi gì đó (notify observer update)

Observer

Cũng là một interface được có mang với method update, cách làm này vẫn nhận thay đổi mỗi khi tất cả notify tự Subject

ConcreteSubject

Nhiệm vụ là lưu trữ status của các ConcreteObserver objects cùng từ các state này sẽ gửi đi thông báo mỗi khi state bị nắm đổi

setState optional - phối state mang lại SubjectgetState optional - rước state lúc này của Subject

ConcreteObserver

Luôn duy trì 1 reference đến một ConcreteSubjectCần phải tàng trữ state cân xứng với state của SubjectImplements phương thức update của Observer nhằm state luôn đồng bộ với state của Subject (sử dụng mỗi khi có notify)

Ví dụ

Giả sử mỗi lần có fan đăng nhập vào hệ thống, chúng ta sẽ ghi log hoặc báo là fan đó mới đăng nhập với block ip nếu như user đó là chưa hợp lệ. Hoặc sẽ check nếu tài khoản hết hạn thì đã gửi e-mail thông báo...

Như vậy, họ sẽ làm cho 1 lấy ví dụ và tại đây mình sẽ vận dụng với quy mô Account login cùng với Logger và Mailer, Security, cụ thể như sau.

Flow

ConcreteSubject (Account) sẽ thông tin tới tất cả các observers(Logger với Mailer, Security) bất cứ khi nào có một user tiến hành đăng nhập.Sau khi thừa nhận được thông tin rằng bao gồm user đăng nhập và điện thoại tư vấn tới update, những ConcreteObserver (Logger và Mailer, Security ) đang sử dụng dữ liệu từ ConcreteSubject và lấy state để xử lý.

Xem thêm: Tên Miền Camera Ddns Là Gì ? Ứng Dụng Chi Tiết Của Ddns Dns Động Có Ý Nghĩa Gì

Bước 1

Tạo SubjectObserver

Observer

interface Observerpublic function update();Subjectinterface Subjectpublic function attach(Observer $observer);public function detach(Observer $observer);public function notify();

Bước 2

Tạo ConcreteSubject implements Subject tạo thành ở trên, mình đặt tên là Account

class trương mục implements Subjectconst LOGIN_SUCCESS = 1;const LOGIN_FAILURE = 2; const LOGIN_IVALID = 3; const EXPIRED = 4;private $state;private $storage; private $data;public function __construct()$this->storage = array();$this->data = array(); // Attach 1 Observerpublic function attach(Observer $observer)$isContain = array_search($observer, $this->storage); if ($isContain === false) $this->storage<> = $observer; // Xóa 1 Observer thoát khỏi danh sáchpublic function detach(Observer $observer) foreach($this->storage as $key => $val) if ($val == $observer) unset($this->storage<$key>); // Gửi thông báo update tới toàn bộ các observers trong khối hệ thống public function notify() foreach($this->storage as $observer) $observer->update($this); public function login($email, $ip) $this->setData(< "email" => $email, "ip" => $ip >); if ($email == "" && $ip == "10.0.0.1") $this->setState(Account::LOGIN_INVALID) else $login = $this->process($email); if ($login) $this->setState(Account::LOGIN_SUCCESS); else $this->setState(Account::LOGIN_FAILURE); $this->notify(); public function save() $this->notify(); public function setState($state) $this->state = $state; public function getState() return $this->state; public function process($email) if ($email == "") return true; return false; public function setData($data) $this->data = $data; public function getData() return $this->data;

Bước 3

Tạo những ConcreteSubject

Logger

class Logger implements Observer public function update(Account $account) $state = $account->getState(); $data = $account->getData() if ($state == Account::LOGIN_SUCCESS) // tiến hành log thời hạn user online blahh.. Echo "User $data<"email"> vừa online"; Mailer

class Security implements Observer public function update(Account $account) $state = $account->getState(); $data = $account->getData(); if ($state == Account::LOGIN_INVALID) // Block ip echo "Account $data<"email"> with ip $data<"ip"> are trying to mod our system";

Bước 5

Chạy demo thôi

// Include các classinclude ...$account = new Account();//Attach những observer vào subject$security = new Security();$account->attach(new Logger());$account->attach(new Mailer());$account->attach($security);// Đăng nhập$account->login("", "192.168.0.1");// chuyển đổi state$account->setState(Account::EXPIRED);$account->save();$account->login("", "10.0.0.1");// Xóa security observer$account->detach($security);$account->login("", "10.0.0.1"); //will successOutput

> User vừa online> tài khoản has expired. Thư điện tử sent!> tài khoản with ip 10.0.0.1 aretrying to gian lận our systemKếtNhư vậy là vẫn tìm hiểu hoàn thành về Observer với cách áp dụng trong PHP, nếu không dùng PHP các bạn vẫn rất có thể áp dụng theo phong cách xây dựng tương tự như mình sẽ bài viết liên quan về những pattern thông dụng hơn ở tất cả ngôn ngữ và share lại vào các nội dung bài viết tiếp theo.

Nguồn tham khảoSách kiến thiết Patterns Elements of Reusable Object-oriented softwareFeedback

Trong quá trình tìm hiểu có thể còn sai sót, khôn cùng mong chúng ta nếu thấy điều gì không đúng trong nội dung bài viết xin vui lòng bình luận lại nhằm mình sửa đổi và cải thiện trong các nội dung bài viết sau. Cảm ơn!