Nội dung
Decorator là một mẫu cấu trúc cho phép thêm động các hành vi mới vào các đối tượng bằng cách đặt chúng bên trong các đối tượng bọc đặc biệt.
Sử dụng decorator, có thể bọc các đối tượng vô số lần vì cả đối tượng đích và decorator đều tuân theo cùng một giao diện. Kết quả đối tượng sẽ nhận được một hành vi xếp chồng của tất cả các wrapper.
Cách sử dụng mẫu
Sử dụng: Decorator khá chuẩn trong mã Pyhon, đặc biệt là trong mã liên quan đến luồng.
Nhận dạng: Decorator có thể được nhận dạng bởi các hàm tạo hoặc phương thức khởi tạo chấp nhận các đối tượng của cùng một lớp hoặc giao diện như lớp hiện tại.
Chương trình mẫu
main.py
class Component():
"""
Giao diện Component cơ sở xác định các hoạt động có thể được thay đổi bởi
decorator.
"""
def operation(self) -> str:
pass
class ConcreteComponent(Component):
"""
Concrete Component cung cấp các triển khai mặc định của các hoạt động.
Có thể có một số biến thể của các lớp này.
"""
def operation(self) -> str:
return "ConcreteComponent"
class Decorator(Component):
"""
Lớp Decorator cơ sở tuân theo giao diện tương tự như các thành phần khác.
Mục đích chính của lớp này là xác định giao diện bao bọc cho tất cả các Concrete
Component. Việc triển khai mặc định của mã wrap có thể bao gồm một trường
để lưu trữ một component được bọc và phương tiện để khởi tạo nó.
"""
_component: Component = None
def __init__(self, component: Component) -> None:
self._component = component
@property
def component(self) -> str:
"""
Decorator ủy quyền cho tất cả các component được bao bọc.
"""
return self._component
def operation(self) -> str:
return self._component.operation()
class ConcreteDecoratorA(Decorator):
"""
Concrete Decorator gọi đối tượng được bọc và thay đổi kết quả của nó
theo một cách nào đó.
"""
def operation(self) -> str:
"""
Decorator có thể gọi việc thực thi của hoạt động cha, thay vì gọi trực
tiếp đối tượng được bao bọc. Cách tiếp cận này đơn giản hóa việc
mở rộng các lớp decorator.
"""
return f"ConcreteDecoratorA({self.component.operation()})"
class ConcreteDecoratorB(Decorator):
"""
Decorator có thể thực hiện hành vi của chúng trước hoặc sau lời gọi
đến một đối tượng được bao bọc.
"""
def operation(self) -> str:
return f"ConcreteDecoratorB({self.component.operation()})"
def client_code(component: Component) -> None:
"""
Client hoạt động với tất cả các đối tượng bằng giao diện Component.
Bằng cách này, nó có thể độc lập với các lớp cụ thể của các thành phần
mà nó hoạt động cùng.
"""
# ...
print(f"RESULT: {component.operation()}", end="")
# ...
if __name__ == "__main__":
# Bằng cách này, client có thể hỗ trợ cả hai component đơn giản...
simple = ConcreteComponent()
print("Client: I've got a simple component:")
client_code(simple)
print("\n")
# ...cũng như decorator.
#
# Lưu ý cách decorator có thể bọc không chỉ các component
# đơn giản mà còn cả các decorator khác.
decorator1 = ConcreteDecoratorA(simple)
decorator2 = ConcreteDecoratorB(decorator1)
print("Client: Now I've got a decorated component:")
client_code(decorator2)
Kết quả
Client: I've got a simple component:
RESULT: ConcreteComponent
Client: Now I've got a decorated component:
RESULT: ConcreteDecoratorB(ConcreteDecoratorA(ConcreteComponent))
Để lại một bình luận