mirror of
https://github.com/rjNemo/design-patterns
synced 2026-06-12 13:36:41 +00:00
chore: enforce style guidelines
This commit is contained in:
parent
d525eb96b1
commit
6b031eb853
13 changed files with 48 additions and 40 deletions
|
|
@ -8,10 +8,10 @@ class AbstractFactory(ABC):
|
||||||
"""
|
"""
|
||||||
The Abstract Factory interface declares a set of methods that return
|
The Abstract Factory interface declares a set of methods that return
|
||||||
different abstract products. These products are called a family and are
|
different abstract products. These products are called a family and are
|
||||||
related by a high-level theme or concept. Products of one family are usually
|
related by a high-level theme or concept. Products of one family are
|
||||||
able to collaborate among themselves. A family of products may have several
|
usually able to collaborate among themselves. A family of products may have
|
||||||
variants, but the products of one variant are incompatible with products of
|
several variants, but the products of one variant are incompatible with
|
||||||
another.
|
products of another.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC
|
||||||
|
|
||||||
|
|
||||||
class AbstractProductA(ABC):
|
class AbstractProductA(ABC):
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ from AbstractProductA import AbstractProductA
|
||||||
class AbstractProductB(ABC):
|
class AbstractProductB(ABC):
|
||||||
"""
|
"""
|
||||||
Here's the the base interface of another product. All products can interact
|
Here's the the base interface of another product. All products can interact
|
||||||
with each other, but proper interaction is possible only between products of
|
with each other, but proper interaction is possible only between products
|
||||||
the same concrete variant.
|
of the same concrete variant.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,17 @@
|
||||||
from AbstractFactory import AbstractFactory
|
from AbstractFactory import AbstractFactory
|
||||||
from products import (ConcreteProductA1, ConcreteProductA2, ConcreteProductB1,
|
from products import (
|
||||||
ConcreteProductB2)
|
ConcreteProductA1,
|
||||||
|
ConcreteProductA2,
|
||||||
|
ConcreteProductB1,
|
||||||
|
ConcreteProductB2,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ConcreteFactory1(AbstractFactory):
|
class ConcreteFactory1(AbstractFactory):
|
||||||
"""
|
"""
|
||||||
Concrete Factories produce a family of products that belong to a single
|
Concrete Factories produce a family of products that belong to a single
|
||||||
variant. The factory guarantees that resulting products are compatible. Note
|
variant. The factory guarantees that resulting products are compatible.
|
||||||
that signatures of the Concrete Factory's methods return an abstract
|
Note that signatures of the Concrete Factory's methods return an abstract
|
||||||
product, while inside the method a concrete product is instantiated.
|
product, while inside the method a concrete product is instantiated.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,14 @@ class ConcreteProductA2(AbstractProductA):
|
||||||
|
|
||||||
|
|
||||||
class ConcreteProductB1(AbstractProductB):
|
class ConcreteProductB1(AbstractProductB):
|
||||||
|
|
||||||
def useful_function_b(self) -> str:
|
def useful_function_b(self) -> str:
|
||||||
return "The result of the product B1."
|
return "The result of the product B1."
|
||||||
|
|
||||||
def another_useful_function_b(self, collaborator: AbstractProductA) -> str:
|
def another_useful_function_b(self, collaborator: AbstractProductA) -> str:
|
||||||
"""
|
"""
|
||||||
The variant, Product B1, is only able to work correctly with the variant,
|
The variant, Product B1, is only able to work correctly with the
|
||||||
Product A1. Nevertheless, it accepts any instance of AbstractProductA as an
|
variant, Product A1. Nevertheless, it accepts any instance of
|
||||||
argument.
|
AbstractProductA as an argument.
|
||||||
"""
|
"""
|
||||||
result = collaborator.useful_function_a()
|
result = collaborator.useful_function_a()
|
||||||
return f"The result of the B1 collaborating with the ({result})"
|
return f"The result of the B1 collaborating with the ({result})"
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ class Director:
|
||||||
@builder.setter
|
@builder.setter
|
||||||
def builder(self, builder: Builder) -> None:
|
def builder(self, builder: Builder) -> None:
|
||||||
"""
|
"""
|
||||||
The Director works with any builder instance that the client code passes
|
The Director works with any builder instance that the client code
|
||||||
to it. This way, the client code may alter the final type of the newly
|
passes to it. This way, the client code may alter the final type of the
|
||||||
assembled product.
|
newly assembled product.
|
||||||
"""
|
"""
|
||||||
self._builder = builder
|
self._builder = builder
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ class ConcreteBuilder1(Builder):
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
"""
|
"""
|
||||||
A fresh builder instance should contain a blank product object, which is
|
A fresh builder instance should contain a blank product object, which
|
||||||
used in further assembly.
|
is used in further assembly.
|
||||||
"""
|
"""
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
|
|
@ -25,8 +25,8 @@ class ConcreteBuilder1(Builder):
|
||||||
Concrete Builders are supposed to provide their own methods for
|
Concrete Builders are supposed to provide their own methods for
|
||||||
retrieving results. That's because various types of builders may create
|
retrieving results. That's because various types of builders may create
|
||||||
entirely different products that don't follow the same interface.
|
entirely different products that don't follow the same interface.
|
||||||
Therefore, such methods cannot be declared in the base Builder interface
|
Therefore, such methods cannot be declared in the base Builder
|
||||||
(at least in a statically typed programming language).
|
interface (at least in a statically typed programming language).
|
||||||
|
|
||||||
Usually, after returning the end result to the client, a builder
|
Usually, after returning the end result to the client, a builder
|
||||||
instance is expected to be ready to start producing another product.
|
instance is expected to be ready to start producing another product.
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ class Product1:
|
||||||
It makes sense to use the Builder pattern only when your products are quite
|
It makes sense to use the Builder pattern only when your products are quite
|
||||||
complex and require extensive configuration.
|
complex and require extensive configuration.
|
||||||
|
|
||||||
Unlike in other creational patterns, different concrete builders can produce
|
Unlike in other creational patterns, different concrete builders can
|
||||||
unrelated products. In other words, results of various builders may not
|
produce unrelated products. In other words, results of various builders may
|
||||||
always follow the same interface.
|
not always follow the same interface.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ class ICreator(ABC):
|
||||||
product = self.factory_method()
|
product = self.factory_method()
|
||||||
|
|
||||||
# Now, use the product.
|
# Now, use the product.
|
||||||
result = f"Creator: The same creator's code has just worked with {product.operation()}"
|
result = f"""
|
||||||
|
Creator: The same creator's code has just worked with
|
||||||
|
{product.operation()}
|
||||||
|
"""
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,5 @@ class ConcreteCreator1(ICreator):
|
||||||
|
|
||||||
|
|
||||||
class ConcreteCreator2(ICreator):
|
class ConcreteCreator2(ICreator):
|
||||||
|
|
||||||
def factory_method(self) -> ConcreteProduct2:
|
def factory_method(self) -> ConcreteProduct2:
|
||||||
return ConcreteProduct2()
|
return ConcreteProduct2()
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,16 @@ from ICreator import ICreator
|
||||||
|
|
||||||
def client_code(creator: ICreator) -> None:
|
def client_code(creator: ICreator) -> None:
|
||||||
"""
|
"""
|
||||||
The client code works with an instance of a concrete creator, albeit through
|
The client code works with an instance of a concrete creator, albeit
|
||||||
its base interface. As long as the client keeps working with the creator via
|
through its base interface. As long as the client keeps working with the
|
||||||
the base interface, you can pass it any creator's subclass.
|
creator via the base interface, you can pass it any creator's subclass.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
print(f"Client: I'm not aware of the creator's class, but it still works.\n"
|
print(
|
||||||
f"{creator.some_operation()}", end="")
|
f"Client: I'm not aware of the creator's class, but it still works.\n"
|
||||||
|
f"{creator.some_operation()}",
|
||||||
|
end="",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
print("App: Launched with the ConcreteCreator1.")
|
print("App: Launched with the ConcreteCreator1.")
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,16 @@ class SomeComponent:
|
||||||
implementations have to override `__copy__` and `__deepcopy__` member
|
implementations have to override `__copy__` and `__deepcopy__` member
|
||||||
functions.
|
functions.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
some_int: int
|
some_int: int
|
||||||
some_list_of_objects: List
|
some_list_of_objects: List
|
||||||
some_circular_ref: Any
|
some_circular_ref: Any
|
||||||
|
|
||||||
def __copy__(self) -> SomeComponent:
|
def __copy__(self) -> SomeComponent:
|
||||||
"""
|
"""
|
||||||
Create a shallow copy. This method will be called whenever someone calls
|
Create a shallow copy. This method will be called whenever someone
|
||||||
`copy.copy` with this object and the returned value is returned as the
|
calls `copy.copy` with this object and the returned value is returned
|
||||||
new shallow copy.
|
as the new shallow copy.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# First, let's create copies of the nested objects.
|
# First, let's create copies of the nested objects.
|
||||||
|
|
@ -38,8 +39,7 @@ class SomeComponent:
|
||||||
|
|
||||||
# Then, let's clone the object itself, using the prepared clones of the
|
# Then, let's clone the object itself, using the prepared clones of the
|
||||||
# nested objects.
|
# nested objects.
|
||||||
new = self.__class__(
|
new = self.__class__(self.some_int, some_list_of_objects, some_circular_ref)
|
||||||
self.some_int, some_list_of_objects, some_circular_ref)
|
|
||||||
new.__dict__.update(self.__dict__)
|
new.__dict__.update(self.__dict__)
|
||||||
|
|
||||||
return new
|
return new
|
||||||
|
|
@ -63,8 +63,7 @@ class SomeComponent:
|
||||||
|
|
||||||
# Then, let's clone the object itself, using the prepared clones of the
|
# Then, let's clone the object itself, using the prepared clones of the
|
||||||
# nested objects.
|
# nested objects.
|
||||||
new = self.__class__(
|
new = self.__class__(self.some_int, some_list_of_objects, some_circular_ref)
|
||||||
self.some_int, some_list_of_objects, some_circular_ref)
|
|
||||||
|
|
||||||
new.__dict__ = copy.deepcopy(self.__dict__, memo)
|
new.__dict__ = copy.deepcopy(self.__dict__, memo)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ circular_ref.set_parent(component)
|
||||||
|
|
||||||
shallow_copied_component = copy.copy(component)
|
shallow_copied_component = copy.copy(component)
|
||||||
|
|
||||||
# Let's change the list in shallow_copied_component and see if it changes in component.
|
# Let's change the list in shallow_copied_component and see if it changes in
|
||||||
|
# component.
|
||||||
shallow_copied_component.some_list_of_objects.append("another object")
|
shallow_copied_component.some_list_of_objects.append("another object")
|
||||||
if component.some_list_of_objects[-1] == "another object":
|
if component.some_list_of_objects[-1] == "another object":
|
||||||
print(
|
print(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue