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.