https://github.com/pseudoincorrect/design_patterns_python
Design Pattern Course
https://github.com/pseudoincorrect/design_patterns_python
design-patterns python
Last synced: 9 months ago
JSON representation
Design Pattern Course
- Host: GitHub
- URL: https://github.com/pseudoincorrect/design_patterns_python
- Owner: pseudoincorrect
- Created: 2019-04-03T17:12:37.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2019-05-16T11:18:56.000Z (over 6 years ago)
- Last Synced: 2025-02-09T09:09:56.979Z (10 months ago)
- Topics: design-patterns, python
- Language: Python
- Homepage:
- Size: 46.9 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README
Awesome Lists containing this project
README
-------------------------------------------------------------------------------
- "SOLID" DESIGN PRINCIPLES ---------------------------------------------------
-------------------------------------------------------------------------------
S - Single Responsability Principle
A class should only have one reason to change
Separation of concerns - different classes handling different, independant
tasks/problems
O - Open-Closed Principle
A class should be open for extension, closed for modification
If you go back to a class and modify it (change code inside a already written
functions) it's probably a better idea to use OOP technics (such a inheritance)
to extend the class itself, or refactor the class to separate the concerns
L - Liskov Substitution Principle
You should be able to substitue a class by a type or a subtype
On the example with square and rectangle, we violation of the Principle.
There, for the Square class, when changing one of the edge size, all edges
should change. in the example it does not, hence the error of calculation
I - Interface Segregation Principle
Don't put too much into a single interface, split them.
YAGNI - You Ain't Going to Need It, don't write method/function you don't
need. write them when you need it. Yeah, I know the feeling of uncompletion
struck you hard, but it's life
D - Dependency Inversion Principle
High Level Modules should not depend on low level ones, use abstraction instead
-------------------------------------------------------------------------------
- CREATIONAL DESIGN PATTERNS --------------------------------------------------
-------------------------------------------------------------------------------
Builder
Separate component builder for when obect constructs get too complicated
We can use sub-builders to divide the overal build problem
usually used after the instance initialization
We can use fluent interface (return self) to chain the builders
Factories
Methods usually used to initialize a class in various different way
Can be a static class method
MyClass: @static MyClass.initializeThisWay(args)
Prototypes
Make an object from an existing object
in python, with copy.deepcopy
we can use a prototype factory: an object that store multiple
prototypes. When the need of creating an object arise, we can pick of the
prototype, copy it, and use it
Singleton
Tricky one
When you need to ensure that only one instance of a class exists.
can be done with Decorator of metaclass in python.
Generaly Tough to test (ex: singleton of a database oject). to solve this issue
we can use dependency injection (injecting a mock Db in the test case)
-------------------------------------------------------------------------------
- STRUCTURAL DESIGN PATTERNS --------------------------------------------------
-------------------------------------------------------------------------------
Adapter
convert an interface you get to an interface you need
Bridge
Decouple abstration from implementation
example: a Point class can use cartesian or polar notation
we can use a bridge for method that use Point without the
need to expose the complexity of cartesian or polar representations
Composite
Useful for reccursion. we can use this pattern to create an "object A"
containing multiple "objects B" and apply the same operation (function)
to them if for instace we have a list of As and Bs. A is a composite of
object B (several B contain in A)
Decorators
Attach additional responsabilities to objecs
Facade
provide a simple iterface for other complicated interfaces while keeping
the access to lower level features (if needed).
Flyweight
Used to support large number of objects. example: storing numbers that
reference to strings/sentences rather that storing them directly
Proxy
provide an object that forward the calls to an object while performing
additional functions ex: login
-------------------------------------------------------------------------------
- BEHAVIORAL DESIGN PATTERNS --------------------------------------------------
-------------------------------------------------------------------------------
Responsability Chain
allows component to process information/event in chain
Command
encapsulate request inside a seperate object instead of calling them directly
good for audit, undo,redo, database
Interpreter
Transform textual inputs into OOP structures (related: compiler theory)
Iterator
Provide an interface for accessing the elements of an aggregated object
__iter__ and __next__ in python, OR yield() (preferred)
Mediator
Provide mediation between two objects (ex: chat room)
basically an object that contain other objects and orchestrate them
Memento
Yield token representing the state of a system (snapshot)
Oberserver
Allows notifications of changes in a system (Event, Observables, etc...)
State
State machine (what else to say)
Strategy
define the high level functionality of a system. the details are
filled by an implementor (low level function)
Strategy use Composition (we inject the low lev object into the Strategy)
Template
Same as above but with inheritance
Visitor
Allows non intrusive addition of functionality to hierarchies
ex: adding functionality in a separate class to traverse a Object containing
a complicated data structure.
-------------------------------------------------------------------------------