背景
优化:封装 >> 简单工厂
实现类图
完整代码
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 抽象工厂