设计模式:抽象工厂模式(Python)

抽象工厂模式(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


你可能感兴趣的:(设计模式)