chore: enforce style guidelines

This commit is contained in:
Ruidy Nemausat 2020-09-14 21:26:57 +02:00
parent d525eb96b1
commit 6b031eb853
13 changed files with 48 additions and 40 deletions

View file

@ -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

View file

@ -1,4 +1,4 @@
from abc import ABC, abstractmethod from abc import ABC
class AbstractProductA(ABC): class AbstractProductA(ABC):

View file

@ -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

View file

@ -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.
""" """

View file

@ -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})"

View file

@ -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

View file

@ -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.

View file

@ -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:

View file

@ -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

View file

@ -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()

View file

@ -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.")

View file

@ -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)

View file

@ -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(