基于Python学习《Head First设计模式》第四章 工厂模式+抽象工厂
背景
优化:封装 >> 简单工厂
实现类图
完整代码
from abc import abstractmethodclass 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.nameclass PizzaStore:@abstractmethoddef _create_pizza(self, ptype) -> Pizza:passdef order_pizza(self, ptype):pizza = self._create_pizza(ptype)print(f'---下单一个{pizza.name}---')pizza.prepare()pizza.cut()pizza.bake()pizza.box()print('订单制作完成\n')return pizzaclass 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 pizzaclass ChicagoStylePizzaStore(PizzaStore):def _create_pizza(self, ptype) -> Pizza:if ptype == 'cheese':pizza = ChicagoStyleCheesePizza()return pizzaif __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 = [] # 原料@abstractmethoddef prepare(self):passdef bake(self):print('350度烘焙25分钟')def cut(self):print('将披萨切块')def box(self):print('披萨装盒')def get_name(self):return self.namedef set_name(self, name):self.name = namedef __str__(self):return f'{self.name}已制作完成,使用的原料有:{"、".join(self.veggies)}'
class CheesePizza(Pizza):"""芝士披萨"""ingredient: PizzaIngredientFactorydef __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 abstractmethodclass Pizza:name: str # 名称dough: str # 面团类型sauce: str # 酱料toppings: list # 佐料veggies: list # 原料def __init__(self):self.toppings = [] # 佐料self.veggies = [] # 原料@abstractmethoddef prepare(self):passdef bake(self):print('350度烘焙25分钟')def cut(self):print('将披萨切块')def box(self):print('披萨装盒')def get_name(self):return self.namedef set_name(self, name):self.name = namedef __str__(self):return f'{self.name}已制作完成,使用的原料有:{"、".join(self.veggies)}'class PizzaStore:@abstractmethoddef _create_pizza(self, ptype) -> Pizza:passdef order_pizza(self, ptype):pizza = self._create_pizza(ptype)pizza.prepare()pizza.cut()pizza.bake()pizza.box()print(f'{pizza}\n')return pizzaclass Sauce:name: str = '酱料'class NYSauce(Sauce):name = '纽约风味的酱料'class ChicagoSauce(Sauce):name = '芝加哥风味的酱料'class PizzaIngredientFactory:"""原料工厂"""sauce: Sauce # 原料工厂的原料之一:酱料@abstractmethoddef create_sauce(self) -> Sauce:passclass NYPizzaIngredientFactory(PizzaIngredientFactory):"""纽约原料工厂"""def create_sauce(self) -> Sauce:return NYSauce() # 提供纽约酱料class ChicagoPizzaIngredientFactory(PizzaIngredientFactory):"""芝加哥原料工厂"""def create_sauce(self) -> Sauce:return ChicagoSauce() # 提供芝加哥原料class CheesePizza(Pizza):"""芝士披萨"""ingredient: PizzaIngredientFactorydef __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 pizzaif __name__ == '__main__':store = NYStylePizzaStore()store.order_pizza('cheese')store = ChicagoStylePizzaStore()store.order_pizza('cheese')"""运行结果:
纽约风味的芝士披萨准备中...
将披萨切块
350度烘焙25分钟
披萨装盒
纽约风味的芝士披萨已制作完成,使用的原料有:纽约风味的酱料芝加哥风味的芝士披萨准备中...
将披萨切块
350度烘焙25分钟
披萨装盒
芝加哥风味的芝士披萨已制作完成,使用的原料有:芝加哥风味的酱料
"""
抽象工厂模式定义
工厂模式 VS 抽象工厂