基于Python学习《Head First设计模式》第四章 工厂模式+抽象工厂

发布于:2025-06-03 ⋅ 阅读:(24) ⋅ 点赞:(0)

背景

在这里插入图片描述
在这里插入图片描述

优化:封装 >> 简单工厂

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实现类图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

完整代码

from abc import abstractmethod


class Pizza:
    name: str  # 名称
    dough: str  # 面团类型
    sauce: str  # 酱料
    toppings: list  # 佐料

    def __init__(self):
        self.toppings = []  # 佐料

    def prepare(self):
        print(f'{self.name}准备中...')
        print(f'揉搓{self.dough}...')
        print(f'添加{self.sauce}...')
        print(f'添加佐料:{"、".join(self.toppings)}')

    def bake(self):
        print('350度烘焙25分钟')

    def cut(self):
        print('将披萨切块')

    def box(self):
        print('披萨装盒')

    def get_name(self):
        return self.name


class PizzaStore:
    @abstractmethod
    def _create_pizza(self, ptype) -> Pizza:
        pass

    def order_pizza(self, ptype):
        pizza = self._create_pizza(ptype)
        print(f'---下单一个{pizza.name}---')

        pizza.prepare()
        pizza.cut()
        pizza.bake()
        pizza.box()

        print('订单制作完成\n')
        return pizza


class NYStyleCheesePizza(Pizza):

    def __init__(self):
        super().__init__()
        self.name = '纽约风味的芝士披萨'
        self.sauce = '大蒜番茄酱'
        self.dough = '薄饼'
        self.toppings.append('意大利高级干酪')


class ChicagoStyleCheesePizza(Pizza):

    def __init__(self):
        super().__init__()
        self.name = '芝加哥风味的芝士披萨'
        self.sauce = '小番茄酱料'
        self.dough = '厚饼'
        self.toppings.append('意大利白干酪')

    def cut(self):
        print('将披萨切成正方形')


class NYStylePizzaStore(PizzaStore):

    def _create_pizza(self, ptype) -> Pizza:
        if ptype == 'cheese':
            pizza = NYStyleCheesePizza()
        return pizza


class ChicagoStylePizzaStore(PizzaStore):

    def _create_pizza(self, ptype) -> Pizza:
        if ptype == 'cheese':
            pizza = ChicagoStyleCheesePizza()
        return pizza


if __name__ == '__main__':
    NYStore = NYStylePizzaStore()
    ChicagoStore = ChicagoStylePizzaStore()

    NYStore.order_pizza('cheese')

    ChicagoStore.order_pizza('cheese')

"""运行结果:
---下单一个纽约风味的芝士披萨---
纽约风味的芝士披萨准备中...
揉搓薄饼...
添加大蒜番茄酱...
添加佐料:意大利高级干酪
将披萨切块
350度烘焙25分钟
披萨装盒
订单制作完成

---下单一个芝加哥风味的芝士披萨---
芝加哥风味的芝士披萨准备中...
揉搓厚饼...
添加小番茄酱料...
添加佐料:意大利白干酪
将披萨切成正方形
350度烘焙25分钟
披萨装盒
订单制作完成
"""

工厂模式的定义

在这里插入图片描述
在这里插入图片描述

简单工厂和工厂模式的区别

在这里插入图片描述
1、简单工厂结构:
在这里插入图片描述

2、工厂模式结构:
在这里插入图片描述

小结

依赖倒置原则:要依赖抽象,不要依赖具体类

在这里插入图片描述

示例:倒置思考方式

在这里插入图片描述

如何避免违反 依赖倒置 原则

在这里插入图片描述

进一步优化

在这里插入图片描述

class Pizza:
    name: str  # 名称
    dough: str  # 面团类型
    sauce: str  # 酱料
    toppings: list  # 佐料
    veggies: list  # 原料

    def __init__(self):
        self.toppings = []  # 佐料
        self.veggies = []  # 原料

    @abstractmethod
    def prepare(self):
        pass

    def bake(self):
        print('350度烘焙25分钟')

    def cut(self):
        print('将披萨切块')

    def box(self):
        print('披萨装盒')

    def get_name(self):
        return self.name

    def set_name(self, name):
        self.name = name

    def __str__(self):
        return f'{self.name}已制作完成,使用的原料有:{"、".join(self.veggies)}'

在这里插入图片描述

class CheesePizza(Pizza):
    """芝士披萨"""
    ingredient: PizzaIngredientFactory

    def __init__(self, ingredient: PizzaIngredientFactory):
        super().__init__()
        self.ingredient = ingredient  # 使用指定的原料工厂

    def prepare(self):
        print(f'{self.name}准备中...')
        self.sauce = self.ingredient.create_sauce()  # 使用指定原料工厂提供的酱料
        self.veggies.append(self.sauce.name)  # 原料列表
        # 其他原料先省略

在这里插入图片描述

在这里插入图片描述

class NYStylePizzaStore(PizzaStore):

    def _create_pizza(self, ptype) -> Pizza:
        self.ingredient = NYPizzaIngredientFactory()  # 纽约的披萨店用纽约的原料工厂
        if ptype == 'cheese':
            pizza = CheesePizza(self.ingredient)
            pizza.set_name('纽约风味的芝士披萨')
            print(pizza)
        # 其他先省略
        return pizza  # 除cheese外其他披萨会报错,先忽略

优化图解

在这里插入图片描述

完整代码

from abc import abstractmethod


class Pizza:
    name: str  # 名称
    dough: str  # 面团类型
    sauce: str  # 酱料
    toppings: list  # 佐料
    veggies: list  # 原料

    def __init__(self):
        self.toppings = []  # 佐料
        self.veggies = []  # 原料

    @abstractmethod
    def prepare(self):
        pass

    def bake(self):
        print('350度烘焙25分钟')

    def cut(self):
        print('将披萨切块')

    def box(self):
        print('披萨装盒')

    def get_name(self):
        return self.name

    def set_name(self, name):
        self.name = name

    def __str__(self):
        return f'{self.name}已制作完成,使用的原料有:{"、".join(self.veggies)}'


class PizzaStore:
    @abstractmethod
    def _create_pizza(self, ptype) -> Pizza:
        pass

    def order_pizza(self, ptype):
        pizza = self._create_pizza(ptype)

        pizza.prepare()
        pizza.cut()
        pizza.bake()
        pizza.box()

        print(f'{pizza}\n')
        return pizza


class Sauce:
    name: str = '酱料'


class NYSauce(Sauce):
    name = '纽约风味的酱料'


class ChicagoSauce(Sauce):
    name = '芝加哥风味的酱料'


class PizzaIngredientFactory:
    """原料工厂"""
    sauce: Sauce  # 原料工厂的原料之一:酱料

    @abstractmethod
    def create_sauce(self) -> Sauce:
        pass


class NYPizzaIngredientFactory(PizzaIngredientFactory):
    """纽约原料工厂"""

    def create_sauce(self) -> Sauce:
        return NYSauce()  # 提供纽约酱料


class ChicagoPizzaIngredientFactory(PizzaIngredientFactory):
    """芝加哥原料工厂"""

    def create_sauce(self) -> Sauce:
        return ChicagoSauce()  # 提供芝加哥原料


class CheesePizza(Pizza):
    """芝士披萨"""
    ingredient: PizzaIngredientFactory

    def __init__(self, ingredient: PizzaIngredientFactory):
        super().__init__()
        self.ingredient = ingredient  # 使用指定的原料工厂

    def prepare(self):
        print(f'{self.name}准备中...')
        self.sauce = self.ingredient.create_sauce()  # 使用指定原料工厂提供的酱料
        self.veggies.append(self.sauce.name)  # 原料列表


class NYStylePizzaStore(PizzaStore):

    def _create_pizza(self, ptype) -> Pizza:
        self.ingredient = NYPizzaIngredientFactory()  # 纽约的披萨店用纽约的原料工厂
        if ptype == 'cheese':
            pizza = CheesePizza(self.ingredient)
            pizza.set_name('纽约风味的芝士披萨')
        return pizza  # 除cheese外其他披萨会报错,先忽略


class ChicagoStylePizzaStore(PizzaStore):

    def _create_pizza(self, ptype) -> Pizza:
        self.ingredient = ChicagoPizzaIngredientFactory()  # 芝加哥的披萨店用芝加哥的原料工厂
        if ptype == 'cheese':
            pizza = CheesePizza(self.ingredient)
            pizza.set_name('芝加哥风味的芝士披萨')
        return pizza


if __name__ == '__main__':
    store = NYStylePizzaStore()
    store.order_pizza('cheese')

    store = ChicagoStylePizzaStore()
    store.order_pizza('cheese')

"""运行结果:
纽约风味的芝士披萨准备中...
将披萨切块
350度烘焙25分钟
披萨装盒
纽约风味的芝士披萨已制作完成,使用的原料有:纽约风味的酱料

芝加哥风味的芝士披萨准备中...
将披萨切块
350度烘焙25分钟
披萨装盒
芝加哥风味的芝士披萨已制作完成,使用的原料有:芝加哥风味的酱料
"""

抽象工厂模式定义

在这里插入图片描述
在这里插入图片描述

工厂模式 VS 抽象工厂

在这里插入图片描述
在这里插入图片描述

要点汇总

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到