如何将专门的参数传递给工厂模板?
How to pass specialized arguments to a factory template?
假设你有一个基础class(例如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
}
}
然后我创建一个子class 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
参数。
我花了一些时间想出类型正确的解决方案,该解决方案使用模板并在输入类型上灵活(只要它适合工厂 subclass 方法)- 但没有什么好足够的。您能想出更好的方法来处理这个问题吗?
您是否尝试应用 abstract factory 模式?看看 link.
中的真实代码
通常,当所有具体工厂都可以通过与抽象工厂具有相同的输入来实例化不同的实现时,就会应用工厂模式。您的示例表明您对具体工厂的输入与抽象工厂的输入不同。这意味着,您没有正确使用工厂模式。
要更正此问题,您需要将输入创建作为实现细节。
可以找到许多方法来实现这一点。我可以告诉你 2 个选项:
拥有 AnimalFactories 工厂。因此,这个工厂(创建者)创建了 AnimalFactory,什么都不拿。在不同的实现中,它们构造具体的 AnimalDetail 实例并将其传递给具体的 AnimalFactory 实例。
让您的工厂更加独立。什么都不传,让具体的实现构造和使用具体的AnimalDetail。
简而言之,这意味着 AnimalDetail 并不是真正抽象的东西 - 它只是 不同 因情况而异。如果它真的很抽象,您的消费者将能够在不知道差异的情况下使用它。但事实并非如此。基于这一发现,我认为根本不需要将 AnimalDetail 作为抽象类型。
假设你有一个基础class(例如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
}
}
然后我创建一个子class 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
参数。
我花了一些时间想出类型正确的解决方案,该解决方案使用模板并在输入类型上灵活(只要它适合工厂 subclass 方法)- 但没有什么好足够的。您能想出更好的方法来处理这个问题吗?
您是否尝试应用 abstract factory 模式?看看 link.
中的真实代码通常,当所有具体工厂都可以通过与抽象工厂具有相同的输入来实例化不同的实现时,就会应用工厂模式。您的示例表明您对具体工厂的输入与抽象工厂的输入不同。这意味着,您没有正确使用工厂模式。
要更正此问题,您需要将输入创建作为实现细节。
可以找到许多方法来实现这一点。我可以告诉你 2 个选项:
拥有 AnimalFactories 工厂。因此,这个工厂(创建者)创建了 AnimalFactory,什么都不拿。在不同的实现中,它们构造具体的 AnimalDetail 实例并将其传递给具体的 AnimalFactory 实例。
让您的工厂更加独立。什么都不传,让具体的实现构造和使用具体的AnimalDetail。
简而言之,这意味着 AnimalDetail 并不是真正抽象的东西 - 它只是 不同 因情况而异。如果它真的很抽象,您的消费者将能够在不知道差异的情况下使用它。但事实并非如此。基于这一发现,我认为根本不需要将 AnimalDetail 作为抽象类型。