表驱动的工厂vs继承

时间:2014-06-01 14:24:39

标签: oop factory table-driven

我有一堆派生类,只有静态方法才有所不同。

(它是Ruby,但问题不在于Ruby,而在于设计。)

class Exporter
  def export
    # ...
  end
end

class ExporterA < Exporter
  def from
    'aaa_table'
  end

  def fields
    ['a1', 'a2', 'a3']
  end

  def to
    'aaa_file'
  end
end

class ExporterB < Exporter
  def from
    'bbb_table'
  end

  def fields
    ['b1', 'b2', 'b3']
  end

  def to
    'bbb_file'
  end
end

所以,我看了这个,想出了将所有这些静态数据放到某种表中,并使用Exporter和适当的属性。在这种情况下,我需要一些ExporterFactory类,它将知道谁是谁以及如何创建A和B出口商。

class ExporterFactory
  def _table
    return {
      :a => {
        :from => 'aaa_table',
        :fields => ['a1', 'a2', 'a3'],
        :to => 'aaa_file',
      },
      :b => {
        :from => 'bbb_table',
        :fields => ['b1', 'b2', 'b3'],
        :to => 'bbb_file',
      },
    }
  end

  def create(type)
    return Exporter.new(self._table[type])
  end
end

再次,我看了这个,现在我不喜欢这种方法。原因:

  • _table的真实数据要大得多,所以我的桌子看起来很重,很难看。
  • 现在,您可以创建一个真正有意义的Exporters
  • 看起来工厂知道的太多了,我更希望在ExporterA中封装有关A-export的数据。

我无法决定。第二种方法似乎更符合逻辑,但我仍然想使用第一种方法。我的主要想法是“我想用继承来组织那个大而丑陋的桌子”。

我应该选择什么?我会在每种方式中遇到什么样的问题?

1 个答案:

答案 0 :(得分:1)

我同意您的工厂知道太多,这意味着每次出口商变更时都必须更改。此外,如果您有一个需要额外代码的导出程序,则无法创建它。如果您需要,您的第一个设计允许您编写覆盖超类方法的导出器。

您可以将数据放在initialize中并覆盖而不是三种方法,从而使您的第一个设计更简洁:

class Exporter
  attr_accessor :from, :fields, :to

  def initialize(from, fields, to)
    self.from = from
    self.fields = fields
    self.to = to
  end

  def export
    # ...
  end

end

class ExporterA < Exporter
  def initialize
    super 'aaa_table', ['a1', 'a2', 'a3'], 'aaa_file'
  end 
end

class ExporterB < Exporter
  def initialize
    super 'bbb_table', ['b1', 'b2', 'b3'], 'bbb_file'
  end 
end