工厂方法Python设计模式
工厂方法是一种创建设计模式,它允许接口或类创建对象,但让子类决定要实例化哪个类或对象。使用工厂方法,我们有最好的方法来创建一个对象。这里,对象的创建不向客户端公开逻辑,并且为了创建新类型的对象,客户端使用相同的公共接口。
没有工厂方法我们面临的问题:
想象一下,您有自己的创业公司,在全国不同地区提供拼车服务。该应用程序的初始版本仅提供两轮拼车,但随着时间的推移,您的应用程序变得流行,现在您还想添加三轮和四轮拼车。
这是一个好消息!但是你创业公司的软件开发人员呢?他们必须更改整个代码,因为现在大部分代码都与两轮车类耦合,开发人员必须对整个代码库进行更改。
在完成所有这些更改后,开发人员要么以凌乱的代码结束,要么以辞职信结束。
不使用工厂方法的问题的图解表示
让我们再用一个与不同语言的翻译和本地化相关的例子来理解这个概念。
假设我们创建了一个应用程序,其主要目的是将一种语言翻译成另一种语言,而目前我们的应用程序只支持 10 种语言。现在我们的应用程序已经在人们中广受欢迎,但需求突然增长到包含 5 种以上的语言。
这是一个好消息!只为业主不为开发商。他们必须更改整个代码,因为现在大部分代码仅与现有语言耦合,这就是为什么开发人员必须对整个代码库进行更改,这确实是一项艰巨的任务。
让我们看一下不使用工厂方法可能会遇到的问题的代码。
注意:以下代码是在不使用工厂方法的情况下编写的。
Python3
# Python Code for Object
# Oriented Concepts without
# using Factory method
class FrenchLocalizer:
""" it simply returns the french version """
def __init__(self):
self.translations = {"car": "voiture", "bike": "bicyclette",
"cycle":"cyclette"}
def localize(self, msg):
"""change the message using translations"""
return self.translations.get(msg, msg)
class SpanishLocalizer:
"""it simply returns the spanish version"""
def __init__(self):
self.translations = {"car": "coche", "bike": "bicicleta",
"cycle":"ciclo"}
def localize(self, msg):
"""change the message using translations"""
return self.translations.get(msg, msg)
class EnglishLocalizer:
"""Simply return the same message"""
def localize(self, msg):
return msg
if __name__ == "__main__":
# main method to call others
f = FrenchLocalizer()
e = EnglishLocalizer()
s = SpanishLocalizer()
# list of strings
message = ["car", "bike", "cycle"]
for msg in message:
print(f.localize(msg))
print(e.localize(msg))
print(s.localize(msg))
Python3
# Python Code for factory method
# it comes under the creational
# Design Pattern
class FrenchLocalizer:
""" it simply returns the french version """
def __init__(self):
self.translations = {"car": "voiture", "bike": "bicyclette",
"cycle":"cyclette"}
def localize(self, msg):
"""change the message using translations"""
return self.translations.get(msg, msg)
class SpanishLocalizer:
"""it simply returns the spanish version"""
def __init__(self):
self.translations = {"car": "coche", "bike": "bicicleta",
"cycle":"ciclo"}
def localize(self, msg):
"""change the message using translations"""
return self.translations.get(msg, msg)
class EnglishLocalizer:
"""Simply return the same message"""
def localize(self, msg):
return msg
def Factory(language ="English"):
"""Factory Method"""
localizers = {
"French": FrenchLocalizer,
"English": EnglishLocalizer,
"Spanish": SpanishLocalizer,
}
return localizers[language]()
if __name__ == "__main__":
f = Factory("French")
e = Factory("English")
s = Factory("Spanish")
message = ["car", "bike", "cycle"]
for msg in message:
print(f.localize(msg))
print(e.localize(msg))
print(s.localize(msg))
工厂方法解决方案:
它的解决方案是将直接的对象构造调用替换为对特殊工厂方法的调用。实际上,对象创建没有区别,但它们是在工厂方法中调用的。
例如,我们的 Two_Wheeler、Three_Wheeler 和 Four_wheeler 类应该实现拼车接口,该接口将声明一个名为Ride的方法。每个类都将唯一地实现此方法。
现在让我们通过一个例子来理解工厂方法:
Python3
# Python Code for factory method
# it comes under the creational
# Design Pattern
class FrenchLocalizer:
""" it simply returns the french version """
def __init__(self):
self.translations = {"car": "voiture", "bike": "bicyclette",
"cycle":"cyclette"}
def localize(self, msg):
"""change the message using translations"""
return self.translations.get(msg, msg)
class SpanishLocalizer:
"""it simply returns the spanish version"""
def __init__(self):
self.translations = {"car": "coche", "bike": "bicicleta",
"cycle":"ciclo"}
def localize(self, msg):
"""change the message using translations"""
return self.translations.get(msg, msg)
class EnglishLocalizer:
"""Simply return the same message"""
def localize(self, msg):
return msg
def Factory(language ="English"):
"""Factory Method"""
localizers = {
"French": FrenchLocalizer,
"English": EnglishLocalizer,
"Spanish": SpanishLocalizer,
}
return localizers[language]()
if __name__ == "__main__":
f = Factory("French")
e = Factory("English")
s = Factory("Spanish")
message = ["car", "bike", "cycle"]
for msg in message:
print(f.localize(msg))
print(e.localize(msg))
print(s.localize(msg))
工厂方法的类图:
让我们看看以拼车为例的类图。
使用工厂方法的优点:
- 我们可以轻松添加新类型的产品,而不会干扰现有的客户端代码。
- 通常,避免产品与创建者类和对象之间的紧密耦合。
使用工厂方法的缺点:
- 要创建特定的具体产品对象,客户端可能必须对创建者类进行子类化。
- 您最终会得到大量的小文件,即文件杂乱无章。
- 在图形系统中,根据用户的输入,它可以绘制不同的形状,如矩形、正方形、圆形等。但是为了方便开发人员和客户,我们可以使用工厂方法来创建实例,具体取决于用户的输入。然后我们不必更改客户端代码来添加新形状。
- 在酒店预订网站上,我们可以预订 1 间、2 间、3 间等房间。在这里用户可以输入他要预订的房间数量。使用工厂方法,我们可以创建一个工厂类 Any Rooms,这将帮助我们根据用户的输入创建实例。同样,我们不必更改客户端的代码来添加新设施。