2. What is that crap
Define an interface for creating an object,
but let the subclasses decide which class to
instantiate.
The Factory method lets a class defer
instantiation to subclasses.
5. Static Factory
• Forces all the creation operations to be
focused in one spot
Static Factory:
Shape
Circle
Square Product
6. class Shape(object):
def factory(type):
if type == "Circle" : return Circle()
if type == "Square" : return Square()
assert 1, "Bad shape creation " + type
factory = staticmethod(factory)
class Circle(Shape):
def draw(self): print "Circle.draw"
def erase(self): print "Circle.erase"
class Square(Shape):
def draw(self): print "Square.draw"
def erase(self): print "Square.erase"
def shape_name_gen(n):
types = Shape.__subclasses__()
for i in range(n):
yield random.choice(types).__name__
shapes = [Shape.factory(i) for i in shape_name_gen(7)]
for shape in shapes:
shape.draw()
shape.erase()
7. Polymorphic Factory
• Make a single superclass version of the method that calls a
Factory Method to handle the instantiation
• The new class can be dynamically added to the factory
• Factory methods are in separate class as virtual function
• Different types of factories can be subclassed from the basic
factory
8. class ShapeFactory:
factories = {}
def add_factory(id, shapefactory):
ShapeFactory.factories.put[id] = shapeFactory
add_factory = staticmethod(add_factory)
def create_shape(id):
if not ShapeFactory.factories.has_key(id):
ShapeFactory.factories[id] = eval(id+'.Factory()')
return ShapeFactory.factories[id].create()
create_shape = staticmethod(create_shape)
class Shape(object): pass
class Circle(Shape): def shape_name_gen(n):
def draw(self): print "Circle.draw" types = Shape.__subclasses__()
def erase(self): print "Circle.erase" for i in range(n):
class Factory: yield random.choice(types).__name__
def create(self): return Circle()
shapes = [ShapeFactory.create_shape(i)
class Square(Shape): for i in shape_name_gen(7)]
def draw(self): print "Square.draw"
def erase(self): print "Square.erase" for shape in shapes:
class Factory: shape.draw()
def create(self): return Square() shape.erase()
9. Abstract Factory
• The client creates a concrete
implementation of the
abstract factory and then
uses the generic interface to
create object
• The idea is that at the point
of creation of the factory
object, you decide how all the
objects created by that
factory will be used.
10. class Obstacle: pass class GameElementFactory: pass
class Player: pass
class JavAndPuzzle(GameElementFactory):
class Jav(Player): def make_player(self): return Jav()
def interact_with(self, obstacle): def make_obstacle(self): return Puzzle()
print("Jav is playing a" )
obstacle.action() class
BenAndWeapon(GameElementFactory):
class Ben(Player): def make_player(self): return Ben()
def interact_with(self, obstacle): def make_obstacle(self): return Weapon()
print("Ben is playing a " ) class GameEnvironment:
obstacle.action() def __init__(self, factory):
self.factory = factory
class Puzzle(Obstacle): self.p = factory.make_player()
def action(self): self.ob = factory.make_obstacle()
print("Puzzle")
def play(self):
class Weapon(Obstacle): self.p.interact_with(self.ob)
def action(self):
print("Weapon") g1 = GameEnvironment(JavAndPuzzle())
g2 = GameEnvironment(BenAndWeapon())
g1.play()
g2.play()
11. Limitations of Factory
• The first limitation is that refactoring an
existing class to use factories breaks existing
clients.