如何让父对象拥有的2个对象在Ruby中相互通信?

时间:2011-06-01 09:59:49

标签: ruby oop

首先,如果这是一个n00b问题,我很抱歉。我是一名自学成才的网络开发人员,这是我第一次真正涉足应用程序。我试图找到我正在寻找的答案,但我不确定正确的术语,所以没有找到任何相关的结果。我想这是因为要么我不知道正确的方式要求我需要什么;答案是如此明显,它不需要写或我要求的是如此愚蠢的概念不存在我应该完全这样做。

无论如何,关于我的问题。我正在开发一个有3个课程给我带来麻烦的应用程序。有'MainContainer',主要处理UI;挑选任务的'Assigner';以及执行任务的“工人”。它处于一个非常早期的阶段,但现在它看起来很像。

class MainContainer

  def setup
    @worker = Worker.new(:x => 200, :y => 200)
    @assigner = Assigner.new(:x => 400, :y => 300)
  end

  # update & draw code
end

class Assigner

  def set_target
    parent.worker.target self.x, self.y
  end

  # input, update & draw code
end

class Worker < GameObject

  def target(tx, ty)
    @target_x = tx
    @target_y = ty
    @has_task = true
  end

  # update & draw code
end

应用程序的基本流程如下:MainContainer的一个实例加载并在屏幕上显示UI,包括分配者和工作者。然后,用户使用分配器在UI中移动并选择任务。到目前为止,一切正常。

我无法弄清楚Assigner如何将值传递给worker。我在示例中的代码是worker的set_target方法。 parent.worker.target self.x, self.y行是我最近的尝试。我在这里尝试的其他内容包括@worker.target self.x, self.y

等内容

我正在考虑将@worker传递给@assigner,但计划是有一个随着时间的推移会增加/减少的工人数量。我计划使用WorkerManager来处理这些问题,这将跟踪当前有多少工作人员可用,但是如果我将其传递给@assigner,它是不是只传递了它的副本?我仍然没有实现类似的东西,所以我没有测试过,也许这是要走的路?

我想到的另一件事就是让工人成为一个全球性的人,但这个问题很可能会再次频繁发生,所以我最终会得到一个满是全球的应用程序,我猜这不是正确的方式!

我来自web-dev,所以我能想到的唯一其他解决方案就是数据库的全部数据库。如果我无法获得其他任何东西,这是最后的手段。

无论如何,要重新陈述我的问题。在MainContainer的一个实例中,如何让Assigner和Worker在彼此之间传递数据?

我真的很感激这里有任何帮助,即使它有点像“stfu n00b,请阅读:相关链接”。

2 个答案:

答案 0 :(得分:1)

我认为设计中存在一个缺陷。你说Assigner选择任务而工人做了。看起来他们不需要沟通。如果他们需要,他们可能会做的比你描述的要多,这可能表明有机会重构成更孤立的课程,责任更少。

那么,如果MainContainer完全控制了怎么办?

def main
  @worker = Worker.new
  @assigner = Assigner.new
  target = @assigner.target
  result = @worker.do_work(target)
  update_ui(result)
end

UI应该与业务逻辑分开,上面的伪代码只是说明了对MainContainer进行控制以避免让Worker和Assigner相互通信的想法。如果需要,这还允许您处理多个工作人员。

我希望这会有所帮助。

答案 1 :(得分:1)

我的回答可能会受到这样一个事实的影响,即我没有明确指出问题所在,所以请记住这一点并在我错误的地方纠正我。

最好的方法可能是完全隔离工人和分配者,并将所有逻辑放入控制器。

但是,如果您需要工作人员之间进行更多沟通,并且您希望让参与者参与其中,那么分配者可能知道它创建的工作人员和工作人员知道哪个分配者创建了它们。然后,分配者应该负责创建工作者(以及创建分配者的控制器)。像(丑陋,非优化和未经过测试的代码):

class Assigner
  attr_reader :workers
  def initialize
    @workers = []
  end
  def create_worker
    worker = Worker.new
    worker.assigner = self
    @workers << worker
    worker
  end
end

class Worker
  attr_accessor :assigner
end

当然,您需要管理每个分配者的工作人员集合,例如一旦完成工作,就将他们移除。

Ruby中的所有内容都作为引用传递,因此不会在方法调用中复制对象。一个discussion on the ruby forum can be found。 (这也是你在问题中想知道的。)

我希望我的答案有所帮助。如果没有,请在评论中指出,我会尽力改进。