假设您有一个基类(例如Animal
)和一个工厂(AnimalFactory
)使用模板方法执行相同的操作(使用不同的细节)来创建实例。 AnimalFactory
接受AnimalDetails
以便能够建立动物:
我使用伪代码使问题足够通用。
class Animal {}
class AnimalDetails {}
class AnimalFactory {
makeBaby:Animal(details:AnimalDetails) { /* some special action */ }
createTemplate:Animal (details:AnimalDetails) {
makeBaby(details)
return baby
}
}
然后我用他们的工厂和专门的参数创建一个子类Bird和Mammal:
class Bird:Animal {}
class BirdDetails:AnimalDetails {}
class Mammal:Animal {}
class MammalDetails:AnimalDetails {}
class BirdFactory:AnimalFactory {
makeBaby:Bird(details:BirdDetails) { /* bird specific action using bird details */
}
class MammalFactory:AnimalFactory {
makeBaby:Mammal(details:MammalDetails) { /* mammal specific action using bird details */
}
这显然不是类型正确的,因为模板方法(AnimalFactory.createTemplate
)期望AnimalDetails
参数。
我花了一些时间来提出使用模板的类型正确的解决方案,并且在输入类型上是灵活的(只要它适合工厂的子类方法) - 但没有什么是足够好的。你能想出一个更好的方法来处理这个问题吗?
答案 0 :(得分:1)
通常,当所有具体工厂都可以通过与抽象工厂具有相同的输入来实例化不同的实现时,应用工厂模式。您的示例显示您对具体工厂的输入与抽象工具的输入不同。这意味着,您没有正确使用工厂模式。
要解决此问题,您需要使输入创建成为实施细节。
可以找到许多方法来实现这一目标。我可以告诉你2个选项:
拥有AnimalFactories的工厂。所以,这个工厂(创建者)通过什么都不做来创建AnimalFactory。在不同的实现中,它们构造并将具体的AnimalDetail实例传递给具体的AnimalFactory实例。
让您的工厂更加独立。不传递它们,让具体的实现构建并使用具体的AnimalDetail。
简而言之,这意味着,AnimalDetail 实际上并不是一个抽象的东西 - 它只是不同的情况。如果它真的是抽象的,那么你的消费者就可以在不知道差异的情况下使用它。但事实并非如此。根据这一发现,我根本不需要将AnimalDetail作为抽象类型。
答案 1 :(得分:0)
您是否尝试过应用abstract factory模式?看一下链接中的真实世界代码。