我有两个耦合的课程DhcpServer
和SessionManager
。我的规格中有以下要求导致了这种耦合:
DhcpServer
禁止,则{li> SessionManager
不得发出IP地址租约(例如,在创建会话时发生错误)
SessionManager
必须在DhcpServer
创建新租约后启动会话,并在租约到期或客户明确发布后立即销毁会话DhcpServer
必须在SessionManager
停止相应会话时(例如通过系统管理员的请求)销毁租约首先,很容易将所有代码放入一个类中。但责任是截然不同的,所以我将它们分成两部分并创建了两个接口:
class ISessionObserver(object):
def onSessionStart(**kwargs): pass
def onSessionStop(**kwargs): pass
class IDhcpObserver(object):
def onBeforeLeaseCreate(**kwargs):
"""
return False to cancel lease creation
"""
pass
def onLeaseCreate(**kwargs): pass
def onLeaseDestroy(**kwargs): pass
然后我在IDhcpObserver
中SessionManager
和ISessionObserver
中DhcpServer
实施了SessionManager
。这导致了耦合。尽管类不直接相互依赖,但它们依赖于彼此包中声明的接口。
后来我想为会话启动添加另一个协议,使IAnotherProtocolObserver
的逻辑保持不变。我也不希望它实现SessionManager
。
此外,DHCP服务器与我的会话概念无关。由于Twisted(我正在使用)没有DHCP协议实现,我想将它作为一个单独的项目发布,它既不依赖于{{1}}也不依赖于它的包。
如何在保持代码片松散耦合的同时满足我的规范要求?
答案 0 :(得分:5)
解耦类的好方法是使用events。
所以你需要做的是在事情发生时“开火”事件。示例:SessionManager
可以创建会话时发送“创建会话”事件。让DhcpServer
监听该事件并在收到它时准备租约。
现在你需要的是第三个类,它创建另外两个并配置事件监听器。
这个解决方案的美妙之处在于它让一切变得简单。当你编写单元测试时,你总是只需要其中一个类,因为你只需要检查是否已经触发了正确的事件。