Skip to content

Commit 7c51e67

Browse files
authored
Merge pull request #11 from dancergraham/feature/factory
Feature/factory Doc: Code running instructions
2 parents d5badb7 + a503c81 commit 7c51e67

File tree

11 files changed

+126
-36
lines changed

11 files changed

+126
-36
lines changed

chapter01_strategy/readme.md

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Chapter 1: Strategy design pattern
22

3-
> **Strategy**: defines a family of algorithms, encapsulates each one and makes them interchangeable.
3+
> **Strategy**: defines a family of algorithms, encapsulates each one and makes them interchangeable.
44
> Strategy lets the algorithm vary independently of clients that use it.
55
66
### Class Diagram
@@ -26,7 +26,6 @@ Strategy "1" <|.. "*" ConcreteStrategyB
2626
}
2727
```
2828

29-
3029
## Use in Python
3130

3231
The more pythonic approach in my mind is to define methods within an appropriate namespace
@@ -35,8 +34,15 @@ this does not violate the above definition. The class-based approach is
3534
needed in Java and has the advantage of explicitly setting out the required
3635
method in an abstract base class.
3736

38-
An example from the standard lib is changing the text [completion method](https://docs.python.org/3/library/readline.html?highlight=set_#readline.set_completer)
37+
An example from the standard lib is changing the
38+
text [completion method](https://docs.python.org/3/library/readline.html?highlight=set_#readline.set_completer)
3939
from the readline module. This is used by the python REPL when we hit <button>TAB</button> in the REPL.
4040
We can change the completion behavior via the `set_completer()` method, which takes a function
41-
which replaces the current completion function. The function is used explicitly to set
42-
the required behavior.
41+
which replaces the current completion function. The function is used explicitly to set
42+
the required behavior.
43+
44+
## Running the code
45+
46+
```bash
47+
python duck.py
48+
```

chapter02_observer/readme.md

+9-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@
33
> **Observer**: defines a one-to-many dependency between objects so that when one object changes state, all of its
44
> dependents are notified and updated automatically.
55
6-
A very useful design pattern, often used in user interfaces
7-
and as part of the popular Model-View-Controller (MVC) pattern used,
6+
A very useful design pattern, often used in user interfaces
7+
and as part of the popular Model-View-Controller (MVC) pattern used,
88
for instance, in Django.
9-
As I wrote out the code I found it very appealing that I did not need
9+
As I wrote out the code I found it very appealing that I did not need
1010
to change the subject at all to add new observers.
11+
12+
## Running the code
13+
14+
```bash
15+
python weather.py
16+
```

chapter03_decorator/readme.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ it just serves as documentation.
1717
```bash
1818
python coffee.py
1919
```
20+

chapter04_factory/pizza_abstract_factory.py

+13-8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ def __str__(self):
1111
return "Shredded Mozzarella"
1212

1313

14+
class ParmesanCheese(Cheese):
15+
def __str__(self):
16+
return "Shredded Parmesan"
17+
18+
1419
class ReggianoCheese(Cheese):
1520
def __str__(self):
1621
return "Reggiano Cheese"
@@ -112,22 +117,22 @@ def __str__(self) -> str:
112117

113118

114119
class PizzaIngredientFactory(abc.ABC):
115-
def create_dough():
120+
def create_dough(self):
116121
raise NotImplementedError
117122

118-
def create_sauce():
123+
def create_sauce(self):
119124
raise NotImplementedError
120125

121-
def create_cheese():
126+
def create_cheese(self):
122127
raise NotImplementedError
123128

124-
def create_veggies():
129+
def create_veggies(self):
125130
raise NotImplementedError
126131

127-
def create_pepperoni():
132+
def create_pepperoni(self):
128133
raise NotImplementedError
129134

130-
def create_clam():
135+
def create_clam(self):
131136
raise NotImplementedError
132137

133138

@@ -264,8 +269,8 @@ class PizzaStore:
264269
def create_pizza(self, item):
265270
raise NotImplementedError
266271

267-
def order_pizza(self, type):
268-
pizza = self.create_pizza(type)
272+
def order_pizza(self, type_):
273+
pizza = self.create_pizza(type_)
269274
print(f"--- Making a {pizza.name} ---")
270275
pizza.prepare()
271276
pizza.bake()

chapter04_factory/readme.md

+21-5
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,30 @@
22

33
> **Simple Factory**: A class which chooses which product class to instantiate and return, based upon method parameters.
44
5-
The Python standard library contains multiple references to factory objects, for instances in [dataclasses](https://docs.python.org/3/library/dataclasses.html?highlight=factory)
5+
The Python standard library contains multiple references to factory objects, for instances
6+
in [dataclasses](https://docs.python.org/3/library/dataclasses.html?highlight=factory).
7+
The Factory Boy package provides easy object creation for Django
8+
and for other ORMs.
69

7-
> **Factory Method**: Defines an interface for creating an object, but lets subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses.
10+
> **Factory Method**: Defines an interface for creating an object, but lets subclasses decide which class to
11+
> instantiate. The Factory method lets a class defer instantiation to subclasses.
812
9-
For instance the `PizzaStore` abstract class in this repo provides an abstract `create_pizza` interface for creating one product.
13+
For instance the `PizzaStore` abstract class in this repo provides an abstract `create_pizza` interface for creating one
14+
product.
1015

11-
The [python-qrcode](https://github.com/dancergraham/python-qrcode) module uses the factory method pattern nicely to separate only the part of the code that changes (generating png, svg, etc) from the underlying logic of the code generation and to allow extension through the creation of new factory methods without modification of the existing code. I took advantage of this to add a new class for the creation of 3D QR codes with my favourite NURBS modelling software Rhino.
16+
The [python-qrcode](https://github.com/dancergraham/python-qrcode) module uses the factory method pattern nicely to
17+
separate only the part of the code that changes (generating png, svg, etc.) from the underlying logic of the code
18+
generation and to allow extension through the creation of new factory methods without modification of the existing code.
19+
I took advantage of this to add a new class for the creation of 3D QR codes with my favourite NURBS modelling software
20+
Rhino.
1221

13-
> **Abstract Factory**: Provides an interface for creating families of related or dependent objects without specifying their concrete classes.
22+
> **Abstract Factory**: Provides an interface for creating families of related or dependent objects without specifying
23+
> their concrete classes.
1424
1525
For instance the `PizzaIngredientFactory` abstract class defines an interface for a family of products.
26+
27+
## Running the code
28+
29+
```bash
30+
python pizza_abstract_factory.py
31+
```

chapter05_singleton/readme.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,11 @@
22

33
> **Singleton**: ensures a class has only one instance, and provides a global point of access to it.
44
5-
My implementation is based this [stackoverflow post](https://stackoverflow.com/questions/6760685/creating-a-singleton-in-python?noredirect=1&lq=1).
5+
My implementation is based
6+
this [stackoverflow post](https://stackoverflow.com/questions/6760685/creating-a-singleton-in-python?noredirect=1&lq=1).
7+
8+
## Running the code
9+
10+
```bash
11+
python chocolate.py
12+
```

chapter06_command/readme.md

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
# Chapter 6: Command design pattern
22

3-
> **Command**: Encapsulates a request as an object, thereby letting you parameterise clients with different requests, queue or log requests, and support undoable operations.
3+
> **Command**: Encapsulates a request as an object, thereby letting you parameterize clients with different requests,
4+
> queue or log requests, and support undoable operations.
45
56
## Use in Python
67

7-
[Threading](https://docs.python.org/3/library/threading.html) In the Python standard library follows the command design pattern: The _Client_ is the main thread and the _receiver_ is the target thread. The _Command_ is a callable Python object which is executed by calling its `__call__()` method. The _Invoker_ is the `Thread` instance and its `run()` method is equivalent to calling _execute_ in the Command pattern. `Thread`'s `run` method can be overridden in subclasses to customise the functionality beyond simply providing a function and input `args` and `kwargs`.
8+
[Threading](https://docs.python.org/3/library/threading.html) In the Python standard library follows the command design
9+
pattern: The _Client_ is the main thread and the _receiver_ is the target thread. The _Command_ is a callable Python
10+
object which is executed by calling its `__call__()` method. The _Invoker_ is the `Thread` instance and its `run()`
11+
method is equivalent to calling _execute_ in the Command pattern. `Thread`'s `run` method can be overridden in
12+
subclasses to customise the functionality beyond simply providing a function and input `args` and `kwargs`.
13+
14+
## Running the code
15+
16+
```bash
17+
python remote_undo.py
18+
```

chapter07_adapter_facade/readme.md

+18-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
1-
# Chapter 7: Adapter and Façade design patterns
1+
# Chapter 7: Adapter and Facade design patterns
22

3-
I find myself using the adapter and facade patterns a lot when refactoring existing code. I know how I want it to work and I know how it works now but I don't have time _right now_ to fix it so I add an adapter or facade to give it a clean interface and I only change the underlying code if I need to make significant changes to the underlying implementation.
3+
I find myself using the adapter and facade patterns a lot when refactoring existing code. I know how I want it to work
4+
and I know how it works now, but I don't have time _right now_ to fix it, so I add an adapter or facade to give it a clean
5+
interface and I only change the underlying code if I need to make significant changes to the underlying implementation.
46

5-
> **Adapter**: Converts the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
7+
> **Adapter**: Converts the interface of a class into another interface the clients expect. Adapter lets classes work
8+
> together that couldn't otherwise because of incompatible interfaces.
69
7-
Compiled C modules in Python could be seen as examples of the adapter pattern: the Python implementation provides an interface for python code to work with the incompatible underlying C code.
10+
Compiled C modules in Python could be seen as examples of the adapter pattern: the Python implementation provides an
11+
interface for python code to work with the incompatible underlying C code.
812

9-
> **Façade**: Provides a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use.
13+
> **Facade**: Provides a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level
14+
> interface that makes the subsystem easier to use.
1015
11-
The [pathlib](https://github.com/python/cpython/blob/main/Lib/pathlib.py) Python library provides a simplified high-level cross-platform interface to methods and attributes from the `os`, `sys`, `io` and other modules.
12-
16+
The [pathlib](https://github.com/python/cpython/blob/main/Lib/pathlib.py) Python library provides a simplified
17+
high-level cross-platform interface to methods and attributes from the `os`, `sys`, `io` and other modules.
18+
19+
## Running the code
20+
21+
```bash
22+
python duck.py
23+
```

chapter08_template/readme.md

+6
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@ Variants of the template pattern are found throughout the Python object model, f
77
## Template method in Django
88

99
The template design pattern is widely used in frameworks such as Django, providing base classes which can be extended to provide required methods. For instance the [`full_clean`](https://github.com/django/django/blob/0dd29209091280ccf34e07c9468746c396b7778e/django/forms/forms.py#L424) method on Django forms runs the `_clean_fields()`, `self._clean_form()` and `self._post_clean()` methods, the latter of which is a *hook* for additional model validation and cleaning after the built-in validation logic has been applied.
10+
11+
## Running the code
12+
13+
```bash
14+
python barista.py
15+
```
+17-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
11
# Chapter 9: Iterator and Composite design patterns
22

3-
> **Iterator Method**: provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
3+
> **Iterator Method**: provides a way to access the elements of an aggregate object sequentially without exposing its
4+
> underlying representation.
45
5-
Java offers either the "Look Before You Leap" (LBYL) philosophy or the "Easier to Ask for Forgiveness than for Permission"(EAFP) with its [`iterator`](https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html) interface: The former involves calling `hasNext()` prior to calling `next()` whilst the latter uses the more recent `forEachRemaining()` method.
6+
Java offers either the "Look Before You Leap" (LBYL) philosophy or the "Easier to Ask for Forgiveness than for
7+
Permission"(EAFP) with its [`iterator`](https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html) interface:
8+
The former involves calling `hasNext()` prior to calling `next()` whilst the latter uses the more
9+
recent `forEachRemaining()` method.
610

711
Iteration is built in to the Python object model.
812

9-
Python requires only the `__iter__()` method to be implemented for an object to return `True` to `isinstance(obj, Iterable)`, however if an object implements just `__getitem__()` without `__iter__` then it will function as an iterable in Cpython!
13+
Python requires only the `__iter__()` method to be implemented for an object to return `True`
14+
to `isinstance(obj, Iterable)`, however if an object implements just `__getitem__()` without `__iter__` then it will
15+
function as an iterable in Cpython!
1016

11-
> **Composite Pattern**: allows you to compose objects into tree structures to represent whole-part hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
17+
> **Composite Pattern**: allows you to compose objects into tree structures to represent whole-part hierarchies.
18+
> Composite lets clients treat individual objects and compositions of objects uniformly.
19+
20+
## Running the code
21+
22+
```bash
23+
python menus.py
24+
```

chapter10_state/readme.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,12 @@
22

33
> **State Pattern**: allows an object to alter its behaviour when its internal state changes.
44
5-
The class structure is the same as the Strategy Design Pattern but the intent is different : In the State pattern the subclasses represent specific application states and may cover multiple attributes and methods whereas Strategy allows an algorithm to be selected upon arbitrary criteria and would typically just apply to a single method.
5+
The class structure is the same as the Strategy Design Pattern but the intent is different : In the State pattern the
6+
subclasses represent specific application states and may cover multiple attributes and methods whereas Strategy allows
7+
an algorithm to be selected upon arbitrary criteria and would typically just apply to a single method.
8+
9+
## Running the code
10+
11+
```bash
12+
python gumballstate.py
13+
```

0 commit comments

Comments
 (0)