抽象工厂模式(Abstract Factory Pattern):
提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
原则:
依赖抽象,不要依赖具体类。
案例:
还是“工厂方法模式”中的例子,但是换一种方式来解决:
因为口味的不同是原材料的不同造成的,因此我们就创建原材料工厂,每个工厂生产的原材料都不相同,同一款Pizza从不同的原材料工厂拿货,做出的Pizza口味自然就不同了。
所以我们不用再根据城市和款式组合出各种Pizza类型(NYStyleCheesePizza、NYStyleClamPizza、ChicagoStyleCheesePizza和ChicagoStyleClamPizza),我们只需要根据款式建立Pizza类型(CheesePizza和ClamPizza),然后根据区域建立不同的原材料工厂(NYPizzaIngredientFactory和ChicagoPizzaIngredientFactory),将工厂和Pizaa类型绑定即可。
抽象工厂在这里表示:创建一个产品家族(Dough、Sauce、Cheese和Clam)的抽象类型(PizzaIngredientFactory),这个类型的子类(NYPizzaIngredientFactory和ChicagoPizzaIngredientFactory)定义了产品被产生的方法。
这样我们就可以针对(抽象类型的)接口编程而不是具体实现。
工厂方法和抽象工厂的区别:
工厂方法模式是在超类(PizzaStore)中定义一个工厂的抽象接口(create_pizza),然后由子类负责创建具体对象;
而抽象工厂则是维护一个产品家族,由子类定义产品被产生的方法,客户根据超类的接口开发。
本例中,工厂方法返回一个产品,抽象工厂则可获取一组产品的生产接口。
代码:
#!/usr/bin/python
class Pizza:
name = ""
dough = None
sauce = None
cheese = None
clam = None
def prepare(self):
pass
def bake(self):
print "Bake for 25 minutes at 350."
def cut(self):
print "Cutting into diagonal slices."
def box(self):
print "Put into official box."
def get_name(self):
return self.name
def set_name(self, name):
self.name = name
def to_string(self):
string = "%s:\n" % self.name
string += " Dough: %s\n" % self.dough.to_string() if self.dough else ""
string += " Sauce: %s\n" % self.sauce.to_string() if self.sauce else ""
string += " Cheese: %s\n" % self.cheese.to_string() if self.cheese else ""
string += " Clam: %s\n" % self.clam.to_string() if self.clam else ""
return string
class CheesePizza(Pizza):
def __init__(self, ingredient_factory):
self.ingredient_factory = ingredient_factory
def prepare(self):
print "Preparing: %s" % self.name
self.dough = self.ingredient_factory.create_dough()
self.sauce = self.ingredient_factory.create_sauce()
self.cheese = self.ingredient_factory.create_cheese()
class ClamPizza(Pizza):
def __init__(self, ingredient_factory):
self.ingredient_factory = ingredient_factory
def prepare(self):
print "Preparing: %s" % self.name
self.dough = self.ingredient_factory.create_dough()
self.sauce = self.ingredient_factory.create_sauce()
self.clam = self.ingredient_factory.create_clam()
class PizzaStore:
def order_pizza(self, pizza_type):
self.pizza = self.create_pizza(pizza_type)
self.pizza.prepare()
self.pizza.bake()
self.pizza.cut()
self.pizza.box()
return self.pizza
def create_pizza(self, pizza_type):
pass
class NYPizzaStore(PizzaStore):
def create_pizza(self, pizza_type):
ingredient_factory = NYPizzaIngredientFactory()
if pizza_type == "cheese":
pizza = CheesePizza(ingredient_factory)
pizza.set_name("New York Style Cheese Pizza")
elif pizza_type == "clam":
pizza = ClamPizza(ingredient_factory)
pizza.set_name("New York Style Clam Pizza")
else:
pizza = None
return pizza
class ChicagoPizzaStore(PizzaStore):
def create_pizza(self, pizza_type):
ingredient_factory = ChicagoPizzaIngredientFactory()
if pizza_type == "cheese":
pizza = CheesePizza(ingredient_factory)
pizza.set_name("Chicago Style Cheese Pizza")
elif pizza_type == "clam":
pizza = ClamPizza(ingredient_factory)
pizza.set_name("Chicago Style Clam Pizza")
else:
pizza = None
return pizza
class PizzaIngredientFactory:
def create_dough(self):
pass
def create_sauce(self):
pass
def create_cheese(self):
pass
def create_clam(self):
pass
class NYPizzaIngredientFactory(PizzaIngredientFactory):
def create_dough(self):
return ThinDough()
def create_sauce(self):
return MarinaraSauce()
def create_cheese(self):
return FreshCheese()
def create_clam(self):
return FreshClam()
class ChicagoPizzaIngredientFactory(PizzaIngredientFactory):
def create_dough(self):
return ThickDough()
def create_sauce(self):
return MushroomSauce()
def create_cheese(self):
return BlueCheese()
def create_clam(self):
return FrozenClam()
class Dough:
def to_string(self):
pass
class ThinDough(Dough):
def to_string(self):
return "Thin Dough"
class ThickDough(Dough):
def to_string(self):
return "Thick Dough"
class Sauce:
def to_string(self):
pass
class MarinaraSauce(Sauce):
def to_string(self):
return "Marinara Sauce"
class MushroomSauce(Sauce):
def to_string(self):
return "Mushroom Sauce"
class Cheese:
def to_string(self):
pass
class FreshCheese(Cheese):
def to_string(self):
return "Fresh Cheese"
class BlueCheese(Cheese):
def to_string(self):
return "Blue Cheese"
class Clam:
def to_string(self):
pass
class FreshClam(Clam):
def to_string(self):
return "Fresh Clam"
class FrozenClam(Clam):
def to_string(self):
return "Frozen Clam"
if __name__ == "__main__":
ny_store = NYPizzaStore()
chicago_store = ChicagoPizzaStore()
pizza = ny_store.order_pizza("cheese")
print pizza.to_string()
print "Mike ordered a %s" % pizza.get_name()
print
pizza = chicago_store.order_pizza("clam")
print pizza.to_string()
print "John ordered a %s" % pizza.get_name()
print
输出:
Preparing: New York Style Cheese Pizza
Bake for 25 minutes at 350.
Cutting into diagonal slices.
Put into official box.
New York Style Cheese Pizza:
Dough: Thin Dough
Sauce: Marinara Sauce
Cheese: Fresh Cheese
Mike ordered a New York Style Cheese Pizza
Preparing: Chicago Style Clam Pizza
Bake for 25 minutes at 350.
Cutting into diagonal slices.
Put into official box.
Chicago Style Clam Pizza:
Dough: Thick Dough
Sauce: Mushroom Sauce
Clam: Frozen Clam
John ordered a Chicago Style Clam Pizza