提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
依赖抽象,不要依赖具体类。
还是“工厂方法模式”中的例子,但是换一种方式来解决:
因为口味的不同是原材料的不同造成的,因此我们就创建原材料工厂,每个工厂生产的原材料都不相同,同一款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