我有一堆派生类,它们只是静态方法不同。
(这是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
中
我不能决定。第二种方法似乎更符合逻辑,但我仍然想使用第一种方法。我的主要想法是"我想用继承来组织那个又大又丑的表"。
我应该选择什么?在这两种情况下会有什么样的问题呢?
我同意您的Factory知道的太多,这意味着每次任何出口商更改时它都必须更改。此外,如果您有一个需要额外代码的export,那么将无法创建它。你的第一个设计允许你在需要的时候编写覆盖超类方法的出口商。
您可以通过将数据放在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