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

さて、私の質問は、トランスポートオブジェクトをそれを必要とするメソッドのAgentメソッドに渡すのか、それとも単にTransportオブジェクトをAgentコンストラクターに渡して、メソッド内から呼び出すのかということです。すなわち

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)

Transportを独自のクラスに移動した理由は次のとおりです。

1)エージェントインスタンスは同じトランスポートオブジェクトを共有できます。つまり、エージェントのセットに必要なトランスポートオブジェクトは1つだけです。複数のトランスポートを持つことができます(1つはagentsA..N用、もう1つはagentsO..Z用)。

2)トランスポートには、エージェントのリストを引数として取るメソッドが含まれています。たとえば、エージェントオブジェクトのリストを指定して、エージェントへの同時通信テストを実行できます。

ただし、エージェント自体は、Agentクラスに含まれる意味のあるメソッド(エージェントをリモートで再起動するなど)の一部について、トランスポート(SSL証明書の場所など)に設定された属性を必要とする場合があります。

エージェントのリストを必要とするメソッドを取得し、それらをTransportのクラスメソッドに移動してから、Transportインスタンスを含むAgentオブジェクトに属性を作成する必要がありますか?実行していることを続行し、Transportオブジェクトを特定のAgentオブジェクトメソッドに渡すことだけを要求する必要がありますか?表示されていない方法でこれをすべてリファクタリングする必要がありますか?

ご意見をいただければ幸いです。

4

2 に答える 2

3

エージェントのコンストラクターへの引数としてトランスポートを追加することも検討しているので、1つのエージェントが複数のトランスポートで機能することはないと思います。

トランスポートインスタンスは、エージェントが接続されていなくても何か便利なことができると思います。その逆も同様です。

私の仮定が正しければ、私はこれを提案します:

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を変更して、以前にすでに設定されているかどうかを確認します
于 2012-04-06T01:25:29.143 に答える
0

「エージェントは1つのトランスポートでしか機能できませんが、そのトランスポートは切り替えることができます」ということを考えると、トランスポートを設定するための(オプションの)パラメーターを__init__設定し、エージェントのトランスポート属性をパブリックにすることをお勧めします。割り当て時にコードを実行する必要がある場合は、プロパティを作成します。

于 2012-04-06T16:39:31.400 に答える