Creational Pattern
Lets look at some of the examples of crational pattern in this article.
Singleton desgin pattern:
This pattern restricts the creation of instance to one instance. This can be verified via following example:
class Singleton:
__instance = None
@staticmethod
def get_instance():
if Singleton.__instance is None:
Singleton()
return Singleton.__instance
def __init__(self):
# print(self)
# print("type = ", type(self))
if Singleton.__instance is not None:
raise Exception("Singleton class !Can't create multiple objects!")
else:
Singleton.__instance = self
s = Singleton()
print(s)
s = Singleton.get_instance()
print(s)
s = Singleton.get_instance()
print(s)
s = Singleton.get_instance()
print(s)
Output:
<__main__.Singleton object at 0x7f78d1920c50>
<__main__.Singleton object at 0x7f78d1920c50>
<__main__.Singleton object at 0x7f78d1920c50>
<__main__.Singleton object at 0x7f78d1920c50>
Builder design pattern:
Builder design pattern helps to create complex from simple object by separating construction and representation. Following example illustrates builder design pattern using python:
class Builder:
"""
This is like an abstract class
"""
def get_wheel(self): pass
def get_body(self): pass
def get_engine(self): pass
class JeepBuilder(Builder):
def get_wheel(self):
wheel = Wheel()
wheel.size = 34
return wheel
def get_engine(self):
eng = Engine()
eng.horsepower = 770
return eng
def get_body(self):
body = Body()
body.shape = "Range Rover"
return body
class Director:
__builder = None
def __init__(self, b):
self.__builder = b
def get_car(self):
car = Car()
car.set_body(self.__builder.get_body())
# car.set_wheel(self.__builder.get_wheel())
car.set_engine(self.__builder.get_engine())
# set wheel
i = 0
while i < 4:
wheel = self.__builder.get_wheel()
car.set_wheel(wheel)
i += 1
return car
# This one is our main product
class Car:
_body = None
_engine = None
_wheels = list()
def set_body(self, body):
self._body = body
def set_engine(self, eng):
self._engine = eng
def set_wheel(self, wh):
self._wheels.append(wh)
def get_specification(self):
print(f"body shape = {self._body.shape}")
print(f"engine horsepower= {self._engine.horsepower}")
print(f"wheel size = {self._wheels[0].size}")
class Wheel:
size = None
class Body:
shape = None # e.g SUV
class Engine:
horsepower = None
if __name__ == "__main__":
print("jeep")
builder = JeepBuilder()
director = Director(builder)
jeep = director.get_car() # return an instance
jeep.get_specification()
print("thanks")
Output:
jeep
body shape = Range Rover
engine horsepower= 770
wheel size = 34
thanks
Factory design patter:
This pattern helps to create object without giving underlying details to client and communicating to those created object via common interfact. Following example illustrates factory design pattern:
class Button(object):
html = "<button></button>"
def get_html(self):
return self.html
class Image(Button):
html = "<img></img>"
class Input(Button):
html = "<input></input>"
class Card(Button):
html = "<obj></obj>"
class ButtonFactory:
def create_button(self, typ):
# Note we need to capitalize() because we are passing values in lower case
return globals()[typ.capitalize()]()
btn = ButtonFactory()
input_list = ['image', 'input', 'card']
for b in input_list:
t = btn.create_button(b).get_html()
print(t)
Output:
<img></img>
<input></input>
<obj></obj>
Prototype design pattern:
Prototype design pattern helps to hide the complexity of the instances created by the class via cloning an object. Following example show prototype desing pattern:
import copy
class Prototype:
_type = None
_value = None
def get_type(self):
return self._type
def get_value(self):
return self._value
def clone(self):
pass
class Type1(Prototype):
def __init__(self, value):
self._type = "type1"
self._value = value
def clone(self):
return copy.copy(self)
class Type2(Prototype):
def __init__(self, value):
self._type = "type2"
self._value = value
def clone(self):
return copy.copy(self)
class ObjectFactory:
__type1value1 = None
__type1value2 = None
__type2value1 = None
__type2value2 = None
@staticmethod
def initialize():
ObjectFactory.__type1value1 = Type1(1)
ObjectFactory.__type1value2 = Type1(2)
ObjectFactory.__type2value1 = Type2(1)
ObjectFactory.__type2value2 = Type2(2)
@staticmethod
def get_type1_value1():
return ObjectFactory.__type1value1.clone()
@staticmethod
def get_type1_value2():
return ObjectFactory.__type1value2.clone()
@staticmethod
def get_type2_value1():
return ObjectFactory.__type2value1.clone()
@staticmethod
def get_type2_value2():
return ObjectFactory.__type2value2.clone()
def main():
print("starting main")
# initialize and call method
ObjectFactory.initialize()
obj = ObjectFactory.get_type1_value1()
print(f"type= {obj.get_type()}, value = {obj.get_value()}")
obj = ObjectFactory.get_type1_value2()
print(f"type= {obj.get_type()}, value = {obj.get_value()}")
obj = ObjectFactory.get_type2_value1()
print(f"type= {obj.get_type()}, value = {obj.get_value()}")
obj = ObjectFactory.get_type2_value2()
print(f"type= {obj.get_type()}, value = {obj.get_value()}")
print("thanks")
if __name__ == "__main__":
main()
starting main
type= type1, value = 1
type= type1, value = 2
type= type2, value = 1
type= type2, value = 2
thanks
In the next lession we will look at some structural design pattern.