|
1 | 1 | # Design Patterns in Python |
2 | 2 |
|
3 | | -A comprehensive library demonstrating software design patterns implemented in Python, following best practices and modern Python idioms. |
| 3 | +Python implementation of the 23 Gang of Four design patterns with type hints and comprehensive examples. |
4 | 4 |
|
5 | | -## Overview |
| 5 | +## Getting Started |
6 | 6 |
|
7 | | -Design patterns are reusable solutions to commonly occurring problems in software design. This library provides clear, well-tested implementations of the most important design patterns from the Gang of Four (GoF) book and other sources. |
| 7 | +Explore patterns by category using the sidebar navigation: |
8 | 8 |
|
9 | | -## Pattern Categories |
| 9 | +- **Creational** (5) - Object creation mechanisms |
| 10 | +- **Behavioral** (11) - Object interaction and responsibility |
| 11 | +- **Structural** (7) - Object composition and relationships |
10 | 12 |
|
11 | | -### Creational Patterns ✅ Complete (5/5) |
| 13 | +## Quick Links |
12 | 14 |
|
13 | | -Creational patterns deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. |
| 15 | +- [Introduction](introduction.md) - Core concepts and principles |
| 16 | +- [Pattern Catalog](overview.md) - Complete pattern reference table |
| 17 | +- [Pattern Selection Guide](pattern_guide.md) - Choosing the right pattern |
| 18 | +- [Quick Reference](quick_reference.md) - Pattern cheat sheet |
14 | 19 |
|
15 | | -#### Factory Pattern |
16 | | -Creates objects without specifying the exact class to instantiate. Useful when the exact type of object is determined at runtime. |
17 | | - |
18 | | -**Use When:** |
19 | | -- Object creation logic is complex |
20 | | -- You want to centralize object creation |
21 | | -- The exact type of object depends on configuration or user input |
22 | | - |
23 | | -#### Singleton Pattern |
24 | | -Ensures a class has only one instance and provides a global point of access to it. Useful for managing shared resources like database connections or configuration. |
25 | | - |
26 | | -**Use When:** |
27 | | -- Exactly one instance of a class is needed |
28 | | -- Controlled access to a single instance is necessary |
29 | | -- The instance should be extensible by subclassing |
30 | | - |
31 | | -#### Builder Pattern |
32 | | -Separates the construction of a complex object from its representation. Useful when objects require many configuration parameters. |
33 | | - |
34 | | -**Use When:** |
35 | | -- Object construction requires many parameters |
36 | | -- Objects need to be immutable after construction |
37 | | -- Construction process must allow different representations |
38 | | - |
39 | | -#### Prototype Pattern |
40 | | -Creates new objects by cloning existing instances. Useful when object creation is expensive or complex. |
41 | | - |
42 | | -**Use When:** |
43 | | -- Object creation is costly |
44 | | -- System should be independent of how objects are created |
45 | | -- Classes to instantiate are specified at runtime |
46 | | - |
47 | | -#### Abstract Factory Pattern |
48 | | -Provides an interface for creating families of related or dependent objects without specifying their concrete classes. |
49 | | - |
50 | | -**Use When:** |
51 | | -- System should be independent of how its objects are created |
52 | | -- System needs to work with multiple families of related objects |
53 | | -- You want to provide a library of objects without exposing implementation |
54 | | - |
55 | | -### Behavioral Patterns ✅ Complete (11/11) |
56 | | - |
57 | | -Behavioral patterns are concerned with algorithms and the assignment of responsibilities between objects. |
58 | | - |
59 | | -#### Strategy Pattern |
60 | | -Defines a family of algorithms, encapsulates each one, and makes them interchangeable. Allows the algorithm to vary independently from clients that use it. |
61 | | - |
62 | | -**Use When:** |
63 | | -- Many related classes differ only in their behavior |
64 | | -- You need different variants of an algorithm |
65 | | -- Algorithm uses data that clients shouldn't know about |
66 | | - |
67 | | -#### Observer Pattern |
68 | | -Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified automatically. |
69 | | - |
70 | | -**Use When:** |
71 | | -- Changes to one object require changing others |
72 | | -- Number of dependent objects is unknown or dynamic |
73 | | -- An object should notify others without assumptions about who they are |
74 | | - |
75 | | -#### Command Pattern |
76 | | -Encapsulates a request as an object, thereby allowing parameterization of clients with different requests, queue or log requests, and support undoable operations. |
77 | | - |
78 | | -**Use When:** |
79 | | -- You want to parameterize objects by an action |
80 | | -- You need to queue, schedule, or execute requests at different times |
81 | | -- You need to support undo operations |
82 | | - |
83 | | -#### Chain of Responsibility Pattern |
84 | | -Passes requests along a chain of handlers. Each handler decides either to process the request or pass it to the next handler in the chain. |
85 | | - |
86 | | -**Use When:** |
87 | | -- More than one object may handle a request |
88 | | -- The handler is not known a priori |
89 | | -- The set of handlers should be specified dynamically |
90 | | - |
91 | | -#### Interpreter Pattern |
92 | | -Defines a representation for a language's grammar along with an interpreter that uses the representation to interpret sentences in the language. |
93 | | - |
94 | | -**Use When:** |
95 | | -- The grammar is simple |
96 | | -- Efficiency is not a critical concern |
97 | | -- The grammar changes frequently |
98 | | - |
99 | | -#### State Pattern |
100 | | -Allows an object to alter its behavior when its internal state changes. The object will appear to change its class. |
101 | | - |
102 | | -**Use When:** |
103 | | -- Object behavior depends on its state |
104 | | -- Operations have large conditional statements that depend on object state |
105 | | -- State transitions are explicit and numerous |
106 | | - |
107 | | -#### Template Method Pattern |
108 | | -Defines the skeleton of an algorithm in a base class, allowing subclasses to override specific steps without changing the algorithm's structure. |
109 | | - |
110 | | -**Use When:** |
111 | | -- You want to implement the invariant parts of an algorithm once |
112 | | -- Common behavior among subclasses should be localized |
113 | | -- You want to control subclass extensions at specific points |
114 | | - |
115 | | -#### Iterator Pattern |
116 | | -Provides a way to access elements sequentially without exposing underlying representation. Python has built-in support for this pattern. |
117 | | - |
118 | | -**Use When:** |
119 | | -- You need to traverse a collection without exposing its structure |
120 | | -- Multiple simultaneous traversals are needed |
121 | | -- You want a uniform interface for different collections |
122 | | - |
123 | | -#### Visitor Pattern |
124 | | -Represents an operation to be performed on elements of an object structure. Lets you define new operations without changing the classes. |
125 | | - |
126 | | -**Use When:** |
127 | | -- Object structure is stable but operations change frequently |
128 | | -- Many unrelated operations need to be performed on objects |
129 | | -- You want to separate algorithms from the objects they operate on |
130 | | - |
131 | | -#### Mediator Pattern |
132 | | -Defines an object that encapsulates how a set of objects interact. Promotes loose coupling by preventing objects from referring to each other explicitly. |
133 | | - |
134 | | -**Use When:** |
135 | | -- Objects communicate in complex ways with many dependencies |
136 | | -- Reusing objects is difficult due to tight coupling |
137 | | -- Behavior distributed among classes should be customizable |
138 | | - |
139 | | -#### Memento Pattern |
140 | | -Captures and externalizes an object's internal state for later restoration without violating encapsulation. |
141 | | - |
142 | | -**Use When:** |
143 | | -- Undo/redo functionality is needed |
144 | | -- Snapshots of state are required |
145 | | -- Direct access to state fields would violate encapsulation |
146 | | - |
147 | | -### Structural Patterns ✅ Complete (7/7) |
148 | | - |
149 | | -Structural patterns are concerned with how classes and objects are composed to form larger structures. |
150 | | - |
151 | | -#### Decorator Pattern |
152 | | -Attaches additional responsibilities to an object dynamically. Provides a flexible alternative to subclassing for extending functionality. |
153 | | - |
154 | | -**Use When:** |
155 | | -- Responsibilities need to be added to individual objects dynamically |
156 | | -- Extension by subclassing is impractical |
157 | | -- You want to add functionality without affecting other objects |
158 | | - |
159 | | -#### Adapter Pattern |
160 | | -Converts the interface of a class into another interface clients expect. Allows classes to work together that couldn't otherwise due to incompatible interfaces. |
161 | | - |
162 | | -**Use When:** |
163 | | -- You want to use an existing class with an incompatible interface |
164 | | -- You need to create a reusable class that cooperates with unrelated classes |
165 | | -- You need to use several existing subclasses but it's impractical to adapt their interface by subclassing |
166 | | - |
167 | | -#### Composite Pattern |
168 | | -Composes objects into tree structures to represent part-whole hierarchies. Allows clients to treat individual objects and compositions uniformly. |
169 | | - |
170 | | -**Use When:** |
171 | | -- You want to represent part-whole hierarchies |
172 | | -- You want clients to ignore the difference between compositions and individual objects |
173 | | -- The structure can be represented as a tree |
174 | | - |
175 | | -#### Facade Pattern |
176 | | -Provides a simplified interface to a complex subsystem. Wraps complicated classes with a single, easier-to-use interface. |
177 | | - |
178 | | -**Use When:** |
179 | | -- You want to provide a simple interface to a complex subsystem |
180 | | -- There are many dependencies between clients and implementation classes |
181 | | -- You want to layer your subsystems |
182 | | - |
183 | | -#### Proxy Pattern |
184 | | -Provides a surrogate or placeholder for another object to control access to it. Useful for lazy loading, access control, or caching. |
185 | | - |
186 | | -**Use When:** |
187 | | -- You need lazy initialization (virtual proxy) |
188 | | -- You need access control (protection proxy) |
189 | | -- You need to cache expensive operations (caching proxy) |
190 | | -- You need a local representative for a remote object (remote proxy) |
191 | | - |
192 | | -#### Bridge Pattern |
193 | | -Decouples an abstraction from its implementation so that the two can vary independently. Uses composition to separate interface from implementation. |
194 | | - |
195 | | -**Use When:** |
196 | | -- You want to avoid permanent binding between abstraction and implementation |
197 | | -- Both abstractions and implementations should be extensible by subclassing |
198 | | -- Changes in implementation should not impact clients |
199 | | - |
200 | | -## Principles Demonstrated |
201 | | - |
202 | | -### Composition over Inheritance |
203 | | -Demonstrates how composition provides more flexibility than inheritance by allowing behavior to be changed at runtime. |
204 | | - |
205 | | -### Inheritance |
206 | | -Shows proper use of inheritance to model "is-a" relationships and share common behavior. |
207 | | - |
208 | | -## Documentation Guides |
209 | | - |
210 | | -This library includes comprehensive guides to help you master design patterns: |
211 | | - |
212 | | -- **[Pattern Selection Guide](pattern_guide.md)** - Detailed guidance on when to use each pattern, including benefits, drawbacks, and trade-offs |
213 | | -- **[Pattern Comparison Guide](pattern_comparison.md)** - Side-by-side comparisons of similar patterns to help you choose the right one |
214 | | -- **[Practical Examples](practical_examples.md)** - Real-world use cases showing how patterns solve actual problems in web applications, microservices, and data processing |
215 | | -- **[Anti-Patterns](anti_patterns.md)** - Common mistakes and misuses to avoid when implementing patterns |
216 | | -- **[Quick Reference](quick_reference.md)** - Concise cheat sheet for rapid pattern selection and implementation |
217 | | - |
218 | | -## Testing |
219 | | - |
220 | | -All patterns include comprehensive test suites demonstrating correct usage and behavior. Run tests with: |
| 20 | +## Installation |
221 | 21 |
|
222 | 22 | ```bash |
223 | | -pytest tests/ |
| 23 | +pip install -e . |
224 | 24 | ``` |
225 | 25 |
|
226 | | -Current test statistics: |
227 | | -- 275+ tests |
228 | | -- 94% code coverage |
229 | | -- All 23 GoF patterns tested |
| 26 | +## Usage |
230 | 27 |
|
231 | | -## Type Checking |
| 28 | +```python |
| 29 | +from design_patterns.creational.factory import AnimalFactory |
| 30 | +from design_patterns.behavioral.strategy import ShoppingCart, CreditCardPayment |
232 | 31 |
|
233 | | -The codebase uses type hints throughout. Run type checking with: |
| 32 | +factory = AnimalFactory() |
| 33 | +dog = factory.get_animal("dog", "Buddy") |
234 | 34 |
|
235 | | -```bash |
236 | | -mypy src/ |
| 35 | +cart = ShoppingCart() |
| 36 | +cart.set_payment_strategy(CreditCardPayment("1234-5678")) |
237 | 37 | ``` |
238 | | - |
239 | | -## Best Practices |
240 | | - |
241 | | -- All implementations follow Python idioms and conventions |
242 | | -- Type hints are used throughout for better IDE support and documentation |
243 | | -- Comprehensive docstrings explain the purpose and usage of each pattern |
244 | | -- Test coverage ensures correctness and demonstrates usage |
245 | | - |
246 | | -## Contributing |
247 | | - |
248 | | -When adding new patterns: |
249 | | -1. Create the pattern implementation in the appropriate category directory |
250 | | -2. Include comprehensive docstrings with examples |
251 | | -3. Add complete test coverage |
252 | | -4. Update this documentation |
253 | | - |
254 | | -## References |
255 | | - |
256 | | -- Design Patterns: Elements of Reusable Object-Oriented Software (Gang of Four) |
257 | | -- Head First Design Patterns |
258 | | -- Python-specific design patterns and idioms |
259 | | - |
260 | | -## API Reference |
261 | | - |
262 | | -::: design_patterns |
263 | | - options: |
264 | | - show_root_heading: true |
265 | | - show_source: false |
0 commit comments