当规范坚持时,如何避免类耦合

Iho*_*nko 3 python architecture design-patterns decoupling

我有两个耦合的类DhcpServerSessionManager.我的规格中有以下要求导致了这种耦合:

  • DhcpServer如果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
Run Code Online (Sandbox Code Playgroud)

然后,我实现了IDhcpObserverSessionManagerISessionObserverDhcpServer.这导致了耦合.即使类不直接相互依赖,它们依赖于彼此包中声明的接口.

后来我想为会话启动添加另一个协议,SessionManager保持逻辑不变.我也不希望它也能实现IAnotherProtocolObserver.

此外,DHCP服务器与我的会话概念无关.由于Twisted(我正在使用)没有DHCP协议实现,我想将它作为一个单独的项目发布,它既没有依赖也没有依赖SessionManager它的包.

如何在保持代码片松散耦合的同时满足我的规范要求?

Aar*_*lla 5

解耦类的好方法是使用事件.

所以你需要做的是在事情发生时"发射"事件.示例:当SessionManager可以创建会话时发送事件" 创建会话".使DhcpServer侦听该事件,当它接收到它准备租约.

现在你需要的只是第三个类,它创建另外两个并配置事件监听器.

这个解决方案的优点在于它可以保持一切简单.编写单元测试时,您将始终只需要其中一个类,因为您只需检查是否已触发正确的事件.

  • 所以,如果我理解正确,我的观察者界面就可以了.但是,不是在`DhcpServer`和`SessionManager`中交叉实现它们,而是应该引入第三个.这个类是一个中介,它实现了观察者接口并调用了'DhcpServer`和`SessionManager`的方法,对吧? (2认同)