Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decorator Pattern #18

Open
tuananhhedspibk opened this issue Dec 27, 2023 · 0 comments
Open

Decorator Pattern #18

tuananhhedspibk opened this issue Dec 27, 2023 · 0 comments

Comments

@tuananhhedspibk
Copy link
Owner

tuananhhedspibk commented Dec 27, 2023

Problem

Giả sử bạn có một class Notifier với method send, method này chỉ gửi message đi mà thôi, thế nhưng bạn còn muốn nhiều hơn thế, thay vì chỉ gửi message bạn còn muốn gửi

  • Mail
  • Tin nhắn slack
  • Tin nhắn facebook
  • ...

Một cách giải quyết đơn giản đó là extends từ class Notifier thành các classes:

  • FacebookNotifier
  • SlackNotifier
  • ...

Thế nhưng cách làm này có một nhược điểm có thể thấy rõ đó là việc nó sẽ làm tăng số lượng classes lên một cách "đáng kể".

Solution

  1. Việc kế thừa không giúp chúng ta có thể thay đổi hoặc chỉnh sửa behavior của obj tại runtime. Mà ta chỉ có thể thay thế toàn bộ object mà thôi.
  2. Thông thường các ngôn ngữ OOP chỉ cho phép đơn kế thừa (1 subclass extend 1 parentClass only).

Một cách giải quyết ở đây đó là Aggregation hoặc Composition, bản thân 1 object sẽ kết tập từ nhiều objects thuộc về các classes khác, từ đó "chuyển tiếp - delegate" công việc cho các classes kia.

Screenshot 2023-12-27 at 23 11 41

Có thể mô tả pattern này trong 1 từ đó là "Wrapper", khái niệm wrapper ở đây sẽ được hiểu như việc một object có thể "link" tới các target objects khác. Wrapper thường delegate các requests mà nó nhận được (trong thực tế thì wrapper có thể chỉnh sửa kết quả hoặc param sau hoặc trước khi delegate cho các target objects).

Bản thân các wrapper cũng sẽ implements các interface giống như các objects được "bao" bên trong wrapper, từ phương diện của client thì các objects này là như nhau.

Các decorator sẽ bao lấy nhau thành 1 stack, stack cuối cùng sẽ được sử dụng bởi client. Do các decorator đều implement 1 interface nên client code sẽ không quan tâm tới việc đó là "pure" object hay là một decorator.

Screenshot 2023-12-28 at 22 46 54

Screenshot 2023-12-28 at 23 00 04

Structure

Screenshot 2023-12-28 at 23 01 22

Pros

  1. Có thể mở rộng object behavior mà không cần tạo subclass
  2. Có thể thêm chức năng cho object ở runtime
  3. Có thể kết hợp các behaviors lại bằng cách wrap một object với nhiều decorators.

Cons

  1. Khó có thể loại bỏ một wrapper khỏi wrapper stack.
  2. Khó có thể triển khai một decorator theo cách mà các behaviors của nó không phụ thuộc vào thứ tự của decorators stack.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant