我在一个有趣的项目中遇到了这个问题,在这个项目中,我必须告诉一个类在指定的开始和结束时间(以及间隔of c)的特定时间段内执行一个操作。在
为了便于讨论,考虑类A(拥有我调用的API的类)必须调用类B(它调用类C,反过来调用类D)和E(反过来调用类F和类G)。在
A->;B->;C->;D
A->;E->;G
现在B、C、E类需要时间的上下文。我目前已经设置了它,以便类A将上下文传递给类B和E,然后它们根据需要依次传递上下文。在
我正试图找出解决这个需求的最佳方法,而不需要传递上下文,尽管我很讨厌,但我正在考虑使用Highlander(或Singleton)或Borg模式(Monostate的变体)。我只是想知道我对这些模式有什么选择。在
选项1
使用传统伯格呼吸困难综合征,例如:
class Borg:
__shared_state = {}
def __init__(self):
self.__dict__ = self.__shared_state
我可以简单地在任何地方实例化这个类,并且可以访问我想要的全局状态。在
选项2
单态的另一个变体:
^{pr2}$从理论上讲,我可以简单地通过以下方式进行扩展:
class X(InheritableBorg):
pass
为了扩展我只想:
class NewInheritableBorg(InheritableBorg):
__time = (0, 0, 'd')
从理论上讲,我可以利用多重继承,然后可以一次性访问多个borg,例如:
class X(InheritableBorg1, InheritableBorg2):
pass
我甚至可以有选择地覆盖那些东西。在
选项3
如果可能,请使用包装的嵌套函数作为类装饰器/包装器。但是,我只能使用一次,并且需要传递函数句柄。这是基于代理/委托的混合思想。在
这在我的头脑中不是具体的,但本质上类似于:
def timer(time)
def class_wrapper(class_to_wrap):
class Wrapper(class_to_wrap):
def __init__(self, *a, **kw):
super().__init__(*a, **kw)
def get_time(self):
return time
return Wrapper
return class_wrapper
@timer(time)
class A_that_needs_time_information:
pass
I think that might work... BUT I still need to pass the function handle.
摘要
所有这些都是可能的解决方案,我倾向于多重继承的Borg模式(尽管类包装很酷)。在
常规的Borg模式必须被实例化很多次,这似乎是太多的开销仅仅存储一组值。
Borg mixin的实例化次数与类的实例化次数相同。我看不出测试会有多困难。
包装器是超通用的,相对容易测试。理论上,因为它是一个函数闭包,所以我应该可以改变它,但实际上它变成了一个单例函数(这看起来太复杂了,在这种情况下,我不妨使用常规的singleton模式)。另外,传递函数句柄也会破坏目的。
除了这三种方法,还有其他方法吗?有更好的方法吗(博格人似乎不容易测试,因为没有DI)?有什么缺点我似乎错过了?在
或者我可以坚持我现在所拥有的。。。按要求消磨时间。它满足松耦合要求和DI最佳实践。。。但这太麻烦了。一定有更好的办法!在
一般来说,尽量保持简单。你在考虑一个相对简单的问题非常复杂的解决方案。在
根据您提供的信息,您似乎可以将执行操作的请求包装在一个对象中,该对象还包含上下文。然后在不同的类之间传递一个对象。例如:
如果有其他的要求可以证明需要考虑更复杂的解决方案,您应该指定它们。在
相关问题 更多 >
编程相关推荐