├── .idea ├── Python-Design-Patterns.iml ├── misc.xml ├── modules.xml └── vcs.xml ├── Behavioral ├── command.py ├── command_example.py ├── command_example_1.py ├── observer.py ├── observer_example.py ├── state.py └── template.py ├── BingSiteAuth.xml ├── Creational ├── abstract_factory.py ├── factory.py ├── lazy_instantiation_singleton.py ├── singleton.py ├── singleton_example.py └── singleton_with_metaclass.py ├── Model View Controller └── MVC.py ├── README.md ├── Structural ├── adapter.py ├── facade.py └── proxy.py ├── _config.yml ├── googlea86b5cd8b12ff6a4.html └── index.html /.idea/Python-Design-Patterns.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Behavioral/command.py: -------------------------------------------------------------------------------- 1 | # ---------------- 2 | # Command Pattern. 3 | # ---------------- 4 | # Encapsulate a request as an object, thereby allowing for the parameterization of clients with different requests, 5 | # and the queuing or logging of requests. It also allows for the support of undoable operations. 6 | 7 | from abc import ABC, abstractmethod 8 | 9 | class Command(ABC): 10 | def __init__(self, receiver): 11 | self.receiver = receiver 12 | 13 | def process(self): 14 | pass 15 | 16 | class CommandImplementation(Command): 17 | def __init__(self, receiver): 18 | self.receiver = receiver 19 | 20 | def process(self): 21 | self.receiver.perform_action() 22 | 23 | 24 | class Receiver: 25 | def perform_action(self): 26 | print('Action performed in receiver.') 27 | 28 | class Invoker: 29 | def command(self, cmd): 30 | self.cmd = cmd 31 | 32 | def execute(self): 33 | self.cmd.process() 34 | 35 | 36 | 37 | receiver = Receiver() 38 | cmd = CommandImplementation(receiver) 39 | invoker = Invoker() 40 | invoker.command(cmd) 41 | invoker.execute() 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Behavioral/command_example.py: -------------------------------------------------------------------------------- 1 | # ---------------- 2 | # Command Pattern. 3 | # ---------------- 4 | # Encapsulate a request as an object, thereby allowing for the parameterization of clients with different requests, 5 | # and the queuing or logging of requests. It also allows for the support of undoable operations. 6 | 7 | class Installer: 8 | def __init__(self, source, dir): 9 | self.options = [] 10 | self.dir = dir 11 | self.source = source 12 | 13 | def add_preferences(self, cmd): 14 | self.options.append(cmd) 15 | 16 | def install(self): 17 | for option in self.options: 18 | value = [v for k, v in option.items()] 19 | 20 | if (value[0]): 21 | print("installing files -- ", [k for k, v in option.items()], self.source, " to ", self.dir) 22 | else: 23 | print('Not installed: ', [k for k, v in option.items()]) 24 | 25 | installer = Installer('C++ binaries', 'c:\\c++\\binaries') 26 | installer.add_preferences({'c++':True}) 27 | installer.add_preferences({'c#': False}) 28 | installer.install() 29 | 30 | -------------------------------------------------------------------------------- /Behavioral/command_example_1.py: -------------------------------------------------------------------------------- 1 | # ----------------------- 2 | # Command pattern example. 3 | # ------------------------ 4 | # Encapsulate a request as an object, thereby allowing for the parameterization of clients with different requests, 5 | # and the queuing or logging of requests. It also allows for the support of undoable operations. 6 | 7 | from abc import ABC, abstractmethod 8 | 9 | #--------------------------- 10 | # Abstract Command class 11 | #--------------------------- 12 | class Order(ABC): 13 | 14 | @abstractmethod 15 | def process(self): 16 | pass 17 | 18 | #--------------------------- 19 | # Concrete Command class 20 | #--------------------------- 21 | class BuyStock(Order): 22 | def __init__(self, stock): 23 | self.stock = stock 24 | 25 | def process(self): 26 | self.stock.buy() 27 | 28 | #--------------------------- 29 | # Concrete Command class 30 | #--------------------------- 31 | class SellStock(Order): 32 | def __init__(self, stock): 33 | self.stock = stock 34 | 35 | def process(self): 36 | self.stock.sell() 37 | 38 | #--------------------------- 39 | # Receiver class 40 | #--------------------------- 41 | class Trade: 42 | def buy(self): 43 | print("Stock buy request placed.") 44 | 45 | def sell(self): 46 | print("Stock sell request placed.") 47 | 48 | 49 | class Invoker: 50 | def __init__(self): 51 | self._queue = [] 52 | 53 | def process_order(self, order): 54 | self._queue.append(order) 55 | order.process() 56 | 57 | trade = Trade() 58 | buy_stock = BuyStock(trade) 59 | sell_stock = SellStock(trade) 60 | 61 | invoker = Invoker() 62 | invoker.process_order(buy_stock) 63 | invoker.process_order(sell_stock) 64 | -------------------------------------------------------------------------------- /Behavioral/observer.py: -------------------------------------------------------------------------------- 1 | # ------------------------------ 2 | # Observer Design Pattern 3 | # ------------------------------ 4 | # Define a one-to-many dependency between objects 5 | # where a state change in one object results in all its dependents being notified and updated automatically. 6 | 7 | 8 | class Subject: 9 | def __init__(self): 10 | self.__observers = [] 11 | 12 | def register(self, observer): 13 | self.__observers.append(observer) 14 | 15 | def notify(self, *args, **kwargs): 16 | for observer in self.__observers: 17 | observer.notify(self, *args, **kwargs) 18 | 19 | 20 | class Observer1: 21 | def __init__(self, subject): 22 | subject.register(self) 23 | 24 | def notify(self, subject, *args): 25 | print(type(self).__name__,': Got', args, 'From', subject) 26 | 27 | 28 | class Observer2: 29 | def __init__(self, subject): 30 | subject.register(self) 31 | 32 | def notify(self, subject, *args): 33 | print(type(self).__name__, ': Got', args, 'From', subject) 34 | 35 | 36 | subject = Subject() 37 | 38 | # ---------------------------- 39 | # Registers observer with subject 40 | #-------------------------------- 41 | observer1 = Observer1(subject) 42 | observer2 = Observer2(subject) 43 | 44 | subject.notify('Notification.') 45 | 46 | -------------------------------------------------------------------------------- /Behavioral/observer_example.py: -------------------------------------------------------------------------------- 1 | 2 | # --------------------------------------------------- 3 | # Observer Pattern in publisher and subscriber model. 4 | # --------------------------------------------------- 5 | from abc import ABC, abstractmethod 6 | 7 | class Publisher: 8 | def __init__(self): 9 | self.__subscribers = [] 10 | self.__content = None 11 | 12 | def attach(self, subscriber): 13 | self.__subscribers.append(subscriber) 14 | 15 | def detach(self): 16 | self.__subscribers.pop() 17 | 18 | def get_subscribers(self): 19 | return[type(x).__name__ for x in self.__subscribers] 20 | 21 | def updateSubscribers(self): 22 | for sub in self.__subscribers: 23 | sub.update() 24 | 25 | def add_content(self, content): 26 | self.__content = content 27 | 28 | def get_content(self): 29 | return ("Content:" + self.__content) 30 | 31 | # ------------------------------------- 32 | # Subscriber base class 33 | # ------------------------------------- 34 | class Subscriber(ABC): 35 | 36 | @abstractmethod 37 | def update(self): 38 | pass 39 | 40 | # -------------------- 41 | # Subscriber 1 42 | # -------------------- 43 | class SiteSubscriber(Subscriber): 44 | def __init__(self, publisher): 45 | self.publisher = publisher 46 | self.publisher.attach(self) 47 | 48 | def update(self): 49 | print(type(self).__name__, self.publisher.get_content()) 50 | 51 | # -------------------- 52 | # Subscriber 2 53 | # -------------------- 54 | class IntranetSubscriber(Subscriber): 55 | def __init__(self, publisher): 56 | self.publisher = publisher 57 | self.publisher.attach(self) 58 | 59 | def update(self): 60 | print(type(self).__name__, self.publisher.get_content()) 61 | 62 | # -------------------- 63 | # Subscriber 3 64 | # -------------------- 65 | class ApiSubscriber(Subscriber): 66 | def __init__(self, publisher): 67 | self.publisher = publisher 68 | self.publisher.attach(self) 69 | 70 | def update(self): 71 | print(type(self).__name__, self.publisher.get_content()) 72 | 73 | 74 | 75 | publisher = Publisher() 76 | 77 | for subs in [SiteSubscriber, IntranetSubscriber, ApiSubscriber]: 78 | subs(publisher) 79 | 80 | print("All Subscriber: ", publisher.get_subscribers()) 81 | print("------------------------------------------------") 82 | 83 | publisher.add_content('Update content on all subscribers.') 84 | publisher.updateSubscribers() 85 | 86 | print("------------------------------------------------") 87 | 88 | publisher.detach() 89 | 90 | print("Remaining Subscriber: ", publisher.get_subscribers()) 91 | print("------------------------------------------------") 92 | 93 | publisher.add_content('Updated content for remaining subscriber.') 94 | publisher.updateSubscribers() 95 | 96 | -------------------------------------------------------------------------------- /Behavioral/state.py: -------------------------------------------------------------------------------- 1 | # ------------------------------ 2 | # State Design Pattern 3 | # ------------------------------ 4 | # Allow an object to alter its behavior when its internal state changes. The object will appear to change its class. 5 | 6 | from abc import ABC, abstractmethod 7 | 8 | class State(ABC): 9 | def handle_state(self): 10 | pass 11 | 12 | class StateA(State): 13 | def handle_state(self): 14 | print('State changed to StateA.') 15 | 16 | class StateB(State): 17 | def handle_state(self): 18 | print('State changed to StateB.') 19 | 20 | class Context(State): 21 | def __init__(self): 22 | self.state = None 23 | 24 | def set_state(self, state): 25 | self.state = state 26 | 27 | def handle_state(self): 28 | self.state.handle_state() 29 | 30 | 31 | context = Context() 32 | stateA = StateA() 33 | context.set_state(stateA) 34 | context.handle_state() 35 | 36 | print('-------------------------------------') 37 | 38 | stateB = StateB() 39 | context.set_state(stateB) 40 | context.handle_state() 41 | 42 | -------------------------------------------------------------------------------- /Behavioral/template.py: -------------------------------------------------------------------------------- 1 | # ------------------------------ 2 | # Template Design Pattern. 3 | # ------------------------------ 4 | # Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template method lets subclasses 5 | # redefine certain steps of an algorithm without changing the algorithm's structure 6 | 7 | from abc import ABC, abstractmethod 8 | 9 | class Template(ABC): 10 | def __init__(self): 11 | pass 12 | 13 | @abstractmethod 14 | def function1(self): 15 | pass 16 | 17 | @abstractmethod 18 | def function2(self): 19 | pass 20 | 21 | def execute(self): 22 | print("Run function1 and function2.") 23 | self.function1() 24 | self.function2() 25 | 26 | 27 | class TemplateImplementation1(Template): 28 | def function1(self): 29 | print("TemplateImplementation1.function1() called.") 30 | 31 | 32 | def function2(self): 33 | print("TemplateImplementation1.function2() called.") 34 | 35 | 36 | class TemplateImplementation2(Template): 37 | def function1(self): 38 | print("TemplateImplementation2.function1() called.") 39 | 40 | 41 | def function2(self): 42 | print("TemplateImplementation2.function2() called.") 43 | 44 | 45 | template_implementation11 = TemplateImplementation1() 46 | template_implementation11.execute() 47 | 48 | print("-----------------------------------------------") 49 | 50 | template_implementation12 = TemplateImplementation2() 51 | template_implementation12.execute() 52 | 53 | 54 | -------------------------------------------------------------------------------- /BingSiteAuth.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9D532204371A618F6ACAC140B3CE779B 4 | -------------------------------------------------------------------------------- /Creational/abstract_factory.py: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------------------------------------------------------------- 2 | # Abstract Factory example: Web and intranet are two different applications. Both use Sql And No SQL databases, 3 | # Web uses mongodb and SQL but intranet uses Oracle and OrientDB. Both have different implementations. 4 | # ----------------------------------------------------------------------------------------------------------------- 5 | 6 | from abc import ABC, abstractmethod 7 | 8 | class db_factory(ABC): 9 | @abstractmethod 10 | def create_no_sql_db(self): 11 | pass 12 | @abstractmethod 13 | def create_sql_db(self): 14 | pass 15 | 16 | class web_factory(db_factory): 17 | def create_no_sql_db(self): 18 | return mongodb() 19 | def create_sql_db(self): 20 | return SQL() 21 | 22 | class intranet_factory(db_factory): 23 | def create_no_sql_db(self): 24 | return orientdb() 25 | def create_sql_db(self): 26 | return Oracle() 27 | 28 | 29 | class sql_database(ABC): 30 | @abstractmethod 31 | def save(self): 32 | pass 33 | 34 | @abstractmethod 35 | def select(self): 36 | pass 37 | 38 | class SQL(sql_database): 39 | def save(self): 40 | print ("SQL save called.") 41 | def select(self): 42 | print("SQL select called.") 43 | 44 | class Oracle(sql_database): 45 | def save(self): 46 | print ("Oracle save called.") 47 | def select(self): 48 | print("Oracle select called") 49 | 50 | 51 | class no_sql_database(ABC): 52 | @abstractmethod 53 | def insert(self): 54 | pass 55 | @abstractmethod 56 | def get_object(self): 57 | pass 58 | 59 | class mongodb(no_sql_database): 60 | def insert(self): 61 | print("mongodb insert called.") 62 | def get_object(self): 63 | print("mongodb get_object called.") 64 | 65 | class orientdb(no_sql_database): 66 | def insert(self): 67 | print("orientdb insert called.") 68 | def get_object(self): 69 | print("orientdb get_object called.") 70 | 71 | 72 | 73 | class client: 74 | def get_database(self): 75 | abs_factory = web_factory() 76 | sql_factory = abs_factory.create_sql_db() 77 | sql_factory.save() 78 | sql_factory.select() 79 | 80 | # ------------------------------------------- 81 | abs_factory = web_factory() 82 | sql_factory = abs_factory.create_no_sql_db() 83 | sql_factory.insert() 84 | sql_factory.get_object() 85 | 86 | # ------------------------------------------- 87 | abs_factory = intranet_factory() 88 | ora_factory = abs_factory.create_sql_db() 89 | ora_factory.save() 90 | ora_factory.select() 91 | 92 | # ------------------------------------------- 93 | abs_factory = intranet_factory() 94 | ora_factory = abs_factory.create_no_sql_db() 95 | ora_factory.insert() 96 | ora_factory.get_object() 97 | 98 | 99 | 100 | 101 | client = client() 102 | client.get_database() 103 | -------------------------------------------------------------------------------- /Creational/factory.py: -------------------------------------------------------------------------------- 1 | # --------------------------------------------------------------------------------------------------- 2 | # Gang of Four definition 3 | # --------------------------------------------------------------------------------------------------- 4 | # Define an interface for creating an object, but let subclasses decide which class to instantiate. 5 | # The Factory method lets a class defer instantiation it uses to subclasses. 6 | # 7 | # In example, client code is deciding about object instantiation. 8 | # --------------------------------------------------------------------------------------------------- 9 | 10 | from abc import ABC, abstractmethod 11 | 12 | class Database(ABC): 13 | @abstractmethod 14 | def connection(self): 15 | pass 16 | 17 | class SqlServer: 18 | def connection(self): 19 | return('Sql database connection') 20 | 21 | 22 | class Oracle: 23 | def connection(self): 24 | return('Oracle database connecction.') 25 | 26 | 27 | class DbFactory: 28 | def get_database_connection(self, database): 29 | return database.connection() 30 | 31 | 32 | # Client Code 33 | # ----------------------------- 34 | factory = DbFactory() 35 | print(factory.get_database_connection(SqlServer())) 36 | print(factory.get_database_connection(Oracle())) 37 | -------------------------------------------------------------------------------- /Creational/lazy_instantiation_singleton.py: -------------------------------------------------------------------------------- 1 | # Lazy instantiation in Singleton Pattern 2 | # --------------------------------------- 3 | class Singleton: 4 | __instance = None 5 | def __init__(self): 6 | if not Singleton.__instance: 7 | print("__init__ method called.") 8 | else: 9 | print("Instance already created.", self.getInstance()) 10 | 11 | @classmethod 12 | def getInstance(cls): 13 | if not cls.__instance: 14 | cls.__instance=Singleton() 15 | return cls.__instance 16 | 17 | 18 | # Class is initialized and object is not created yet. 19 | s = Singleton() 20 | 21 | print ("Object created:", Singleton.getInstance()) 22 | 23 | # instance already created. 24 | s1 = Singleton() 25 | 26 | -------------------------------------------------------------------------------- /Creational/singleton.py: -------------------------------------------------------------------------------- 1 | 2 | # ----------------------------------------------------------------------- 3 | # Singleton Pattern 4 | # ----------------------------------------------------------------------- 5 | # singleton pattern restricts the instantiation of a class to one object. 6 | # ----------------------------------------------------------------------- 7 | 8 | 9 | class Singleton(object): 10 | def __new__(cls): 11 | if not hasattr(cls, 'instance'): 12 | cls.instance = super(Singleton, cls).__new__(cls) 13 | return cls.instance 14 | 15 | 16 | 17 | # s1 and s2 will refer to same object. 18 | # ---------------------------------------- 19 | s1 = Singleton() 20 | print("First object", s1) 21 | 22 | s2 = Singleton() 23 | print("Second object", s2) 24 | -------------------------------------------------------------------------------- /Creational/singleton_example.py: -------------------------------------------------------------------------------- 1 | # Implementation of Singleton Pattern for Database connection. 2 | # ------------------------------------------------------------- 3 | 4 | import sqlite3 5 | 6 | class MetaSingleton(type): 7 | _instances = {} 8 | 9 | def __call__(cls, *args, **kwargs): 10 | if cls not in cls._instances: 11 | cls._instances[cls] = super(MetaSingleton, cls).__call__(*args, **kwargs) 12 | return cls._instances[cls] 13 | 14 | 15 | class Database(metaclass=MetaSingleton): 16 | connection = None 17 | def connect(self): 18 | if self.connection is None: 19 | self.connection = sqlite3.connect("db.sqllite3") 20 | self.cursorobj = self.connection.cursor() 21 | return self.cursorobj 22 | 23 | 24 | db1 = Database().connect() 25 | db2 = Database().connect() 26 | 27 | print ("Connection db1", db1) 28 | print ("Connection db2", db2) -------------------------------------------------------------------------------- /Creational/singleton_with_metaclass.py: -------------------------------------------------------------------------------- 1 | 2 | # Implement Singleton using Metaclass 3 | # ------------------------------------ 4 | class MetaSingleton(type): 5 | _instances = {} 6 | 7 | def __call__(cls, *args, **kwargs): 8 | if cls not in cls._instances: 9 | cls._instances[cls] = super(MetaSingleton, cls).__call__(*args, **kwargs) 10 | return cls._instances[cls] 11 | 12 | 13 | class Logger(metaclass=MetaSingleton): 14 | pass 15 | 16 | logger1 = Logger() 17 | logger2 = Logger() 18 | 19 | # Both reffer to same object. 20 | # ---------------------------- 21 | print(logger1, logger2) 22 | -------------------------------------------------------------------------------- /Model View Controller/MVC.py: -------------------------------------------------------------------------------- 1 | class Model: 2 | def db_data(self): 3 | print('Model called for data.') 4 | data = 'Model Data.' 5 | return data 6 | 7 | class View: 8 | def render(self, data): 9 | print('Rendering model on view :' , data) 10 | 11 | class Controller: 12 | def __init__(self): 13 | self.model = Model() 14 | self.view = View() 15 | 16 | def present(self): 17 | print('Controller, managing model and view.') 18 | data = self.model.db_data() 19 | self.view.render(data) 20 | 21 | 22 | controller = Controller() 23 | controller.present() 24 | 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Collection of design patterns in Python. Software design pattern is a general, reusable solution to a commonly occurring problem within a given context in software design. 2 | 3 | 1. Singleton Pattern
4 | 2. Lazy instantiation in Singleton Pattern
5 | 3. Singleton with metaclass
6 | 4. Factory Pattern
7 | 5. Abstract factory Pattern
8 | 6. Facade Pattern
9 | 7. Proxy Pattern
10 | 8. Adapter Pattern
11 | 9. Observer Pattern
12 | 10. Observer Pattern in Publisher and Subscriber example
13 | 11. Command Pattern
14 | 12. Command Pattern Example
15 | 13. Command Pattern Example_1
16 | 14. Template Pattern
17 | 15. State Pattern
18 | 16. Model View Controller
19 | -------------------------------------------------------------------------------- /Structural/adapter.py: -------------------------------------------------------------------------------- 1 | """ 2 | Convert the interface of a class into another interface clients expect. 3 | Adapter lets classes work together that couldn't otherwise because of 4 | incompatible interfaces. 5 | """ 6 | 7 | from abc import ABC, abstractmethod 8 | 9 | # ---------------- 10 | # Target Interface 11 | # ---------------- 12 | class Target(ABC): 13 | """ 14 | Interface for Client 15 | """ 16 | def __init__(self): 17 | self._adaptee = Adaptee() 18 | 19 | @abstractmethod 20 | def request(self): 21 | pass 22 | 23 | # ---------------- 24 | # Adapter Class 25 | # ---------------- 26 | class Adapter(Target): 27 | def request(self): 28 | self._adaptee.adaptee_request() 29 | 30 | # ---------------- 31 | # Adaptee Class 32 | # -------------- 33 | class Adaptee: 34 | def adaptee_request(self): 35 | print("Adaptee function called.") 36 | 37 | 38 | def main(): 39 | adapter = Adapter() 40 | adapter.request() 41 | 42 | 43 | if __name__ == "__main__": 44 | main() -------------------------------------------------------------------------------- /Structural/facade.py: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # Facade Implementation. 3 | #-------------------------------------------------------------------------------- 4 | # Provide a unified interface to a set of interfaces in a subsystem. 5 | # Façade defines a higher-level interface that makes the subsystem easier to use. 6 | # ------------------------------------------------------------------------------- 7 | 8 | class ResourceManager: 9 | def __init__(self): 10 | print("Update all resources.") 11 | 12 | 13 | def update_resources(self): 14 | self.reportDb = ReportDb() 15 | self.reportDb.update() 16 | 17 | self.intranetDb = InntranetDb() 18 | self.intranetDb.save() 19 | 20 | self.site = Site() 21 | self.site.update() 22 | 23 | self.Api = Api() 24 | self.Api.post() 25 | 26 | class ReportDb: 27 | def __init__(self): 28 | print ("ReportDb called.") 29 | 30 | def update(self): 31 | print("ReportDb updated.") 32 | 33 | class InntranetDb: 34 | def __init__(self): 35 | print("InntranetDb called.") 36 | 37 | def save(self): 38 | print("InntranetDb updated.") 39 | 40 | class Site: 41 | def __init__(self): 42 | print("SiteDb called.") 43 | 44 | def update(self): 45 | print("Site updated.") 46 | 47 | class Api: 48 | def __init__(self): 49 | print("Api called.") 50 | 51 | def post(self): 52 | print("Api post called.") 53 | 54 | 55 | # ------------ 56 | # CLient code 57 | # ------------ 58 | resource_manager = ResourceManager() 59 | resource_manager.update_resources() 60 | -------------------------------------------------------------------------------- /Structural/proxy.py: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # Proxy Pattern 3 | #------------------------------------------------------------------------------ 4 | #Provide a surrogate or placeholder for another object to control access to it. 5 | # ----------------------------------------------------------------------------- 6 | 7 | from abc import ABC, abstractmethod 8 | 9 | # ------------------------ 10 | # Payment class is SUBJECT 11 | # ------------------------ 12 | class Payment(ABC): 13 | @abstractmethod 14 | def make_payment(self): 15 | pass 16 | 17 | # ---------------------------------------------- 18 | # Real Subject implementation hidden under PROXY 19 | # ----------------------------------------------- 20 | class Bank(Payment): 21 | def __init__(self): 22 | self.card = None 23 | self.account = None 24 | 25 | def _has_funds(self): 26 | return True 27 | 28 | def _get_account(self): 29 | self.account = self.card 30 | return self.account 31 | 32 | def set_card(self, number): 33 | print("Dbit card no. " +str(number)+ " accepted.") 34 | self.card = number 35 | 36 | def make_payment(self): 37 | if self._has_funds(): 38 | print("Payment made.") 39 | else: 40 | print("Payment rejected.") 41 | 42 | # ---------------------------- 43 | # PROXY 44 | # ---------------------------- 45 | class DebitCard(Payment): 46 | def __init__(self): 47 | self.bank = Bank() 48 | 49 | def make_payment(self): 50 | number = input("Enter debit card number.") 51 | self.bank.set_card(number) 52 | return self.bank.make_payment() 53 | 54 | class Client: 55 | def __init__(self): 56 | print("Purchase some stuff.") 57 | self.debitcard= DebitCard() 58 | 59 | def purchase(self): 60 | self.debitcard.make_payment() 61 | 62 | client = Client() 63 | client.purchase() 64 | 65 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal 2 | plugins: 3 | - jekyll-sitemap 4 | -------------------------------------------------------------------------------- /googlea86b5cd8b12ff6a4.html: -------------------------------------------------------------------------------- 1 | google-site-verification: googlea86b5cd8b12ff6a4.html -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python Design Patterns 4 | 5 | 6 | 30 | 31 | 32 | 33 | 34 | 36 | 37 | 39 | 40 | 41 | 42 | 44 | 45 | 46 | 47 | 49 | 50 | 51 | 52 | 54 | 55 | 56 | 58 | 59 | 60 | 61 | 63 | 64 | 65 | 66 | 68 | 69 | 70 | 71 | 73 | 74 | 75 | 76 | 78 | 79 | 80 | 81 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 95 | 96 | 98 | 99 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 113 | 114 | 117 | 118 | 120 | 121 | 124 | 125 |
35 | Python Design Patterns -
S. No.Design PatternsCategoriesDefinition
1. 38 | Singleton PatternCreationalsingleton allows only a single instance of itself to be created and gives access to that created instance.
2. 43 | Lazy instantiation in Singleton PatternCreationalSingleton example.
3. 48 | Singleton with metaclassCreationalSingleton example.
4. 53 | Factory PatternCreationalDefine an interface for creating an object, but let subclasses decide which class to instantiate.
5. 57 | Abstract factory PatternCreationalProvide an interface for creating families of related or dependent objects without specifying their concrete classes.
6. 62 | Facade PatternStructuralProvide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
7. 67 | Proxy PatternStructuralProvide a surrogate or placeholder for another object to control access to it.
8. 72 | Adapter PatternStructuralConvert the interface of a class into another interface clients expect. An adapter lets classes work together that could not otherwise because of incompatible interfaces. The enterprise integration pattern equivalent is the translator.
9. 77 | Observer PatternBehavioralDefine a one-to-many dependency between objects where a state change in one object results in all its dependents being notified and updated automatically.
10. 82 | Observer Pattern in Publisher and Subscriber exampleBehavioralObserver example.
11. 87 | Command Pattern Behavioral 90 | Encapsulate a request as an object, thereby allowing for the parameterization of clients with different requests, and the queuing or logging of requests. It also allows for the support of undoable operations. 91 |
12. 94 | Command pattern example.Behavioral 97 | Command pattern example.
13. 100 | Command Pattern Example_1 BehavioralCommand pattern example.
14. 105 | Template PatternBehavioral 108 | Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure 109 |
15. 112 | State PatternBehavioral 115 | Allow an object to alter its behavior when its internal state changes. The object will appear to change its class. 116 |
16. 119 | Model View Controller Model View Controller 122 | Software architectural pattern that divides a given application into three interconnected parts. This is done to separate internal representations of information from the ways information is presented to, and accepted from, the user.The MVC design pattern decouples these major components allowing for efficient code reuse and parallel development. 123 |
126 | 127 | 128 | 129 | --------------------------------------------------------------------------------