【发布时间】:2020-12-27 08:50:50
【问题描述】:
在我正在学习的一门课程中,PizzaStore 使用了处理具体披萨实例化的 SimplePizzaFactory 类,描述如下:
在课程中,工厂方法模式的介绍通过介绍需要为 PizzaStore 提供额外级别的特殊性以及提供相同类型的 Pizzas(Viggie、Cheese 等)的能力来描述,但在纽约风格和芝加哥风格,所以我们有一组新的子类(NYStyleViggiePizza、NYStyleCheesePizza、.. ChicagoStyleViggiePizza、ChicagoStyleCheesePizza、..)
导师介绍的解决方案是使用工厂方法模式,如下:
(UML)
用python重写的代码:
# Pizzas Subclasses are defined elsewhere
from abc import ABC, abstractmethod
class PizzaStore(ABC):
@abstractmethod
def create_pizza(self):
pass
def order_pizza(self,type_of_pizza):
type_of_pizza = type_of_pizza.lower()
pizza = self.create_pizza(type_of_pizza)
pizza.prepare()
pizza.bake()
pizza.box()
return pizza
class NYPizzaStore(PizzaStore):
def create_pizza(self, type_of_pizza):
if type_of_pizza == "cheese":
pizza = NYStyleCheesePizza()
elif type_of_pizza == "pepperoni":
pizza = NYStylePepperoniPizza()
elif type_of_pizza == "clam":
pizza = NYStyleClamPizza()
elif type_of_pizza == "viggie":
pizza = NYStyleViggiePizza()
else:
raise Exception("You need to specify a type of NY pizza.")
return pizza
class ChicagoPizzaStore(PizzaStore):
def create_pizza(self,type_of_pizza):
if type_of_pizza == "cheese":
pizza = ChicagoStyleCheesePizza()
elif type_of_pizza == "pepperoni":
pizza = ChicagoStylePepperoniPizza()
elif type_of_pizza == "clam":
pizza = ChicagoStyleClamPizza()
elif type_of_pizza == "viggie":
pizza = ChicagoStyleViggiePizza()
else:
raise Exception("You need to specify a type of NY pizza.")
return pizza
# ===== Driver Code =====
# NY store
ny_pizza_store = NYPizzaStore()
ny_pizza_store.order_pizza("Cheese")
ny_pizza_store.order_pizza("Pepperoni")
print()
# Chicago store
chicago_pizza_store = ChicagoPizzaStore()
chicago_pizza_store.order_pizza("Cheese")
chicago_pizza_store.order_pizza("Pepperoni")
在进入工厂方法之前,我尝试了以下设计,在该方法中我保持 PizzaStore 的原样并将SimpleFactoryPizza 替换为两个新类:NYPizzaFactory 和 ChicagoPizzaFactory
用python重写的代码:
class NYPizzaFactory():
def create_pizza(self,type_of_pizza):
if type_of_pizza == "cheese":
pizza = NYStyleCheesePizza()
elif type_of_pizza == "pepperoni":
pizza = NYStylePepperoniPizza()
elif type_of_pizza == "clam":
pizza = NYStyleClamPizza()
elif type_of_pizza == "viggie":
pizza = NYStyleViggiePizza()
else:
raise Exception("You need to specify a type of NY pizza.")
return pizza
class ChicagoPizzaFactory():
def create_pizza(self,type_of_pizza):
if type_of_pizza == "cheese":
pizza = ChicagoStyleCheesePizza()
elif type_of_pizza == "pepperoni":
pizza = ChicagoStylePepperoniPizza()
elif type_of_pizza == "clam":
pizza = ChicagoStyleClamPizza()
elif type_of_pizza == "viggie":
pizza = ChicagoStyleViggiePizza()
else:
raise Exception("You need to specify a type of NY pizza.")
return pizza
# PizzaStore is the same as before
class PizzaStore:
def __init__(self, pizza_factory_obj):
self.pizza_factory_obj = pizza_factory_obj
def order_pizza(self,type_of_pizza):
type_of_pizza = type_of_pizza.lower()
pizza = self.pizza_factory_obj.create_pizza(type_of_pizza)
pizza.prepare()
pizza.bake()
pizza.box()
return pizza
# ===== Driver Code ======
# NY Store
ny_pizza_factory = NYPizzaFactory()
ny_pizza_store = PizzaStore(ny_pizza_factory)
ny_pizza_store.order_pizza("Cheese")
print()
ny_pizza_store.order_pizza("Pepperoni")
print()
# Chicago Store
chicago_pizza_factory = ChicagoPizzaFactory()
chicago_pizza_store = PizzaStore(chicago_pizza_factory)
chicago_pizza_store.order_pizza("Cheese")
print()
chicago_pizza_store.order_pizza("Pepperoni")
我了解工厂方法允许类将实例化推迟到其子类,这些子类将包含该“工厂方法”的实现。
问题 1:
- 根据定义,我的解决方案不被视为工厂模式吗?与所代表的工厂方法相比,我尝试的方法有什么区别和缺点?
问题 2:
工厂方法结构由以下UML概括:(来自课程资料)
在“Design Patterns: Elements of Reusable Object-Oriented Software”一书中,工厂方法模式的结构是通过这个 UML 描述的:
- 工厂和产品之间的箭头代表课程资料中的“聚合”,而书中的UML图代表“依赖”(我认为),哪一个代表正确的关系?为什么?
【问题讨论】:
-
你的方法不应该是静态的吗?
-
如果你的意思是第二个实现,在工厂类中使 create_pizza() 静态,那么我认为你是正确的,老实说,我只是跟随课程的 java 实现并比较多种方法不同来源查看差异。
-
也许您可以将问题限制为一个问题,而不是当前的四个问题。
-
@khelwood 我以为他们的目标是相同的,但我会这样做。
-
起初工厂在 Python 中比在 Java 中少得多。然后是
__new__,它实际上可以在创建对象时返回不同类的对象。然后工厂没有状态,在使用该方法之前不需要创建工厂实例。它可以是静态的。
标签: python uml aggregation factory-pattern