Python Design Patterns Explained
Python Design Patterns Explained
Abstract—This article discusses design patterns. public to the 3rd "most loved" language, according to a
(from English design pattern) which is a general solution for a research conducted by the website Stack Overflow in 2018, and is
problem that frequently occurs within a certain among the 5 most popular languages, according to a
context in the software project. A design pattern does not
it's not a ready solution nor a finalized project, but rather research conducted by RedMonk.
a way to approach a problem that is already known and studied. Python supports most of the techniques of original programming.
This article discusses design patterns in the language of entry into an object. Any object can be used for any
Python programming that is great for applying patterns of Well, the code will work as long as there are methods and attributes.
project, mainly because it is object-oriented, having typing
adequate. The concept of an object in language is quite
dynamic, among other things.
IndexTerms—Padrões de projeto, python, design pattern. comprehensive: classes, functions, numbers, and modules are all
considered objects. There is also support for metaclasses,
I. INTRODUCTION polymorphism, and inheritance (including multiple inheritance). There is a
This article describes Design Patterns, which are limited support for private variables.
solutions for recurring problems; guidelines on how to
dealing with certain problems. They are not classes, packages or C. Why Python?
libraries that you can connect to your application and wait Python is an open-source scripting language. It has
the magic happens. These are, rather, guidelines on how to libraries that provide support for a variety of standards
to deal with certain problems in certain situations. of design. The syntax of Python is easy to understand and uses
The architect Christopher Alexander states that a pattern keywords in English.
the project should ideally have the following characteristics
Encapsulation, Generality, Balance, Abstraction
[Link]ÕESGOF
Openness and Combinatorics, thus being robust for
solve a small or large and specific problem for According to the book: "Design Patterns: solutions
solve a singular problem. reusable object-oriented software
A. According to Wikipedia "GoF" is divided into 24 types. Based on this large
number of patterns, it was necessary to classify them accordingly
In software engineering, a software design pattern
with its purposes.
it is a general reusable solution for a common problem
There are 3 classifications/families:
in a certain context in software design. It is not
a final design that can be directly transformed into • Design patterns: Design patterns are those
source code or machine. It is a description or model of how that abstract and/or delay the process of creating objects.
solve a problem that can be used in many situations They help to make a system independent of how
different. your objects are created, composed, and represented. A
the class creation pattern uses inheritance to vary
B. About the language the class that is instantiated, while a pattern
Python is a high-level programming language, the creation of the object will delegate the instantiation to another
interpreted, from script, imperative, object-oriented, fun- object.
It is a high-level programming language, with dynamic and strong typing. It was released by• Structural
Guido. patterns: Structural patterns are concerned with
van Rossum in 1991. It currently has a model of like the way classes and objects are composed
community development, open and managed by the to form larger structures. Those of classes use the
non-profit organization Python Software Foundation. inheritance to compose interfaces or implementations, and the
Although several parts of the language have patterns and of objects describe ways to compose objects for
formal specifications, the language as a whole is not obtain new features.
formally specified. The standard is actually the implementation. • Behavioral patterns: The patterns of behavior
CPython. they focus on algorithms and assignments of
Due to its characteristics, it is mainly used responsibilities among the objects. They do not describe
for processing texts, scientific data and creation of only patterns of objects or classes, but also the
CGIs for dynamic web pages. It was considered by communication patterns between objects.
[Link] PATTERNS
A. Padrão Strategy
In the use of the strategy, we can pass as a parameter
a function, or rather, a strategy, for another method,
allowing the removal of several conditional commands, once
that we do not need to manually verify what the strategy was
passed as a parameter.
Note: Difference between function and method: a method per-
a sentence belongs to a class and a function does not necessarily belong. Fig. 2. Implementation of the Chain of Responsibility in Java.
to a class.
Duck typing: is a typing style in which the methods and
the properties of an object determine the valid semantics, in In Java, a middleware is used as shown in figure 2:
instead of inheriting from a specific class or implementation to shift the responsibility to the next case no
of an explicit interface. be the one responsible for accepting this responsibility.
In Python, a Handler is used for the same purpose.
B. Padrão State as shown in figure 3:
The State pattern is a solution to the problem of how
make the behavior dependent on the state.
• Define a 'context' class to present a single
interface for the outside world.
• Define an abstract base class for the state.
• Represent the different 'states' of the state machine
as derived classes of the base class of the State.
• Defines the specific behavior of the state in classes
appropriate state derivatives.
• Maintain a pointer to the current 'state' in the class
context
• To change the state of the state machine, change the
current state pointer.
In the end, the state of the class will be defined by the class itself.
through requests as shown in Figure 1:
Fig. 3. Implementation of the Chain of Responsibility in Python.
D. Standard Command
The Command pattern tells us how to create 'co-objects'
command that encapsulates a request to do something in a
specific object. Basically all command objects
we implement the same interface, which consists of a single
method usually called execute().
Fig. 1. Final implementation of the state pattern. The Command Pattern has as its definition to encapsulate a
request as an object, which allows you to parameterize
other objects with different requests, queue or register
C. Standard Chain of Responsibility bring requests and implement cancellation features
It allows us to apply a sequential logic in a way operations.
dynamic. By using this pattern we can stop using In Python, it is mostly used as a
various IFs and ELSEs through a chain of classes that will be alternative for callback returns to parameterize it
executed in sequence. This greatly facilitates maintenance mentos of the user interface with actions. It is also used
of code. Avoid coupling the sender of a request for queuing tasks, tracking history of
attribution to the recipient, giving more than one object the chance to operations etc.
deal with the request. 1) Difference between Command and Strategy: The idea of
The implementation of the Chain of Responsibility in Python Command is to abstract a command that needs to be executed because
It does not differ from the implementation of Java in structural aspects - it is not possible to execute it at that moment (because we need
either turais or logical, only the syntax of the language will change. to put in a queue or something like that). In Strategy, the idea is
that you have a strategy (an algorithm) to solve G. Null Object Pattern
a problem.
The intention of a Null Object is to encapsulate the absence of a
object, providing a replaceable alternative that offers a
E. Observer Pattern standard behavior without doing anything. In short, a design
The observer pattern allows us to pass a list of observers in which 'nothing will result in nothing'.
voters, interested in the creation of an object, for a In Python, the implementation of this pattern becomes a
class, and iterate over it to run all the observers. an interface identical to the AbstractObject for a null value
Thus, if we have a new observer, just include them in the object can be replaced by a real object. Implement
list of observers. The Observer pattern is quite common your interface to do nothing. What exactly does it mean
in the Python code, especially in the GUI components. doing nothing depends on what kind of behavior the customer has
It provides a way to react to events that occur. is waiting.
in other objects without coupling to their classes.
Identification: The pattern can be recognized by methods
IV.P CREATIVE STANDARDS
of the signature, which store objects in a list and by
calls to the update method issued for objects
A. Singleton Pattern
in this list.
The Singleton is one of the simplest patterns and has a
neF
[Link]
atem
eM
atplhoedt specific objective, to ensure that only one object of a
a certain class is to be created.
It is a behavioral design pattern that defines the
skeleton of an algorithm in the superclass, but allows that • Ensure that a class has only one instance and
as subclasses replace specific stages of the algorithm without provide global access to it.
change its structure. • Encapsulated 'just-in-time initialization' or 'initialization
The standard suggests that you divide an algorithm into a series on first use.
from stages, transform these stages into methods and make a Figure 5 demonstrates a way to implement the sin-
series of calls to these methods in a single "method" gleton in python:
of the model." The stages can be abstract or have some pattern
implementation. To use the algorithm, the client must provide
its own subclass, implement all the abstract steps and
replace some options, if necessary (but not the itself
model method.
The Template Method pattern is quite common in structures
Python. Developers often use it to provide
to the users of the structure a simple way to extend the
standard functionality using inheritance as shown in the figure
4.
B. Prototype Pattern
Declare an abstract base class that specifies a method
"clone" pure virtual and maintains a dictionary of all the
concrete "cloneable" derived classes. Any class that
requires a resource "polymorphic builder": derived from
classe base abstrata, registra sua instância prototípica e imple-
mint aclone() operation.
The implementation differentiation of the Java standard for
Python is only the syntax of the language, the structure and logic.
they remain the same.
The Prototype pattern is available in Python immediately-
mind with a Cloneable interface.
Fig. 4. Demonstration of the template method in Python In Python, the use of the language's feature like
show Figure 6:
compatible with other classes. When we need a
existing class works with other classes without modifying its
source code. In Python the syntax changes but the structure of
standard no. Figure 8 shows an XML adapter
for JSON.
C. Padrão Builder
With the builder design pattern, we can create a class
builder, who is responsible for receiving the parameters, veri-
to establish the validity of the parameters and even define parameters
standards when necessary.
The Python language itself provides ways to
named parameters and default parameters, which makes it easier
often eliminates the need for use
of the builder pattern. However, in the Python language, this pattern
often it is unnecessary, since named parameters and
optional class constructors can often handle Fig. 8. Diagram demonstrating Adapter
with the complexity of the object's creation as shown in
Figure 7:
B. Decorator Pattern
The Decorator is a structural design pattern that per-
I can add new behaviors to objects, putting-
the inside of special objects of the wrapping that contains the
behaviors. Decorators provide an alternative
flexible to the subclass to expand functionality.
Decorator x Adapter - Adapter alters the interface of a
existing object, while the Decorator enhances an object
Fig. 7. Implementation of the Builder in Python
without altering its interface. Furthermore, the Decorator supports
recursive composition, which is not possible when you use
D. Dependency Injection the adapter.
In Python, the structure of dependency injection is something that In Python, the decorator is quite standard in Python code.
the Python developer would never need, because the injection especially in the code related to flows. The decorator
dependency can be easily implemented using can be recognized by creation methods or constructor
the fundamentals of language. The language itself offers that accept objects of the same class or interface as one
easy ways to do like the typing mentioned above and some current class.
libraries like Dependency Injector The final implementation in Python as shown in Figure 9:
However, this library is not widely used due to a...
complicated and somewhat obsolete reasoning comparing
with the way that 'pure' python does the injection
of dependency, it is enough to pass a class
parameter as demonstrated in Figure 7 in this way functions
The methods of the class Builder will be made available to the class.
that injects.
Fig. 9. Implementation of the Decorator pattern in Python
V. PATTERN STRUCTURES
A. Adapter Pattern
The adapter pattern is a software design pattern. C. Facade Pattern
which allows the interface of an existing class to be used The Facade design pattern provides a simplified interface
like another interface. This pattern allows for a (limited) wrapping around a complex system of classes,
some incompatible object in an adapter to make it a library or structure.
Although the Facade reduces the overall complexity of the application, a group of objects must be treated in the same way as a
so, it also helps to move unwanted dependencies to a single instance of an object. The purpose of the composite pattern
local. to compose objects in tree structures that represent
hierarchies.
The Composite is quite common in Python code. It is
frequently used to represent hierarchies of components
elements of the user interface or the code that works with
graphics. It is easy to recognize by behavioral methods,
bringing an instance of the same abstract type / interface to
a tree structure.
VI. CONCLUSION
Throughout this article, Python has proven to be a lin-
optimal programming language for the application of standards
of the project for its flexibility compared to others
more "rigid" languages, due to the fact that most standards
can be easily implemented with their own resources
language. Design patterns attempt to standardize the vo-
vocabulary of certain designs, recurring in numerous
aplicações, como ja foi estudado a melhor forma de resolver
determinados problemas das aplicações foi com o uso dos
design patterns that also serve as a "shortcut" to
to solve these recurring problems.
REFERENCES
CPYTHON. In: WIKIPEDIA, the free encyclopedia. Florida: Wikimedia
Foundation, 2019. Available at: <[Link] Accessed on:
14 jun. 2019.
DESIGN PATTERNS. In: REFACTORING GURU. US: Refactoring
Guru, 2014-2019. Available at: <[Link]
DESIGN PATTERNS. In: SOURCE MAKING. US: Source Making,
2019. Available at: <[Link]
DEPENDENCY INJECTOR. In: [Link], Python-Dependency-
Injector, 2017. Available at: <[Link]
SOFTWARE DESIGN PATTERN. In: WIKIPEDIA,
free encyclopedia. Florida: Wikimedia Foundation, 2019. Available at:
<[Link]
PYTHON. In: WIKIPEDIA, the free encyclopedia. Florida: Wikimedia
Foundation, 2019. Available at: <[Link]
Design patterns abstract and delay the process of object creation by making systems independent of how objects are created, composed, and represented. This approach enables developers to use inheritance to vary the class that is instantiated, or to delegate instantiation to another object, thereby achieving improved flexibility and reusability in design .
Challenges in implementing the Dependency Injection pattern in Python stem from its dynamic and interpreted nature, where enforcing compile-time type checks or strict interface contracts is not direct. However, Python alleviates these challenges by allowing functions to easily accept dependency injection through parameters, use of higher order functions, and the utilization of built-in libraries to provide lightweight dependency management. These language features offer alternatives that align more with Python's philosophy, negating the need for heavy frameworks or complex patterns often necessary in statically-typed languages .
The Facade pattern simplifies interaction with complex systems by providing a unified, simplified interface to a set of interfaces within a subsystem. In Python, this helps reduce the complexity for module users by hiding the intricate details and interdependencies of the underlying system, facilitating easier code integration and usage within larger applications. This abstraction is particularly advantageous for managing complex libraries or APIs, making them more accessible and easier to work with by end-users .
Python's dynamic typing influences the implementation of design patterns by allowing more flexibility, as you do not need to explicitly define interfaces or types, unlike statically typed languages. This can simplify the implementation of patterns like Strategy and Observer by relying on Python's duck typing, where objects are determined by their methods and properties rather than their interfaces, facilitating polymorphic behavior without inheritance .
The Decorator pattern enhances objects by wrapping them with decoratos that add additional behaviors while leaving their interfaces unchanged. This is beneficial in Python for providing flexible extension mechanisms without modifying the original code base. This is achieved by leveraging Python's first-class functions and dynamic typing to compose behaviors dynamically at runtime, facilitating extensions and modifications without subclassing, thus promoting code reuse and adherence to the open/closed principle .
The benefits of using the Singleton pattern in Python include ensuring that only one instance of a class is created and providing global access to that instance, which is useful for managing a shared resource or configuration settings. It is typically implemented by controlling the instantiation process, often with a method that checks for an existing instance before creating a new one. Python's implementation often uses module-level variables to maintain the singleton instance due to its ability to hold state across multiple function calls within a module .
The Observer pattern facilitates communication between objects in Python by establishing a subscription mechanism to allow objects, referred to as observers, to listen for and respond to events or changes in another object's state, known as the subject. In GUI components, this pattern enables decoupling the user interface updates from the component's logic by notifying multiple observer components about any state changes, thus updating their graphical representation dynamically and independently .
The Strategy pattern in Python addresses software complexity by providing a way to define a family of algorithms, encapsulate each one in a class, and make them interchangeable. It eliminates conditional statements and promotes algorithm encapsulation and interchangeability. In contrast, the Command pattern encapsulates a request as an object, enabling parameterization, queuing, logging, and undo operations. This pattern abstracts the action as an object, which can be executed later or re-executed, whereas Strategy focuses on selecting algorithms dynamically at runtime .
The Builder pattern is often considered unnecessary in Python because the language supports named parameters and default values in constructors, allowing the creation of complex objects without requiring a separate builder class. This direct support for setting optional and default parameters reduces the need for an additional pattern to handle object construction complexity, which is typically handled by the Builder pattern in languages without such features .
The State pattern manages behavioral changes by allowing an object to alter its behavior when its internal state changes. It is structured in Python by defining a 'context' class that holds a reference to a state object representing the current state. This pattern includes an abstract base class for states, with each concrete state encapsulated in a subclass that implements specific behaviors. The context class delegates state-specific behavior calls to the current state object, allowing seamless state transitions .