python风格的抽象工厂模式

本文详细介绍了抽象工厂模式的应用场景,通过制作不同口味披萨的实例,解释了如何使用该模式创建产品家族的不同实例,并与工厂模式进行了对比。文章还提供了Python代码示例,展示了如何在实际应用中实现这一模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

抽象工厂模式:

提供一个接口,用户创建多个相关或依赖对象,而不需要指定具体类。

原则:

依赖抽象,不依赖具体类。

实例:

用不同原材料制作不同口味的披萨,创建不同原材料的工厂,不同实体店做出口味不同的披萨。创建一个产品家族(Dough、Sauce、Cheese和Clam)的抽象类型(PizzaIngredientFactory),这个类型的子类(NYPizzaIngredientFactory和ChicagoPizzaIngredientFactory)定义了产品被产生的方法。

工厂模式和抽象工厂模式的区别:

工厂模式是在派生类中定义一个工厂的抽象接口,然后基类负责创建具体对象;抽象工厂模式是维护一个产品家族,由基类定义产品被生产的方法,客户根据派生类的接口进行开发。

代码:

#!/usr/bin/python
# -*- coding:utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

'''
披萨
'''
class Pizza:
    name = ""
    dough = None
    sauce = None
    cheese = None
    clam = None

    def prepare(self):
        pass

    def bake(self):
        print "烘烤25分钟在350。".decode('utf-8')

    def cut(self):
        print "切割成对角线切片。".decode('utf-8')

    def box(self):
        print "放在官方的盒子中。".decode('utf-8')

    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 += "    面团: %s\n" % self.dough.to_string() if self.dough else ""
        string += "    酱汁: %s\n" % self.sauce.to_string() if self.sauce else ""
        string += "    奶酪: %s\n" % self.cheese.to_string() if self.cheese else ""
        string += "    文蛤: %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 "准备: %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 "准备: %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

'''
纽约披萨实体店1
'''
class NYPizzaStore(PizzaStore):
    def create_pizza(self, pizza_type):
        ingredient_factory = NYPizzaIngredientFactory()

        if pizza_type == "cheese":
            pizza = CheesePizza(ingredient_factory)
            pizza.set_name("纽约风格芝士披萨".decode('utf-8'))
        elif pizza_type == "clam":
            pizza = ClamPizza(ingredient_factory)
            pizza.set_name("纽约风格文蛤披萨".decode('utf-8'))
        else:
            pizza = None

        return pizza

'''
芝加哥披萨实体店2
'''
class ChicagoPizzaStore(PizzaStore):
     def create_pizza(self, pizza_type):
        ingredient_factory = ChicagoPizzaIngredientFactory()

        if pizza_type == "cheese":
            pizza = CheesePizza(ingredient_factory)
            pizza.set_name("芝加哥风格芝士披萨".decode('utf-8'))
        elif pizza_type == "clam":
            pizza = ClamPizza(ingredient_factory)
            pizza.set_name("芝加哥风格文蛤披萨".decode('utf-8'))
        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

'''
生产披萨的实体工厂1
'''
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()

'''
生产披萨的实体工厂2
'''
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 "薄的面团"

class ThickDough(Dough):
    def to_string(self):
        return "厚的生面团"

class Sauce:
    def to_string(self):
        pass

class MarinaraSauce(Sauce):
    def to_string(self):
        return "番茄酱"

class MushroomSauce(Sauce):
    def to_string(self):
        return "蘑菇酱"

class Cheese:
    def to_string(self):
        pass

class FreshCheese(Cheese):
    def to_string(self):
        return "新鲜的奶酪"

class BlueCheese(Cheese):
    def to_string(self):
        return "蓝纹奶酪"

class Clam:
    def to_string(self):
        pass

class FreshClam(Clam):
    def to_string(self):
        return "新鲜的文蛤"

class FrozenClam(Clam):
    def to_string(self):
        return "冷冻的文蛤"

if __name__ == "__main__":
	# 创建了两个披萨实体店
    ny_store = NYPizzaStore()
    chicago_store = ChicagoPizzaStore()

    # 在第一个披萨对象中订购了一个cheese风味的披萨
    pizza = ny_store.order_pizza("cheese")
    print pizza.to_string()
    print "迈克订购了一个 %s" % pizza.get_name()
    print 

    pizza = chicago_store.order_pizza("clam")
    print pizza.to_string()
    print "约翰订购了一个%s" % pizza.get_name()
    print

结果:

准备: 纽约风格芝士披萨
烘烤25分钟在350。
切割成对角线切片。
放在官方的盒子中。
纽约风格芝士披萨:
    面团: 薄的面团
    酱汁: 番茄酱
    奶酪: 新鲜的奶酪

迈克订购了一个 纽约风格芝士披萨

准备: 芝加哥风格文蛤披萨
烘烤25分钟在350。
切割成对角线切片。
放在官方的盒子中。
芝加哥风格文蛤披萨:
    面团: 厚的生面团
    酱汁: 蘑菇酱
    文蛤: 冷冻的文蛤

约翰订购了一个芝加哥风格文蛤披萨

 

<think>好的,用户想了解抽象工厂模式的应用场景和实现方法,以及实际应用案例。首先,我需要回忆一下抽象工厂模式的定义和核心概念。根据提供的引用内容,特别是引用[2]和[3],抽象工厂模式主要用于生产一系列相关的对象,而无需指定它们的具体类。它通常基于一组工厂方法,可以隐藏子系统的创建细节,并且可以与桥接模式或单例模式搭配使用。 接下来,用户需要实际应用案例。常见的例子包括跨平台UI组件、数据库访问、游戏角色装备等。比如,引用[2]提到抽象工厂可以用于生成不同风格的用户界面组件,比如按钮和菜单,适用于跨平台应用。此外,数据库访问也是一个经典案例,不同的数据库可能需要不同的连接对象和命令对象,抽象工厂可以封装这些差异。 关于实现方法,根据引用[3],抽象工厂模式的结构包括抽象工厂、具体工厂、抽象产品和具体产品。客户端代码通过抽象工厂接口创建产品,而具体工厂负责实例化具体产品。需要确保每个具体工厂生产的产品属于同一族,例如Windows工厂创建Windows按钮和菜单,而Mac工厂创建Mac风格的组件。 还需要注意抽象工厂与工厂方法模式的区别,引用[1]提到工厂模式是面向抽象类编程,增加产品只需创建新的具体工厂,而简单工厂需要在原有代码修改。因此,在实现时,应该定义清晰的抽象接口,并通过具体工厂实现这些接口来生产产品族。 可能用户的实际需求是希望了解如何在项目中应用抽象工厂,以及如何避免代码的重复和增加扩展性。需要强调抽象工厂的优点,比如解耦客户端和具体类,支持产品族的一致性,但也需指出其缺点,比如新增产品种类需要修改所有工厂接口,这可能不太灵活。 最后,结合引用[4]提到的设计模式应根据实际情况选择,需要评估项目需求是否适合使用抽象工厂,比如当系统需要独立于产品的创建、组合和表示时,或者需要配置多个产品族中的一个时,抽象工厂是合适的选择。</think>### 抽象工厂模式详解 #### 一、应用场景 抽象工厂模式适用于需要创建**一系列相关或依赖对象**的场景,同时要求系统独立于这些对象的创建过程。典型应用包括: 1. **跨平台UI组件**:为不同操作系统(如Windows、Mac)生成风格一致的按钮、文本框、菜单等组件[^2]。 2. **数据库访问层**:针对MySQL、Oracle等数据库,统一创建连接对象、命令对象和事务对象[^2]。 3. **游戏角色装备**:为不同角色(战士、法师)生成配套的武器、防具和技能。 4. **多主题支持**:切换应用主题时,同时更换字体、颜色、图标等资源。 #### 二、实现方法 ##### 1. 核心结构 - **抽象工厂(AbstractFactory)**:声明创建产品族的方法,例如`create_button()`和`create_menu()`。 - **具体工厂(ConcreteFactory)**:实现抽象工厂接口,生成特定产品族(如Windows风格或Mac风格组件)。 - **抽象产品(AbstractProduct)**:定义产品接口(如`Button`、`Menu`)。 - **具体产品(ConcreteProduct)**:实现抽象产品接口的具体类。 ##### 2. Python实现示例 ```python from abc import ABC, abstractmethod # 抽象产品 class Button(ABC): @abstractmethod def render(self): pass class Menu(ABC): @abstractmethod def display(self): pass # 具体产品(Windows风格) class WindowsButton(Button): def render(self): return "Windows风格按钮" class WindowsMenu(Menu): def display(self): return "Windows风格菜单" # 具体产品(Mac风格) class MacButton(Button): def render(self): return "Mac风格按钮" class MacMenu(Menu): def display(self): return "Mac风格菜单" # 抽象工厂 class GUIFactory(ABC): @abstractmethod def create_button(self) -> Button: pass @abstractmethod def create_menu(self) -> Menu: pass # 具体工厂 class WindowsFactory(GUIFactory): def create_button(self): return WindowsButton() def create_menu(self): return WindowsMenu() class MacFactory(GUIFactory): def create_button(self): return MacButton() def create_menu(self): return MacMenu() # 客户端使用 def client_code(factory: GUIFactory): button = factory.create_button() menu = factory.create_menu() print(f"{button.render()} + {menu.display()}") # 根据系统类型选择工厂 import sys if sys.platform == "win32": client_code(WindowsFactory()) else: client_code(MacFactory()) ``` #### 三、优势与局限 - **优势**: - 保证产品族的兼容性(如所有UI组件风格一致) - 客户端代码与具体类解耦 - 新增产品族容易(只需添加新工厂) - **局限**: - 新增产品种类困难(需修改所有工厂接口) - 增加了系统复杂度 #### 四、实际案例 1. **Java AWT/Swing**:通过`Toolkit`类实现跨平台UI组件创建。 2. **Django数据库路由**:根据配置切换不同数据库后端。 3. **游戏引擎材质系统**:为不同渲染管线(如Vulkan、DirectX)生成配套的材质和着色器。 #### 五、与其他模式的关系 - **工厂方法模式**:抽象工厂通常用工厂方法实现具体产品的创建 - **单例模式**:工厂对象常以单例形式存在 - **外观模式**:两者都隐藏复杂性,但抽象工厂聚焦对象创建,外观模式聚焦接口简化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值