2012-04-06 127 views
2

这是情况。我有以下的伪类:将对象传递给其他对象 - 通过方法或构造函数?

class Agent: 
    def __init__(self): 
     self.blah = whatever 
     self.boo = thingy 

    def doA(self, transport): 
     res = transport.doX(self.blah) 

    def doB(self, transport): 
     res = transport.doY(self.boo) 

class Transport: 
    def __init__(self): 
     self.bah = weee 

    def doX(self, item): 
     #.. do some other stuff here 

    def doY(self, item): 
     #.. do some more stuff here 

现在,我的问题是 - 我应该通过我的传送对象为代理方法对于需要或者我应该简单地通过运输对象为代理构造方法并从方法内调用它?即

transport = Transport() 
agent = Agent(transport) 
class Agent: 
    def __init__(self, transport): 
     self.blah = whatever 
     self.transport = transport 

    def doA(self): 
     res = self.transport.doX(self.blah) 

我搬到交通运输出它自己的类的原因是:

1)代理实例可以共享相同的传输对象 - 即:我只需要1个运输对象为一组代理。我可以有多个传输(一个用于代理A..N,另一个用于代理O..Z)。

2)Transport包含将代理列表作为参数的方法。例如,它可以对代理运行一个并发通信测试,给出一个代理对象列表。

但是,代理本身有时需要在传输中设置的属性(SSL证书的位置等),以便在代理类中有意义的某些方法(远程重新启动代理等)。

我是否应该采用需要代理列表的方法并将它们移动为Transport的类方法,然后在包含Transport实例的代理对象中创建一个属性?我是否应该继续我正在做的事情,并且只需要将传输对象传递给某些代理对象方法?我应该以某种我没有看到的方式来重构这一切吗?

任何有用的意见将不胜感激。

+0

听起来像你有另一层耦合打破。 – 2012-04-06 00:30:05

+0

1)同一个代理是否会与几种不同的传输工作? 2)在任何交通工具连接之前,代理人是否可以做一些有用的事情? 3)在任何代理连接之前,运输工具能做些有用的事情吗? – max 2012-04-06 01:12:00

+0

Ignacio,我同意 - 但我问这是因为我不确定如何去耦合它们。 – sjmh 2012-04-06 15:29:36

回答

3

由于您甚至考虑将运输作为参数添加到代理的构造函数中,因此我假设一个代理将不会使用多个传输。

我假设一个传输实例可以在没有任何代理连接到它的情况下做一些有用的事情,反之亦然。

如果我的假设是正确的,我会提出这样的:

class System: 
    def associate_transport_and_agent(transport, *agents): 
    for agent in agents: 
     transport.add_agents(*agents) 
     agent.set_transport(transport) 

class Transport: 
    def __init__(self): 
    self.bah = weee 
    self.agents = set() 
    def add_agents(self, *agents): 
    self.agents.update(agents) 
    def remove_agent(self, agent): 
    self.agents.remove(agent) 
    def doX(self, item): 
    # ... 


class Agent: 
    def __init__(self): 
    self.blah = whatever 
    self.transport = None 
    def set_transport(self, transport): 
    if self.transport == transport: 
     return 
    if self.transport is not None: 
     self.transport.remove_agent(self) 
    self.transport = transport 

    def doA(self): 
    res = self.transport.doX(self.blah) 

如果您打算删除对象,你可能需要使用从任一代理弱引用在运输或其他方向,以帮助垃圾收集器(或者事实上,就你的情况而言,在这两个方向上,因为你可能在其他地方包含强烈的引用)。

编辑:

更新,以反映代理人可能会改变他们的运输:

  • 改变的代理列表设置代理
  • 添加Transport.remove_agent
  • 修改Agent.set_transport检查如果之前已经设置了
+0

座席只能使用1次运输工作,尽管可以切换运输工具。因为这实际上只是一个更大的服务器/客户端体系结构的API,所以我会说不。我必须使用运输工具与代理商沟通以做有用的事情。我把运输工具搬出去的唯一原因是因为同时在几个代理商之间运作的方法。在代理中保持这种逻辑似乎是错误的想法(即 - 在一个代理中使用一种方法来影响其自身和其他代理)。我会尝试像你上面张贴的东西。 – sjmh 2012-04-06 15:20:15

+0

我更新了代码以反映这一点。 – max 2012-04-06 16:20:44

0

鉴于“代理人可以您曾经使用过1次运输,尽管该运输可以切换“,我建议您为您的__init__设置一个(可选)参数来设置运输,并让代理的运输属性为公开。如果您需要在分配时运行代码,请创建一个属性。

相关问题