0

我有一堆派生类,它们仅在静态方法上有所不同。

(它是 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没有意义的东西。
  • 看来工厂知道的太多了,我宁愿把 A-export 的数据封装在ExporterA.

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

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

4

1 回答 1

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
于 2014-06-01T14:48:50.710 回答