我有一个组件,它使用我作为消息队列编写的简单发布/子模块.我想试试像RabbitMQ这样的其他实现.但是,我想使这个后端更改可配置,以便我可以在我的实现和第三方模块之间切换清洁度和测试.
显而易见的答案似乎是:
>阅读配置文件
>创建可修改的设置对象/字典
>修改目标组件以延迟加载指定的实现.
就像是 :
# component.py
from test.queues import Queue
class Component:
def __init__(self, Queue=Queue):
self.queue = Queue()
def publish(self, message):
self.queue.publish(message)
# queues.py
import test.settings as settings
def Queue(*args, **kwargs):
klass = settings.get('queue')
return klass(*args, **kwargs)
不确定init是否应该接受Queue类,我认为这有助于轻松指定测试时使用的队列.
我的另一个想法就像http://www.voidspace.org.uk/python/mock/patch.html,虽然看起来会变得混乱.好处是我不必修改代码来支持交换组件.
任何其他想法或轶事将不胜感激.
编辑:修复缩进.
最佳答案 我之前做过的一件事是创建一个每个特定实现继承自己的公共类.然后有一个可以轻松遵循的规范,每个实现都可以避免重复他们都共享的某些代码.
这是一个糟糕的例子,但您可以看到如何使saver对象使用指定的任何类,其余代码也不关心.
class SaverTemplate(object):
def __init__(self, name, obj):
self.name = name
self.obj = obj
def save(self):
raise NotImplementedError
import json
class JsonSaver(SaverTemplate):
def save(self):
file = open(self.name + '.json', 'wb')
json.dump(self.object, file)
file.close()
import cPickle
class PickleSaver(SaverTemplate):
def save(self):
file = open(self.name + '.pickle', 'wb')
cPickle.dump(self.object, file, protocol=cPickle.HIGHEST_PROTOCOL)
file.close()
import yaml
class PickleSaver(SaverTemplate):
def save(self):
file = open(self.name + '.yaml', 'wb')
yaml.dump(self.object, file)
file.close()
saver = PickleSaver('whatever', foo)
saver.save()