ruby-on-rails - 在 Rails 中将继承转换为组合

标签 ruby-on-rails ruby oop design-patterns inheritance

我在遗留系统中有一个看起来像这样的模型:

 class Prize < ActiveRecord::Base

   def win
     # do a bunch of things
   end
 end

我们从一个奖品开始,但与其他任何奖品一样,我们正在处理的奖品类型也开始扩大。所以现在 def win 正在做一大堆案例/转换来决定奖品类型。

出于这个原因,我决定这样做:

class DailyPrize < Prize
   def win
     #do only daily prize stuff, no type checking.
   end
end

这段代码在我们将其发送给 QA 之前正在接受审查,现在我被要求使用组合(mixin)而不是子类来执行此操作。我想不出一个干净的方法来做到这一点。

遗留代码库在很多地方执行以下操作,我不想到处更改内容:

prize = 奖品.new 获奖.win

那么,我的问题是如何使用组合实现这一点?

最佳答案

这是我通过组合而非继承替换您的代码的理解。

class Prize < ActiveRecord::Base

  def prize
    @prize ||= PrizeFactory.build(self)
  end

  def win
    prize.win
  end
end

class PrizeFactory
  def self.build(prize)
    if prize.daily?
      DailyPrize.new(prize)
    # other condition to build specific prize
    end
  end
end


class DailyPrize
  def initialize(prize)
    @prize = prize
  end

  def win
    #do only daily prize stuff
    #access @prize to get @prize attribute
    #if you use it, you have coupling (see below)
  end
end

问题是,这可能并不比您的实现更好,它实际上取决于您在领域逻辑方面取得的成就。

使用组合,一个目标是减少对象之间的耦合,如果你调用了很多 @prize DailyPrice 中的对象方法win方法,你在这两个类之间有一个紧密的耦合,你可能会失去组合的好处。

关于ruby-on-rails - 在 Rails 中将继承转换为组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13571076/

相关文章:

ruby-on-rails - 如何 stub i18n_scope 以在 Rails 4 rspec 3.3.0 上模拟 ActiveRecord::RecordInvalid?

ruby-on-rails - M. Hartl 的密码 Ruby on Rails 教程

ruby-on-rails - 在 heroku 上找不到字体 (404)

ruby - 无法使 setter 方法起作用

oop - 使用复数来命名集合是一种好习惯吗?

ruby-on-rails - RoR - "A Server is already running"- 我如何杀死正在运行的服务器?

ruby-on-rails - 在 Rails 应用程序中上传视频

ruby-on-rails - Errno::ECONNREFUSED:连接被拒绝 - connect(2) for action mailer

vb.net - 在此类中使用 Properties 有什么好处吗?

objective-c - Objective-C - 如何实现自定义回调方法但强制执行特定参数?