考虑以下python3代码:
from abc import ABC, abstractmethod
class Food(ABC):
_food_factory_map = {}
_recipes = {}
@classmethod
def getFood(cls, foodName):
return cls._food_factory_map[foodName]()
@classmethod
def registerFood(cls, foodName, recipe):
def callable(foodClass):
cls._food_factory_map[foodName] = foodClass
cls._recipes[foodName] = recipe
return foodClass
return callable
def __init__(self):
print("Starting Food prep")
@abstractmethod
def prepareFood(self):
...
def serveFood(self):
food = self.prepareFood()
print(food)
@Food.registerFood('Burger', 'Burger Recipe')
class Burger(Food):
def prepareFood(self):
return 'Burger is ready!'
@Food.registerFood('Pizza', 'Pizza Recipe')
class Pizza(Food):
def prepareFood(self):
return 'Pizza is ready!'
if __name__ == '__main__':
fs = ('Burger', 'Pizza')
for f in fs:
print(f"Food Recipe: {Food._recipes[f]}")
food = Food.getFood(f)
food.serveFood()在这里,抽象基类Food有实现工厂设计模式的类方法。客户端可以使用registerFood注册自己的具体类,并使用getFood检索它们。抽象基类还实现了定义接口的其他抽象和具体方法。
还可以将两个类方法(getFood和registerFood)和两个类成员(_food_factory_map和_recipes)分离为它自己的一个类(FoodFactory)
class FoodFactory(ABC):
_food_factory_map = {}
_recipes = {}
@classmethod
def getFood(cls, foodName):
return cls._food_factory_map[foodName]()
@classmethod
def registerFood(cls, foodName, recipe):
def callable(foodClass):
cls._food_factory_map[foodName] = foodClass
cls._recipes[foodName] = recipe
return foodClass
return callable然后,所有客户端代码将改为使用FoodFactory而不是Food。
@FoodFactory.registerFood('Pizza', 'Pizza Recipe')
class Pizza(Food):
def prepareFood(self):
return 'Pizza is ready!'
if __name__ == '__main__':
fs = ('Burger', 'Pizza')
for f in fs:
print(f"Food Recipe: {FoodFactory._recipes[f]}")
food = FoodFactory.getFood(f)
food.serveFood()这些实现中哪一个更好,为什么?或者使用这两者都是完全合理的?它依赖于语言吗?
我可以考虑的一个优点是,使用第二个方法,可以覆盖__new__ of FoodFactory直接返回适当食物的实例,而不是调用单独的getFood方法。但这种差异在很大程度上似乎是表面上的。
发布于 2023-04-02 23:07:14
OOP最佳实践:是否有理由将工厂功能从抽象基类中分离出来?
当构造函数不再是当前问题的适当解决方案时,工厂就得到了保证。因此,您可以认为构造函数是一个非常简单的工厂,当构造逻辑变得足够复杂以保证与工厂的产品(即原始类)分离时,您只需要考虑一个工厂(即单独的类)。
所以,要回答你的一般性问题,如果有任何理由把它分开,答案是肯定的。具体来说,在构造逻辑足够复杂的情况下,或者例如,当您需要一个能够动态生成产品的可注入依赖时。
对于Food来说,知道一组菜谱是没有语义意义的。这是元知识。类似地,你的汽车不包含它自己的建筑蓝图,更不用说其他许多汽车的蓝图了。
我的直觉告诉我,这是一种构图过度继承的违反。更有意义的是,将菜谱集合保存在一个专用的类中(让我们称之为RecipeBook)。
在这里使用继承是错误的构造。您没有使用继承提供的多态性。汉堡包不是菜谱的集合,这也是你的遗产目前所宣称的。
我不是Python,所以我不喜欢编写您的代码片段的改进版本。
发布于 2023-04-02 19:00:31
我想说,这里的主要原因是您在工厂中应用了单例模式。
你绝不能有不同的工厂。
你永远不能嘲笑这家工厂。
https://softwareengineering.stackexchange.com/questions/444809
复制相似问题