Observer pattern - từ tín hiệu giao thông đến game DOTA2 đình đám - Độ khó 3 sao, độ phổ biến 5 sao - Series Design Patterns

Nội dung bài viết

Video học lập trình mỗi ngày

Observer pattern chính là "super pattern" của design pattern, với pattern này thì nhiều ứng dụng sử dụng có thể thấy khắp nơi từ cuộc sống đến phần mềm, và trong bài viết này chúng ta tiếp tục tìm hiểu về Observer pattern.

Chú ý: Bạn có thể xem video phía trên or ở đây nếu bạn là người mới tìm hiều về Design Patterns.

Giới thiệu về Series học Design patterns

Đây là bài viết thứ 3 trong Series học Design patterns mà tôi đã trình bày. Trước bài viết này thì tôi đã trình bày về Strategy patternVì sao tôi phải học Design patterns và cách học theo bảng công thức. Nếu như các bạn nghiêm túc thì không nên bỏ qua những bài viết trên, vì nó đi theo lộ trình nhất định.

1 - DESIGN PATTERNS | Bạn có dám chắc trả lời được 5 Câu hỏi này không? | Hướng dẫn cách học 23 patterns

2 - Strategy Pattern | Từ thành ROME tới SHOPEE

3 - Observer Pattern | Từ tín hiệu giao thông tới game DOTA

Observer pattern là gì?

Như thường lệ chúng ta đi làm rõ khái niệm về Observer pattern là gì?. Nếu như các bạn theo dõi Tips Javascript lâu rồi thì bạn sẽ biết, tôi muốn đơn giản hóa những định nghĩa mang tính học thuật cao. Cho nên tôi thường đưa những khái niệm đó vào cuộc sống. Nhưng trước tiên hãy xem wiki nói gì về khái niệm này:

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

Theo wiki thì Observer pattern là một trong 23 Design patterns được phát triển dựa trên objectsubject. subject sẽ quan sát (Observer) nếu như object có thay đổi gì thì sẽ thông báo về cho subject.

Đọc xong ở đây, tôi biết có nhiều bạn sẽ không hiểu, chính tôi cũng vậy, khi đọc xong thì tôi chả hiểu gì chính vì thế tôi sẽ có cách truyền đạt lại kiểu khác. Hình dung nó như thế này trong cuộc sống.

Observer pattern trong cuộc sống

Đèn đỏ dừng lại và đèn xanh cho phép đi. Trong cuộc sống tín hiệu giao thông luôn hiện hữu đối với mọi người. Mỗi cá nhân đều phải quan sát và tuân thủ những luật lệ đó và quan sát xem tín hiệu giao thông là màu gì để từ đó quyết định đi hay dừng. Đó chính là Observer pattern.

Cụ thể ở đây mỗi cá nhân chính là subject và tín hiệu giao thông chính là object mà mỗi cá nhân phải quan sát (Observer). Khi một object ở đây là tín hiệu giao thông thay đổi, nó sẽ tự động thông báo cho các đối tượng khác và các đối tượng khác sẽ phản hồi tương ứng.

Trong chế độ Observer pattern , subject đã thay đổi được gọi là mục tiêu quan sát và đối tượng được thông báo được gọi là người quan sát. Mục tiêu quan sát có thể tương ứng với nhiều người quan sát và những người quan sát này có thể không có bất kỳ kết nối lẫn nhau nào và có thể được sử dụng khi cần thiết . Thêm và bớt người quan sát làm cho hệ thống có thể mở rộng hơn.

và quan trọng hơn sau bài này tôi sẽ giới thiệu một khái niệm nâng cao công lực cho các bạn. Đó là Pull or Push của zalo, facebook, instagram..

Đến đây chúng ta sẽ hiểu khái niệm dễ dàng hơn đúng không, tiếp tục vậy phần mềm sẽ được áp dụng như thế nào?

Observer pattern trong ứng dụng phần mềm

Những ai đã từng chơi DOTA2 có lẽ sẽ biết đến tín hiệu ping để anh em đồng đội có thể phát hiện chúng ta gặp nguy hiểm hay bị tấn công khi đi farm. Một khi tôi ping thì tín hiệu đó phát ra và những người chơi sẽ quan sát và ứng cứu. Đó cũng chính là Observer pattern. Vậy triển khai code đó như thế nào, thì ngay bây giờ chúng ta sẽ thử làm một demo sau:

  • Tạo một Observer để quan sát một Subject
class  Observer  {

    constructor(name)  {
        this.namePick  =  name;
    }

    update(location)  {
        this.goToHelp(location);
    }

    goToHelp(location)  {
        console.log(`${this.namePick} ping ::${location}`);
    }
}

Observer dùng để add những nhân vật trong game và lắng nghe đồng đội mình nói gì?? Or cần nhận nhiệm vụ gì

  • Tạo một Subject để phát ra những thông báo quan trọng cho các nhân vật
class  Subject  {

    constructor()  {
        this.observerList  =  []
    }

    addObserver(observer)  {
        this.observerList.push(observer);
    }

    notify(location)  {
        this.observerList.forEach(observer  =>  observer.update(location))
    }
}

Một Subject sẽ có 2 chức năng chính đó là add addObserver những người muốn quan sát vào trong một list. Sau đó sẽ phát thông báo notify cho các đối tượng đó.

  • Sử dụng như sau:
const  subject  =  new  Subject()

// your pick
const  riki  =  new  Observer('Riki')
const  sniper  =  new  Observer('Sniper')

// add riki and sniper to team
subject.addObserver(riki)
subject.addObserver(sniper)

// push location to Team
subject.notify({long:  123,  lat:  106})

Done.

Có thể thấy rõ rằng sử dụng Observer pattern có khi làm hiệu suất giảm: Việc thông báo cho tất cả người đăng ký có thể mất một khoảng thời gian đáng kể nếu việc xử lý quan sát viên trở nên quá phức tạp hoặc nếu có quá nhiều thành viên phụ trách việc thông báo.

Có thể bạn đã bị missing