-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathtemplate_method.py
More file actions
107 lines (77 loc) · 3.92 KB
/
Copy pathtemplate_method.py
File metadata and controls
107 lines (77 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
from abc import ABC, abstractmethod
class AbstractClass(ABC):
"""
Абстрактный Класс определяет шаблонный метод, содержащий скелет некоторого
алгоритма, состоящего из вызовов (обычно) абстрактных примитивных операций.
Конкретные подклассы должны реализовать эти операции, но оставить сам
шаблонный метод без изменений.
"""
def template_method(self) -> None:
"""
Шаблонный метод определяет скелет алгоритма.
"""
self.base_operation1()
self.required_operations1()
self.base_operation2()
self.hook1()
self.required_operations2()
self.base_operation3()
self.hook2()
# Эти операции уже имеют реализации.
def base_operation1(self) -> None:
print("AbstractClass says: I am doing the bulk of the work")
def base_operation2(self) -> None:
print("AbstractClass says: But I let subclasses override some operations")
def base_operation3(self) -> None:
print("AbstractClass says: But I am doing the bulk of the work anyway")
# А эти операции должны быть реализованы в подклассах.
@abstractmethod
def required_operations1(self) -> None:
pass
@abstractmethod
def required_operations2(self) -> None:
pass
# Это «хуки». Подклассы могут переопределять их, но это не обязательно,
# поскольку у хуков уже есть стандартная (но пустая) реализация. Хуки
# предоставляют дополнительные точки расширения в некоторых критических
# местах алгоритма.
def hook1(self) -> None:
pass
def hook2(self) -> None:
pass
class ConcreteClass1(AbstractClass):
"""
Конкретные классы должны реализовать все абстрактные операции базового
класса. Они также могут переопределить некоторые операции с реализацией по
умолчанию.
"""
def required_operations1(self) -> None:
print("ConcreteClass1 says: Implemented Operation1")
def required_operations2(self) -> None:
print("ConcreteClass1 says: Implemented Operation2")
class ConcreteClass2(AbstractClass):
"""
Обычно конкретные классы переопределяют только часть операций базового
класса.
"""
def required_operations1(self) -> None:
print("ConcreteClass2 says: Implemented Operation1")
def required_operations2(self) -> None:
print("ConcreteClass2 says: Implemented Operation2")
def hook1(self) -> None:
print("ConcreteClass2 says: Overridden Hook1")
def client_code(abstract_class: AbstractClass) -> None:
"""
Клиентский код вызывает шаблонный метод для выполнения алгоритма. Клиентский
код не должен знать конкретный класс объекта, с которым работает, при
условии, что он работает с объектами через интерфейс их базового класса.
"""
# ...
abstract_class.template_method()
# ...
if __name__ == "__main__":
print("Same client code can work with different subclasses:")
client_code(ConcreteClass1())
print("")
print("Same client code can work with different subclasses:")
client_code(ConcreteClass2())