我发现自己在许多实现类似接口的后端类上编写了一个包装类。基本版本看起来像这样:
class Wrapper(BackendInterface):
def __init__(self, **kwargs):
# Instantiate/initialize backend classes
self._b1 = BackendOne(...)
self._b2 = BackendTwo(...)
...
def _select_backend(self, ...):
# Select backend based on runtime requirements
if condition_one:
return self._b1
elif condition_two:
return self._b2
...
def method_one(self, foo, bar, baz, alpha, beta, gamma, delta, ...):
b = self._select_backend(...)
b.method_one(foo, bar, baz, alpha, beta, gamma, delta, ...)
def method_two(self, a, b, c, d, ...):
b = self._select_backend(...)
b.method_two(a, b, c, d, ...)
...
如上所示,许多(但不是全部)方法归结为后端选择,然后在后端对象上调用相同的方法。在许多情况下,甚至方法签名也是相同的。有没有办法避免这种样板乱七八糟?
我考虑过在每个方法的顶部使用locals()。
...
def method_one(self, foo, bar, baz, alpha, beta, gamma, delta, ...):
args = locals() # Must be the first line!
del args['self']
b = self._select_backend(...)
b.method_one(**args)
...
我相信使用检查模块可以获得类似的结果。
但这种方法存在一些问题。 1.还有很多样板。 2. locals()调用必须在第一行。我很确定有人会尝试在某个时候“优化”该方法并搞砸它。
我可以使用更好的方法吗?
我也有兴趣了解如何在Java中处理这种情况。
注意:如果重要的话,我正在使用Python 2.7.11。
编辑:删除了Java标记。我将分别为Java提出这个问题。这样Python开发人员就不必阅读Java代码,反之亦然。
答案 0 :(得分:0)
当然,您可以在方法中接受*args
- 或*args, **kwargs
- 并将其传递到后端?
def method_one(self, *args, **kwargs):
b = self._select_backend(...)
b.method_one(*args, **kwargs)
答案 1 :(得分:0)
这是我最终为Python做的事情
class Wrapper(BackendInterface):
def __init__(self, **kwargs):
# Instantiate/initialize backend classes
self._b1 = BackendOne(...)
self._b2 = BackendTwo(...)
...
def __dispatch_to_backend(method):
@functools.wraps(method, updated=[])
def wrapper(self, *args, **kwargs):
method_impl = getattr(self._select_backend(...), method.__name__)
return method_impl(*args, **kwargs)
return wrapper
def _select_backend(self, ...):
# Select backend based on runtime requirements
if condition_one:
return self._b1
elif condition_two:
return self._b2
...
method_one = __dispatch_to_backend(BackendInterface.method_one)
method_one = __dispatch_to_backend(BackendInterface.method_two)
...
我猜这是免费的样板文件。