我有一个使用我写的消息队列的简单发布/订阅模块的组件。我想试试像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这样的东西,但似乎会变得混乱。好处是我不必修改代码来支持交换组件。
任何其他想法或轶事都将受到赞赏。
编辑:修正缩进。
答案 0 :(得分:2)
我之前做过的一件事是创建一个每个特定实现继承自的公共类。然后有一个可以轻松遵循的规范,每个实现都可以避免重复他们共享的某些代码。
这是一个不好的例子,但您可以看到如何使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()