2

我有一个正在使用 ruby​​ 进行的项目,它需要一些工人的大量工作。大多数业务逻辑都包含在这些工作人员中,它们变得相当复杂。我设计的技术模拟了 compose 方法模式,但它严重依赖实例变量来保持状态。我设置它的方式似乎是合乎逻辑的,但我想从社区获得一些反馈,看看这是否是错误的,或者不是我可以设置的最干净的方式。

我本质上是使用工人执行(Sidekiq)方法作为一种开关

def perform(transaction_id, data, account_id)
  @transaction_id = transaction_id
  @data           = data
  @account        = Account.new(account_id)

  @campaign_tag   = nil
  @match_str      = nil
  @options        = nil

  has_starter_tag     || return
  find_campaign       || return
  determine_options   || return
  find_active_option  || return
  reservation_over    || return
  already_filled      || return

  send_to_inventory
end

每种方法都遵循相同的逻辑。检查规则,如果不满意,执行操作(发送电子邮件等)并返回 false,从而停止执行。如果满意,则存储一些完成事务所需的 ivar 数据并返回 true,从而进入下一步。

def has_starter_tag
  result = true

  @campaign_tag = find_starter_tag(@account, @data[:variable])
  if !@campaign_tag
    result = false
    send_email_about_badness
    log_some_stuff
  end

  result
end

为了测试这段代码,我对每个方法所依赖的实例变量进行了存根。我知道这是一种代码味道,因为我的测试知道实现而不是接口。也就是说,我喜欢这些方法的干净界面,我觉得我可以扫描源代码并确切地知道发生了什么。

如果我做错了,有人可以花点时间解释一下正确的方法(或至少另一种方法)吗?我一直在弄清楚如何处理必须执行许多似乎相互依赖的小步骤的对象时遇到问题。

4

1 回答 1

1

我的直觉是,您正试图对此进行过度架构。

您所描述的内容不算作设计模式-它只是将所需的功能分成许多单独的方法。问题是这些方法彼此紧密耦合,以至于将它们分开除了“分组”功能之外没有其他用途。这些功能似乎唯一的共同点是它们检查某些内容并取消检查失败的工作。除了重复功能之外,您可以通过将所有代码放在一个函数中并用空行分隔各个部分来实现大致相同的效果。

有时在代码中找到一些 OOP 解决方案或设计模式可能会适得其反。归根结底,真正重要的是,它是否提供了优势?它会保存代码吗?它是否使代码易于维护和扩展?(代码是否需要易于扩展?)不要为了 OOP 而尝试使用 OOP。

于 2012-05-24T00:51:01.363 回答