33
44"""
55*What is this pattern about?
6- The Abstract Factory Pattern serves to provide an interface for
6+
7+ In Java and other languages, the Abstract Factory Pattern serves to provide an interface for
78creating related/dependent objects without need to specify their
89actual class.
10+
911The idea is to abstract the creation of objects depending on business
1012logic, platform choice, etc.
1113
14+ In Python, we interface we use is simply a callable, which is "builtin" interface
15+ in Python, and in normal circumstances we can simply use the class itself as
16+ that callable, because classes are first class objects in Python.
17+
1218*What does this example do?
1319This particular implementation abstracts the creation of a pet and
14- does so depending on the AnimalFactory we chose (Dog or Cat)
15- This works because both Dog/Cat and their factories respect a common
16- interface (.speak(), get_pet() and get_food ()).
17- Now my application can create pets (and feed them) abstractly and decide later,
20+ does so depending on the factory we chose (Dog or Cat, or random_animal )
21+ This works because both Dog/Cat and random_animal respect a common
22+ interface (callable for creation and .speak ()).
23+ Now my application can create pets abstractly and decide later,
1824based on my own criteria, dogs over cats.
19- The second example allows us to create pets based on the string passed by the
20- user, using cls.__subclasses__ (the list of sub classes for class cls)
21- and sub_cls.__name__ to get its name.
2225
2326*Where is the pattern used practically?
2427
3033Provides a way to encapsulate a group of individual factories.
3134"""
3235
33-
34- import six
35- import abc
3636import random
3737
3838
@@ -48,14 +48,11 @@ def __init__(self, animal_factory=None):
4848 def show_pet (self ):
4949 """Creates and shows a pet using the abstract factory"""
5050
51- pet = self .pet_factory . get_pet ()
51+ pet = self .pet_factory ()
5252 print ("We have a lovely {}" .format (pet ))
5353 print ("It says {}" .format (pet .speak ()))
54- print ("We also have {}" .format (self .pet_factory .get_food ()))
5554
5655
57- # Stuff that our factory makes
58-
5956class Dog (object ):
6057
6158 def speak (self ):
@@ -74,80 +71,38 @@ def __str__(self):
7471 return "Cat"
7572
7673
77- # Factory classes
78-
79- class DogFactory (object ):
80-
81- def get_pet (self ):
82- return Dog ()
83-
84- def get_food (self ):
85- return "dog food"
74+ # Additional factories:
8675
87-
88- class CatFactory (object ):
89-
90- def get_pet (self ):
91- return Cat ()
92-
93- def get_food (self ):
94- return "cat food"
95-
96-
97- # Create the proper family
98- def get_factory ():
76+ # Create a random animal
77+ def random_animal ():
9978 """Let's be dynamic!"""
100- return random .choice ([DogFactory , CatFactory ])()
101-
102-
103- # Implementation 2 of an abstract factory
104- @six .add_metaclass (abc .ABCMeta )
105- class Pet (object ):
106-
107- @classmethod
108- def from_name (cls , name ):
109- for sub_cls in cls .__subclasses__ ():
110- if name == sub_cls .__name__ .lower ():
111- return sub_cls ()
112-
113- @abc .abstractmethod
114- def speak (self ):
115- """"""
116-
117-
118- class Kitty (Pet ):
119- def speak (self ):
120- return "Miao"
121-
122-
123- class Duck (Pet ):
124- def speak (self ):
125- return "Quak"
79+ return random .choice ([Dog , Cat ])()
12680
12781
12882# Show pets with various factories
12983if __name__ == "__main__" :
84+
85+ # A Shop that sells only cats
86+ cat_shop = PetShop (Cat )
87+ cat_shop .show_pet ()
88+ print ("" )
89+
90+ # A shop that sells random animals
91+ shop = PetShop (random_animal )
13092 for i in range (3 ):
131- shop = PetShop (get_factory ())
13293 shop .show_pet ()
13394 print ("=" * 20 )
13495
135- for name0 in ["kitty" , "duck" ]:
136- pet = Pet .from_name (name0 )
137- print ("{}: {}" .format (name0 , pet .speak ()))
138-
13996### OUTPUT ###
14097# We have a lovely Cat
14198# It says meow
142- # We also have cat food
143- # ====================
99+ #
144100# We have a lovely Dog
145101# It says woof
146- # We also have dog food
147102# ====================
148103# We have a lovely Cat
149104# It says meow
150- # We also have cat food
151105# ====================
152- # kitty: Miao
153- # duck: Quak
106+ # We have a lovely Cat
107+ # It says meow
108+ # ====================
0 commit comments