{"id":261,"date":"2023-04-12T23:18:52","date_gmt":"2023-04-12T23:18:52","guid":{"rendered":"https:\/\/www.w3computing.com\/articles\/?p=261"},"modified":"2023-08-23T16:21:59","modified_gmt":"2023-08-23T16:21:59","slug":"design-patterns-python-singleton-factory-observer","status":"publish","type":"post","link":"https:\/\/www.w3computing.com\/articles\/design-patterns-python-singleton-factory-observer\/","title":{"rendered":"Implementing design patterns in Python: Singleton, Factory, and Observer patterns"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Design patterns are reusable solutions to common problems that arise in software development. They provide a blueprint for solving particular design issues, allowing developers to build more efficient, maintainable, and flexible software. Design patterns are language-agnostic, but in this article, we will focus on implementing three popular design patterns in Python: the Singleton, Factory, and Observer patterns.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Python is a powerful and versatile programming language, and by utilizing design patterns, developers can improve the quality of their code and create more robust applications. This article is intended for intermediate and advanced Python developers who have a solid grasp of the language&#8217;s fundamentals and want to further enhance their skills by learning how to implement design patterns effectively.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the following sections, we will provide an in-depth explanation of the Singleton, Factory, and Observer patterns, exploring their use cases, implementation details, and real-world examples in Python. By the end of this article, you should have a deeper understanding of these design patterns and how they can be applied to improve your Python projects.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Singleton Pattern<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Singleton pattern is a creational design pattern that ensures a class has only one instance and provides a global point of access to that instance. It restricts the instantiation of a class to a single object, which can be useful when a single shared resource or a unique state is needed across the application.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Ensuring only one instance of a class<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">By implementing the Singleton pattern, developers can guarantee that a class has only one instance throughout the application&#8217;s lifetime. This is particularly useful when managing resources that should not be duplicated, such as database connections, configuration settings, or shared state between components.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Common use cases and benefits<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Some common use cases for the Singleton pattern include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Managing a single database connection to avoid the overhead of establishing multiple connections.<\/li>\n\n\n\n<li>Centralizing access to a shared resource, such as a configuration file or a logging system, to ensure consistency and avoid conflicts.<\/li>\n\n\n\n<li>Implementing a caching mechanism that holds the most frequently used data to improve performance.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The benefits of using the Singleton pattern include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Controlled access to a single instance, preventing unauthorized instantiation or modification.<\/li>\n\n\n\n<li>Reduction of resource usage and potential performance bottlenecks by reusing the single instance instead of creating multiple objects.<\/li>\n\n\n\n<li>Improved consistency and maintainability of the code, as changes to the shared resource can be made in one place.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Implementing the Singleton pattern in Python<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">There are several ways to implement the Singleton pattern in Python. Here, we will discuss three common approaches:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>1. Using a class variable and a class method:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Singleton<\/span>:<\/span>\r\n    _instance = <span class=\"hljs-literal\">None<\/span>\r\n\r\n<span class=\"hljs-meta\">    @classmethod<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">instance<\/span><span class=\"hljs-params\">(cls)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> cls._instance <span class=\"hljs-keyword\">is<\/span> <span class=\"hljs-literal\">None<\/span>:\r\n            cls._instance = cls()\r\n        <span class=\"hljs-keyword\">return<\/span> cls._instance\r\n\r\nsingleton = Singleton.instance()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this approach, we maintain a class variable <code><strong>_instance<\/strong><\/code> to store the single instance of the class. The <code><strong>instance<\/strong><\/code> class method checks if <code><strong>_instance<\/strong><\/code> is <code><strong>None<\/strong><\/code>. If so, it creates a new instance of the class and returns it. Otherwise, it returns the existing instance.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>2. Using the Borg pattern (shared state among instances):<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Borg<\/span>:<\/span>\r\n    _shared_state = {}\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        self.__dict__ = self._shared_state\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Singleton<\/span><span class=\"hljs-params\">(Borg)<\/span>:<\/span>\r\n    <span class=\"hljs-keyword\">pass<\/span>\r\n\r\nsingleton1 = Singleton()\r\nsingleton2 = Singleton()\r<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The Borg pattern allows instances of a class to share the same state, effectively making them behave like a single instance. By subclassing the <code><strong>Borg<\/strong><\/code> class, we create a Singleton class where all instances share the same state.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>3. Using the metaclass approach:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">SingletonMeta<\/span><span class=\"hljs-params\">(type)<\/span>:<\/span>\r\n    _instances = {}\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__call__<\/span><span class=\"hljs-params\">(cls, *args, **kwargs)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> cls <span class=\"hljs-keyword\">not<\/span> <span class=\"hljs-keyword\">in<\/span> cls._instances:\r\n            cls._instances&#91;cls] = super().__call__(*args, **kwargs)\r\n        <span class=\"hljs-keyword\">return<\/span> cls._instances&#91;cls]\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Singleton<\/span><span class=\"hljs-params\">(metaclass=SingletonMeta)<\/span>:<\/span>\r\n    <span class=\"hljs-keyword\">pass<\/span>\r\n\r\nsingleton = Singleton()\r<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this approach, we define a custom metaclass <code><strong>SingletonMeta<\/strong><\/code> that overrides the <code><strong>__call__<\/strong><\/code> method. This method is responsible for creating new instances of a class. By using a dictionary to store instances, we ensure that only one instance is created for each class that uses the <code><strong>SingletonMeta<\/strong><\/code> metaclass.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pros and cons of the Singleton pattern<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Benefits of using the pattern:\n<ul class=\"wp-block-list\">\n<li>Ensures a single, globally accessible instance of a class<\/li>\n\n\n\n<li>Reduces resource usage by reusing the instance<\/li>\n\n\n\n<li>Can improve consistency and maintainability of code<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Drawbacks and potential issues:\n<ul class=\"wp-block-list\">\n<li>Can be difficult to extend or modify the Singleton class<\/li>\n\n\n\n<li>May introduce global state and hidden dependencies, making code harder to test and reason about<\/li>\n\n\n\n<li>Can encourage tightly coupled code, which reduces flexibility and modularity<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Real-world examples of Singleton pattern usage in Python<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Some real-world examples of Singleton pattern usage in Python include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The <code><strong>logging<\/strong><\/code> module in the Python standard library uses a Singleton pattern to manage access to the global logger object.<\/li>\n\n\n\n<li>Django, a popular web framework, utilizes a Singleton pattern for its configuration settings, ensuring that a single instance of settings is available throughout the application.<\/li>\n\n\n\n<li>Flask, another web framework, employs the Singleton pattern for its application context to ensure that there is only one application instance per process.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Factory Pattern<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Factory pattern is a creational design pattern that provides an interface for creating objects in a superclass, allowing subclasses to determine the type of objects to be created. It promotes loose coupling by encapsulating object creation and hiding the specifics of object construction from the client.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating objects without specifying their exact class<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The Factory pattern allows clients to create objects without knowing the exact class of the object being created. This is useful when there are multiple classes with a common interface or when the client needs to work with different types of objects without having to modify the code.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Encapsulating object creation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">By encapsulating object creation, the Factory pattern makes it easier to manage dependencies, extend functionality, and replace components. Clients interact with the factory to create objects, rather than instantiating the objects directly.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Common use cases and benefits<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Some common use cases for the Factory pattern include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Managing the creation of objects in complex systems with multiple components and dependencies.<\/li>\n\n\n\n<li>Supporting multiple product families or varying object configurations.<\/li>\n\n\n\n<li>Simplifying the process of creating objects with different implementations of a common interface.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Benefits of using the Factory pattern include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Increased modularity and flexibility, as the client code is decoupled from the specific object classes.<\/li>\n\n\n\n<li>Improved maintainability, as the object creation logic is centralized and can be easily modified or extended.<\/li>\n\n\n\n<li>Easier testing, as the factory allows for easier substitution of mock objects during testing.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Implementing the Factory pattern in Python<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">There are several variations of the Factory pattern, including the Simple Factory, Factory Method, and Abstract Factory:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>1. Simple factory:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Animal<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">speak<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">pass<\/span>\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Dog<\/span><span class=\"hljs-params\">(Animal)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">speak<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">\"Woof!\"<\/span>\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Cat<\/span><span class=\"hljs-params\">(Animal)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">speak<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">\"Meow!\"<\/span>\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">AnimalFactory<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_animal<\/span><span class=\"hljs-params\">(self, animal_type)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> animal_type == <span class=\"hljs-string\">\"Dog\"<\/span>:\r\n            <span class=\"hljs-keyword\">return<\/span> Dog()\r\n        <span class=\"hljs-keyword\">elif<\/span> animal_type == <span class=\"hljs-string\">\"Cat\"<\/span>:\r\n            <span class=\"hljs-keyword\">return<\/span> Cat()\r\n        <span class=\"hljs-keyword\">else<\/span>:\r\n            <span class=\"hljs-keyword\">raise<\/span> ValueError(<span class=\"hljs-string\">\"Invalid animal type\"<\/span>)\r\n\r\nfactory = AnimalFactory()\r\nanimal = factory.create_animal(<span class=\"hljs-string\">\"Dog\"<\/span>)\r\nanimal.speak()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In the Simple Factory pattern, a separate class (e.g., <code><strong>AnimalFactory<\/strong><\/code>) is responsible for creating objects based on a parameter (e.g., <code><strong>animal_type<\/strong><\/code>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>2. Factory method:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> abc <span class=\"hljs-keyword\">import<\/span> ABC, abstractmethod\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Animal<\/span><span class=\"hljs-params\">(ABC)<\/span>:<\/span>\r\n<span class=\"hljs-meta\">    @abstractmethod<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">speak<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">pass<\/span>\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Dog<\/span><span class=\"hljs-params\">(Animal)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">speak<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">\"Woof!\"<\/span>\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Cat<\/span><span class=\"hljs-params\">(Animal)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">speak<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">\"Meow!\"<\/span>\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">AnimalCreator<\/span><span class=\"hljs-params\">(ABC)<\/span>:<\/span>\r\n<span class=\"hljs-meta\">    @abstractmethod<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_animal<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">pass<\/span>\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">DogCreator<\/span><span class=\"hljs-params\">(AnimalCreator)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_animal<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> Dog()\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CatCreator<\/span><span class=\"hljs-params\">(AnimalCreator)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_animal<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> Cat()\r\n\r\ndog_creator = DogCreator()\r\ndog = dog_creator.create_animal()\r\ndog.speak()\r<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In the Factory Method pattern, the object creation logic is encapsulated within a method in a creator class (e.g., <code><strong>DogCreator<\/strong><\/code> and <code><strong>CatCreator<\/strong><\/code>). This allows for greater flexibility and customization in the object creation process.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>3. Abstract factory:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> abc <span class=\"hljs-keyword\">import<\/span> ABC, abstractmethod\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Animal<\/span><span class=\"hljs-params\">(ABC)<\/span>:<\/span>\r\n<span class=\"hljs-meta\">    @abstractmethod<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">speak<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">pass<\/span>\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Dog<\/span><span class=\"hljs-params\">(Animal)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">speak<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">\"Woof!\"<\/span>\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Cat<\/span><span class=\"hljs-params\">(Animal)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">speak<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">\"Meow!\"<\/span>\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">AnimalFactory<\/span><span class=\"hljs-params\">(ABC)<\/span>:<\/span>\r\n<span class=\"hljs-meta\">    @abstractmethod<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_animal<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">pass<\/span>\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">DogFactory<\/span><span class=\"hljs-params\">(AnimalFactory)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_animal<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> Dog()\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CatFactory<\/span><span class=\"hljs-params\">(AnimalFactory)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_animal<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">return<\/span> Cat()\r\n\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">get_factory<\/span><span class=\"hljs-params\">(factory_type)<\/span>:<\/span>\r\n    <span class=\"hljs-keyword\">if<\/span> factory_type == <span class=\"hljs-string\">\"Dog\"<\/span>:\r\n        <span class=\"hljs-keyword\">return<\/span> DogFactory()\r\n    <span class=\"hljs-keyword\">elif<\/span> factory_type == <span class=\"hljs-string\">\"Cat\"<\/span>:\r\n        <span class=\"hljs-keyword\">return<\/span> CatFactory()\r\n    <span class=\"hljs-keyword\">else<\/span>:\r\n        <span class=\"hljs-keyword\">raise<\/span> ValueError(<span class=\"hljs-string\">\"Invalid factory type\"<\/span>)\r\n\r\nfactory = get_factory(<span class=\"hljs-string\">\"Dog\"<\/span>)\r\nanimal = factory.create_animal()\r\nanimal.speak()\r<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The Abstract Factory pattern involves a higher level of abstraction, where factories themselves are created using another factory function or class (e.g., <code>get_factory<\/code>). This allows for even greater flexibility in object creation and better separation of concerns.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pros and cons of the Factory pattern<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Benefits of using the pattern:\n<ul class=\"wp-block-list\">\n<li>Decouples object creation from client code, promoting modularity and flexibility.<\/li>\n\n\n\n<li>Simplifies the process of adding new object types to an application.<\/li>\n\n\n\n<li>Centralizes object creation logic, making the code more maintainable.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li>Drawbacks and potential issues:\n<ul class=\"wp-block-list\">\n<li>Can lead to an increase in the number of classes, making the code more complex.<\/li>\n\n\n\n<li>May introduce unnecessary layers of abstraction if the object creation process is not complex or if there are only a few object types.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Real-world examples of Factory pattern usage in Python<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Some real-world examples of Factory pattern usage in Python include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Django, a popular web framework, uses the Factory pattern in its form handling system. The form factory allows developers to create form instances dynamically based on the provided form class and data.<\/li>\n\n\n\n<li>The <code><strong>unittest<\/strong><\/code> module in the Python standard library employs the Factory pattern for creating test case instances. The <code><strong>TestLoader<\/strong><\/code> class uses a factory method to instantiate test cases based on test methods found in the test classes.<\/li>\n\n\n\n<li>SQLAlchemy, a powerful Object Relational Mapper (ORM), uses the Factory pattern to create specific dialect objects based on the provided database connection information. This allows the ORM to work seamlessly with different databases without the client code having to manage the creation of database-specific objects.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Observer Pattern<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Observer pattern is a behavioral design pattern that defines a one-to-many dependency between objects, such that when one object (the subject) changes its state, all its dependent objects (observers) are notified and updated automatically.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">One-to-many dependency between objects<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The Observer pattern establishes a one-to-many relationship between a subject and multiple observers. The subject maintains a list of its observers and notifies them whenever its state changes, allowing them to respond accordingly.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Automatic notification of state changes<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">By implementing the Observer pattern, subjects can notify their observers about state changes automatically, without the need for observers to poll the subject or check for updates. This promotes loose coupling between the subject and its observers, making the system more maintainable and scalable.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Common use cases and benefits<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Some common use cases for the Observer pattern include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Updating multiple UI components when the underlying data model changes.<\/li>\n\n\n\n<li>Distributing notifications or events in event-driven systems.<\/li>\n\n\n\n<li>Implementing a publish-subscribe mechanism for asynchronous communication between components.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The benefits of using the Observer pattern include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Loose coupling between subjects and observers, making the system more modular and maintainable.<\/li>\n\n\n\n<li>Automatic propagation of state changes, reducing the need for manual updates or polling.<\/li>\n\n\n\n<li>Improved scalability, as new observers can be added or removed easily without modifying the subject.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Implementing the Observer pattern in Python<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>1. Using a custom implementation:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Subject<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        self._observers = &#91;]\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">attach<\/span><span class=\"hljs-params\">(self, observer)<\/span>:<\/span>\r\n        self._observers.append(observer)\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">detach<\/span><span class=\"hljs-params\">(self, observer)<\/span>:<\/span>\r\n        self._observers.remove(observer)\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">notify<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">for<\/span> observer <span class=\"hljs-keyword\">in<\/span> self._observers:\r\n            observer.update(self)\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Observer<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">update<\/span><span class=\"hljs-params\">(self, subject)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">pass<\/span>\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ConcreteObserver<\/span><span class=\"hljs-params\">(Observer)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">update<\/span><span class=\"hljs-params\">(self, subject)<\/span>:<\/span>\r\n        print(<span class=\"hljs-string\">\"State changed:\"<\/span>, subject.state)\r\n\r\nsubject = Subject()\r\nobserver = ConcreteObserver()\r\nsubject.attach(observer)\r\nsubject.state = <span class=\"hljs-number\">42<\/span>\r\nsubject.notify()\r<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this custom implementation, the <code><strong>Subject<\/strong><\/code> class maintains a list of observers and provides methods to attach, detach, and notify them. The <code><strong>Observer<\/strong><\/code> class defines an abstract <code><strong>update<\/strong><\/code> method, which concrete observers implement to handle notifications.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>2. Using Python&#8217;s built-in Observer pattern support:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Python provides built-in support for the Observer pattern through the <code><strong>Observable<\/strong><\/code> class and the <code><strong>Observer<\/strong><\/code> interface in the <code><strong>observer<\/strong><\/code> module (available in Python 3.11+).<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> observer <span class=\"hljs-keyword\">import<\/span> Observable, Observer\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ConcreteObserver<\/span><span class=\"hljs-params\">(Observer)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">update<\/span><span class=\"hljs-params\">(self, observable, *args, **kwargs)<\/span>:<\/span>\r\n        print(<span class=\"hljs-string\">\"State changed:\"<\/span>, observable.state)\r\n\r\nsubject = Observable()\r\nobserver = ConcreteObserver()\r\nsubject.add_observer(observer)\r\nsubject.state = <span class=\"hljs-number\">42<\/span>\r\nsubject.notify_observers()\r<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\"><strong>3. Observer pattern with decorators:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Observer pattern can also be implemented using decorators, which can simplify the code and make it more Pythonic.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Subject<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\r\n        self._observers = &#91;]\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">attach<\/span><span class=\"hljs-params\">(self, observer)<\/span>:<\/span>\r\n        self._observers.append(observer)\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">detach<\/span><span class=\"hljs-params\">(self, observer)<\/span>:<\/span>\r\n        self._observers.remove(observer)\r\n\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">notify<\/span><span class=\"hljs-params\">(self, func)<\/span>:<\/span>\r\n        <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">wrapper<\/span><span class=\"hljs-params\">(*args, **kwargs)<\/span>:<\/span>\r\n            result = func(*args, **kwargs)\r\n            <span class=\"hljs-keyword\">for<\/span> observer <span class=\"hljs-keyword\">in<\/span> self._observers:\r\n                observer.update(self)\r\n            <span class=\"hljs-keyword\">return<\/span> result\r\n        <span class=\"hljs-keyword\">return<\/span> wrapper\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Observer<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">update<\/span><span class=\"hljs-params\">(self, subject)<\/span>:<\/span>\r\n        <span class=\"hljs-keyword\">pass<\/span>\r\n\r\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ConcreteObserver<\/span><span class=\"hljs-params\">(Observer)<\/span>:<\/span>\r\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">update<\/span><span class=\"hljs-params\">(self, subject)<\/span>:<\/span>\r\n        print(<span class=\"hljs-string\">\"State changed:\"<\/span>, subject.state)\r\n\r\nsubject = Subject()\r\nobserver = ConcreteObserver()\r\nsubject.attach(observer)\r\n\r\n<span class=\"hljs-meta\">@subject.notify<\/span>\r\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">change_state<\/span><span class=\"hljs-params\">(subject, new_state)<\/span>:<\/span>\r\n    subject.state = new_state\r\n\r\nchange_state(subject, <span class=\"hljs-number\">42<\/span>)\r<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this implementation, the <code><strong>Subject<\/strong><\/code> class defines a <code><strong>notify<\/strong><\/code> method that acts as a decorator. The decorator wraps a function, in this case <code><strong>change_state<\/strong><\/code>, to automatically notify the observers when the function is called. The <code><strong>Observer<\/strong><\/code> and <code><strong>ConcreteObserver<\/strong><\/code> classes remain the same as in the previous examples.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pros and cons of the Observer pattern<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Benefits of using the pattern:\n<ul class=\"wp-block-list\">\n<li>Promotes loose coupling between subjects and observers, making the system more modular and maintainable.<\/li>\n\n\n\n<li>Enables automatic propagation of state changes, reducing the need for manual updates or polling.<\/li>\n\n\n\n<li>Simplifies adding or removing observers without modifying the subject&#8217;s code.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Drawbacks and potential issues:\n<ul class=\"wp-block-list\">\n<li>Can introduce complexity, especially when dealing with multiple subjects and observers.<\/li>\n\n\n\n<li>May lead to performance issues if a large number of observers need to be notified or if the update process is computationally expensive.<\/li>\n\n\n\n<li>Can be difficult to ensure the order of notification and updates when dealing with dependencies between observers.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Real-world examples of Observer pattern usage in Python<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Some real-world examples of Observer pattern usage in Python include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The Model-View-Controller (MVC) architectural pattern, where the model (data) acts as a subject and the views (UI components) act as observers. When the model&#8217;s state changes, the views are updated automatically.<\/li>\n\n\n\n<li>Event-driven systems, such as GUI frameworks (e.g., Tkinter) or web frameworks (e.g., Django), where components register as observers to respond to specific events or signals.<\/li>\n\n\n\n<li>Reactive programming libraries, such as RxPy, which use the Observer pattern to model data streams and propagate changes through a chain of operators.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Best Practices for Implementing Design Patterns<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When implementing design patterns, it&#8217;s essential to prioritize code readability and maintainability. To achieve this, consider the following guidelines:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Use clear and descriptive names for classes, methods, and variables.<\/li>\n\n\n\n<li>Add comments and documentation to explain the purpose and functioning of the pattern.<\/li>\n\n\n\n<li>Apply consistent code formatting and adhere to established style guides, such as PEP 8 for Python.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">While design patterns provide valuable solutions to common problems, it&#8217;s important to balance their use with other software development principles. Keep in mind the following:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Adhere to the SOLID principles, which promote the design of maintainable and scalable software systems.<\/li>\n\n\n\n<li>Consider the trade-offs between flexibility and simplicity when choosing to apply a design pattern.<\/li>\n\n\n\n<li>Don&#8217;t overuse design patterns; apply them only when they genuinely solve a problem or improve the system&#8217;s design.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Design patterns are not one-size-fits-all solutions; they may need to be adapted to suit the unique requirements of a project. To do this effectively:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Understand the problem domain and specific needs of the project before selecting a design pattern.<\/li>\n\n\n\n<li>Customize the pattern to address the project&#8217;s requirements while retaining the core principles of the pattern.<\/li>\n\n\n\n<li>Be open to combining or modifying patterns to create hybrid solutions that better serve the project&#8217;s needs.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Coclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This article provided an overview of three widely used design patterns in Python: Singleton, Factory, and Observer. The Singleton pattern ensures that a class has only one instance and provides a global point of access to that instance. The Factory pattern enables the creation of objects without specifying their exact classes and encapsulates object creation. The Observer pattern defines a one-to-many dependency between objects, automatically notifying observers when the subject&#8217;s state changes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are many other design patterns to explore, each addressing specific challenges and providing valuable insights into software design. By studying and implementing various design patterns in your Python projects, you can enhance your skills as a developer, create more robust and efficient software, and better tackle complex problems.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Design patterns are reusable solutions to common problems that arise in software development. They provide a blueprint for solving particular design issues, allowing developers to build more efficient, maintainable, and flexible software. Design patterns are language-agnostic, but in this article, we will focus on implementing three popular design patterns in Python: the Singleton, Factory, and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4,6],"tags":[],"class_list":["post-261","post","type-post","status-publish","format-standard","category-programming-languages","category-python","entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Design patterns in Python: Singleton, Factory, and Observer<\/title>\n<meta name=\"description\" content=\"Design patterns are reusable solutions to common problems that arise in software development. They provide a blueprint for solving particular\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.w3computing.com\/articles\/design-patterns-python-singleton-factory-observer\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Design patterns in Python: Singleton, Factory, and Observer\" \/>\n<meta property=\"og:description\" content=\"Design patterns are reusable solutions to common problems that arise in software development. They provide a blueprint for solving particular\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.w3computing.com\/articles\/design-patterns-python-singleton-factory-observer\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-04-12T23:18:52+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-08-23T16:21:59+00:00\" \/>\n<meta name=\"author\" content=\"w3compadmin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"w3compadmin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/design-patterns-python-singleton-factory-observer\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/design-patterns-python-singleton-factory-observer\\\/\"},\"author\":{\"name\":\"w3compadmin\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"headline\":\"Implementing design patterns in Python: Singleton, Factory, and Observer patterns\",\"datePublished\":\"2023-04-12T23:18:52+00:00\",\"dateModified\":\"2023-08-23T16:21:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/design-patterns-python-singleton-factory-observer\\\/\"},\"wordCount\":2196,\"commentCount\":0,\"articleSection\":[\"Programming Languages\",\"Python\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/design-patterns-python-singleton-factory-observer\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/design-patterns-python-singleton-factory-observer\\\/\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/design-patterns-python-singleton-factory-observer\\\/\",\"name\":\"Design patterns in Python: Singleton, Factory, and Observer\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\"},\"datePublished\":\"2023-04-12T23:18:52+00:00\",\"dateModified\":\"2023-08-23T16:21:59+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"description\":\"Design patterns are reusable solutions to common problems that arise in software development. They provide a blueprint for solving particular\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/design-patterns-python-singleton-factory-observer\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/design-patterns-python-singleton-factory-observer\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/design-patterns-python-singleton-factory-observer\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Articles Home\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Programming Languages\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/programming-languages\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Implementing design patterns in Python: Singleton, Factory, and Observer patterns\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\",\"name\":\"Developer Articles Hub\",\"description\":\"\",\"alternateName\":\"Developer Articles\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\",\"name\":\"w3compadmin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"contentUrl\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"caption\":\"w3compadmin\"},\"sameAs\":[\"http:\\\/\\\/w3computing.com\\\/articles\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Design patterns in Python: Singleton, Factory, and Observer","description":"Design patterns are reusable solutions to common problems that arise in software development. They provide a blueprint for solving particular","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.w3computing.com\/articles\/design-patterns-python-singleton-factory-observer\/","og_locale":"en_US","og_type":"article","og_title":"Design patterns in Python: Singleton, Factory, and Observer","og_description":"Design patterns are reusable solutions to common problems that arise in software development. They provide a blueprint for solving particular","og_url":"https:\/\/www.w3computing.com\/articles\/design-patterns-python-singleton-factory-observer\/","article_published_time":"2023-04-12T23:18:52+00:00","article_modified_time":"2023-08-23T16:21:59+00:00","author":"w3compadmin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"w3compadmin","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.w3computing.com\/articles\/design-patterns-python-singleton-factory-observer\/#article","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/design-patterns-python-singleton-factory-observer\/"},"author":{"name":"w3compadmin","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"headline":"Implementing design patterns in Python: Singleton, Factory, and Observer patterns","datePublished":"2023-04-12T23:18:52+00:00","dateModified":"2023-08-23T16:21:59+00:00","mainEntityOfPage":{"@id":"https:\/\/www.w3computing.com\/articles\/design-patterns-python-singleton-factory-observer\/"},"wordCount":2196,"commentCount":0,"articleSection":["Programming Languages","Python"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.w3computing.com\/articles\/design-patterns-python-singleton-factory-observer\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.w3computing.com\/articles\/design-patterns-python-singleton-factory-observer\/","url":"https:\/\/www.w3computing.com\/articles\/design-patterns-python-singleton-factory-observer\/","name":"Design patterns in Python: Singleton, Factory, and Observer","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/#website"},"datePublished":"2023-04-12T23:18:52+00:00","dateModified":"2023-08-23T16:21:59+00:00","author":{"@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"description":"Design patterns are reusable solutions to common problems that arise in software development. They provide a blueprint for solving particular","breadcrumb":{"@id":"https:\/\/www.w3computing.com\/articles\/design-patterns-python-singleton-factory-observer\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.w3computing.com\/articles\/design-patterns-python-singleton-factory-observer\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.w3computing.com\/articles\/design-patterns-python-singleton-factory-observer\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Articles Home","item":"https:\/\/www.w3computing.com\/articles\/"},{"@type":"ListItem","position":2,"name":"Programming Languages","item":"https:\/\/www.w3computing.com\/articles\/programming-languages\/"},{"@type":"ListItem","position":3,"name":"Implementing design patterns in Python: Singleton, Factory, and Observer patterns"}]},{"@type":"WebSite","@id":"https:\/\/www.w3computing.com\/articles\/#website","url":"https:\/\/www.w3computing.com\/articles\/","name":"Developer Articles Hub","description":"","alternateName":"Developer Articles","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.w3computing.com\/articles\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561","name":"w3compadmin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","url":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","contentUrl":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","caption":"w3compadmin"},"sameAs":["http:\/\/w3computing.com\/articles"]}]}},"featured_image_src":null,"featured_image_src_square":null,"author_info":{"display_name":"w3compadmin","author_link":"https:\/\/www.w3computing.com\/articles\/author\/w3compadmin\/"},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/261","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/comments?post=261"}],"version-history":[{"count":4,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/261\/revisions"}],"predecessor-version":[{"id":265,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/261\/revisions\/265"}],"wp:attachment":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/media?parent=261"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/categories?post=261"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/tags?post=261"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}