Design patterns 在工厂模式中,创建条件应该迁移到哪里?
在这张图上,您可以看到源类中的一些常量,它们帮助工厂生成正确的对象。我被告知这是一个反模式,我应该将这些常量移到另一个类中。我应该把它们移到工厂级吗 以下是Factory类的代码:Design patterns 在工厂模式中,创建条件应该迁移到哪里?,design-patterns,factory,Design Patterns,Factory,在这张图上,您可以看到源类中的一些常量,它们帮助工厂生成正确的对象。我被告知这是一个反模式,我应该将这些常量移到另一个类中。我应该把它们移到工厂级吗 以下是Factory类的代码: class Factory { public function make($format) { switch ($format) { case Source::Assocs:
class Factory
{
public function make($format)
{
switch ($format)
{
case Source::Assocs:
return new SourceFormatsAssocs();
case Source::XML:
return new SourceFormatsXML();
//Some more formats
}
}
}
这确实可以防止在不修改基类(添加新常量)的情况下添加新的子类。我真的会把它搬到工厂去。工厂必须了解它可以创建的所有类型的子类。基类不需要知道它的子类
此外,这些常量仅由工厂(以及工厂的调用者)使用。基类根本不使用它们。
更好的办法是考虑一个建设者。为什么?因为您可以有一个知道格式类型的抽象类,然后是构造各种子类型的具体构建器。请注意,当构建涉及在多个步骤中使某些内容变得复杂时,应该完成构建器,但也有构建器模式的变体,如Bloch中的静态构建器和fluent构建器,其中您使用该模式链接调用以使代码更具可读性,并且产品是内联生成的
另一种可能性是一个新的选择。如果您对自己的类是否值得一个构建器感到不安,那么这可能是一个很好的匹配。您是对的,但是其他类也在使用这些类型。你认为在一个名为\Formats\Types的类中增加这些常量怎么样?这也是可以接受的。在我看来,这些常量的主要用途是将它们传递给工厂,以便选择合适的子类,因此将它们放在工厂中对我来说是有意义的。看,我想将所有这些文件放在我的名为Sol的库中,使用\Sol\Data\Source\Source和\Sol\Data\Source\Formats\Assocs(或Xml,Object)等名称空间和\Sol\Data\Source\Formats\Factory。现在我想到的是客户机编码员,如果他想添加另一种格式,他没有访问Sol的权限,因此他必须以一种方式扩展工厂,即他提供包含该格式类的文件的路径,并且他必须在自己的库中扩展\Sol\Data\Source\Formats\Types?这合乎逻辑吗?现在是时候选择一种真正的编程语言了。最佳解决方案取决于您使用的语言。但是您应该使用组合而不是继承来实现可扩展工厂。向工厂添加一个
registerSubclassFactory()
方法,该方法允许客户端代码插入一个新工厂,从而允许使用一个新键创建一个新的子类实例。将基本工厂委托给其子类工厂。