mirror of
https://github.com/rjNemo/design-patterns
synced 2026-06-06 02:26:40 +00:00
add code example
This commit is contained in:
parent
eb37c2ddc3
commit
16bd6a2d1a
3 changed files with 107 additions and 0 deletions
57
behavioral/template/abstract_class.py
Normal file
57
behavioral/template/abstract_class.py
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
class AbstractClass(ABC):
|
||||
"""
|
||||
The Abstract Class defines a template method that contains a skeleton of
|
||||
some algorithm, composed of calls to (usually) abstract primitive
|
||||
operations.
|
||||
|
||||
Concrete subclasses should implement these operations, but leave the
|
||||
template method itself intact.
|
||||
"""
|
||||
|
||||
def template_method(self) -> None:
|
||||
"""
|
||||
The template method defines the skeleton of an algorithm.
|
||||
"""
|
||||
|
||||
self.base_operation1()
|
||||
self.required_operations1()
|
||||
self.base_operation2()
|
||||
self.hook1()
|
||||
self.required_operations2()
|
||||
self.base_operation3()
|
||||
self.hook2()
|
||||
|
||||
"""These operations already have implementations."""
|
||||
|
||||
def base_operation1(self):
|
||||
print("AbstractClass says: I am doing the bulk of the work")
|
||||
|
||||
def base_operation2(self):
|
||||
print("AbstractClass says: But I let subclasses override some operations")
|
||||
|
||||
def base_operation3(self):
|
||||
print("AbstractClass says: But I am doing the bulk of the work anyway")
|
||||
|
||||
"""These operations have to be implemented in subclasses."""
|
||||
|
||||
@abstractmethod
|
||||
def required_operations1(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def required_operations2(self):
|
||||
pass
|
||||
|
||||
"""
|
||||
These are "hooks." Subclasses may override them, but it's not mandatory since the hooks already have default (but
|
||||
empty) implementation. Hooks provide additional extension points in some crucial places of the algorithm.
|
||||
"""
|
||||
|
||||
def hook1(self):
|
||||
pass
|
||||
|
||||
def hook2(self):
|
||||
pass
|
||||
29
behavioral/template/concrete_classes.py
Normal file
29
behavioral/template/concrete_classes.py
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
from behavioral.template.abstract_class import AbstractClass
|
||||
|
||||
|
||||
class ConcreteClass1(AbstractClass):
|
||||
"""
|
||||
Concrete classes have to implement all abstract operations of the base
|
||||
class. They can also override some operations with a default implementation.
|
||||
"""
|
||||
|
||||
def required_operations1(self):
|
||||
print("ConcreteClass1 says: Implemented Operation1")
|
||||
|
||||
def required_operations2(self):
|
||||
print("ConcreteClass1 says: Implemented Operation2")
|
||||
|
||||
|
||||
class ConcreteClass2(AbstractClass):
|
||||
"""
|
||||
Usually, concrete classes override only a fraction of base class' operations.
|
||||
"""
|
||||
|
||||
def required_operations1(self):
|
||||
print("ConcreteClass2 says: Implemented Operation1")
|
||||
|
||||
def required_operations2(self):
|
||||
print("ConcreteClass2 says: Implemented Operation2")
|
||||
|
||||
def hook1(self):
|
||||
print("ConcreteCLass2 says: Overridden Hook1")
|
||||
21
behavioral/template/main.py
Normal file
21
behavioral/template/main.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
from behavioral.template.abstract_class import AbstractClass
|
||||
from behavioral.template.concrete_classes import ConcreteClass1, ConcreteClass2
|
||||
|
||||
|
||||
def client_code(abstract_class: AbstractClass) -> None:
|
||||
"""
|
||||
The client code calls the template method to execute the algorithm. Client
|
||||
code does not have to know the concrete class of an object it works with, as
|
||||
long as it works with objects through the interface of their base class.
|
||||
"""
|
||||
|
||||
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())
|
||||
Loading…
Reference in a new issue