Python 具有相同接口的两个模块或具有相同接口的两个类的优点?
例如,我可以创建两个模块(Python 具有相同接口的两个模块或具有相同接口的两个类的优点?,python,oop,module,ooad,Python,Oop,Module,Ooad,例如,我可以创建两个模块(Mod1和Mod2),它们具有f()。或者我可以创建两个类来实现f() 那我也可以 if condition: import Mod1 as m else: import Mod2 as m m.f() 或 显然,如果我想存储任何状态,我需要使用类,但是如果我只是使用类方法,那么两种方法中的任何一种都比另一种有优势吗 编辑:我最关心的是可维护性/可扩展性/可读性,而不是运行时性能。总体思路 在您的特定情况下,您可以使用简单的模块级功能,而不是使一切都
Mod1
和Mod2
),它们具有f()
。或者我可以创建两个类来实现f()
那我也可以
if condition:
import Mod1 as m
else:
import Mod2 as m
m.f()
或
显然,如果我想存储任何状态,我需要使用类,但是如果我只是使用类方法,那么两种方法中的任何一种都比另一种有优势吗
编辑:我最关心的是可维护性/可扩展性/可读性,而不是运行时性能。总体思路
在您的特定情况下,您可以使用简单的模块级功能,而不是使一切都过于复杂。但是,就你对一般情况感兴趣而言,我建议你同意。以下是一个示例解决方案:
class YourAbstractFactory(object):
@classmethod
def get_factory(cls, condition):
cond_map = {
'impl1': Impl1,
'impl2': Impl2
}
impl = cond_map.get(condition)
return impl() if impl else None
def f1(self):
pass
def f2(self):
pass
YourAbstractFacotry
类显然是一个抽象类,它只定义要实现的接口,即f
函数的集合。此外,它还定义并实现了get\u factory
类方法,该方法根据条件返回适当的实现
class Impl1(YourAbstractFactory):
def f1(self):
print('Impl1.f1')
def f2(self):
print('Impl1.f2')
class Impl2(YourAbstractFactory):
def f1(self):
print('Impl2.f1')
def f2(self):
print('Impl2.f2')
上面的类是接口的两个独立实现。它们彼此不知道,可以独立存在
# This is where you put your condition, and get appropriate instance
>>> impl = YourAbstractFactory.get_factory('impl2')
>>> impl.f1()
Impl2.f1
因此,在一般情况下,此解决方案的优点是,您的客户机代码将与您的实现解耦。这意味着,您将只通过条件并获得所需的实现,而不知道客户机代码中的实现,也不依赖于该实现。唯一了解接口具体实现的是get\u factory
方法,该方法易于维护
其他改进
为了进一步增强此解决方案并提高安全性(尽管Python是一种成人语言;),您还可以使用模块及其元类和装饰器来防止初始化未实现所有接口的类的实例。在这种情况下,您需要像这样定义factory类
from abc import ABCMeta, abstractmethod
class YourAbstractFactory(object):
__metaclass__ = ABCMeta
@classmethod
def get_factory(cls, condition):
cond_map = {
'impl1': Impl1,
'impl2': Impl2
}
impl = cond_map.get(condition)
return impl() if impl else None
@abstractmethod
def f1(self):
pass
@abstractmethod
def f2(self):
pass
我想这将取决于你使用f()的频率/内容。在这种特定情况下,我可能只调用每个方法一次,但我也很好奇一般情况。我想一般来说,你会创建模块,而不是类,因为类通常与创建具有属性的对象实例、类方法、,等等,而不仅仅是为了功能。
from abc import ABCMeta, abstractmethod
class YourAbstractFactory(object):
__metaclass__ = ABCMeta
@classmethod
def get_factory(cls, condition):
cond_map = {
'impl1': Impl1,
'impl2': Impl2
}
impl = cond_map.get(condition)
return impl() if impl else None
@abstractmethod
def f1(self):
pass
@abstractmethod
def f2(self):
pass