工厂设计模式转换语句的位置

时间:2014-04-05 06:25:47

标签: oop design-patterns

我试图围绕工厂设计模式的有用性。

与此设计模式的许多实现(即http://msdn.microsoft.com/en-us/library/ee817667.aspx)一样,Main()中有一个switch语句,用于探测字符串以决定创建哪个ConcreteComputerFactory(稍后将其发送到ComputerAssembler.Assemble(ComputerFactory factory) )方法)。

我看到问题的方式: 1.工厂的用户(Main())“知道”具体的工厂实现,其中应该隐藏设计模式的定义。 2.每当引入一个新的concreteComputerFactory时,抽象都没有理由!我们必须转到客户端(Main())添加另一个if / case语句。

主张: 将if / switch语句移动到ComputerAssembler。 (这有一个小问题,现在ComputerAssembler有2个理由要改变:a。与创建相关的整体事物b。添加一个新的ConcreteComputerFactory。但是:这肯定比客户端(Main)好得多)

我认为我还没有完全掌握这个想法。我想听听你为什么我指定的问题不正确,以及为什么我的命题不是一个更好的主意

谢谢:)

3 个答案:

答案 0 :(得分:2)

工厂设计模式的好处不在工厂创建时间,而是在工厂及其产品使用时。创建工厂的代码知道它创建的具体类型。只有在工厂创建之后,当工厂及其产品通过其基础接口而不是其具体类型使用时,您才能看到工厂模式的好处。在基本接口上运行的代码可以创建和使用任意数量的不同具体类,而无需更改任何代码。

例如:

main()
{
  // The point isn't to hide concrete types at factory creation time
  Factory* fact = new ConcreteFactoryA();
  f(fact);
}

void f(Factory* fact)
{
  // This is where the benefit of the factory pattern is found, 
  // where the factory is *used*, not where it is created
  Product* p = fact.CreateProduct();
  p.DoSomething();
  UseProduct(p);
}

如果我用ConcreteFactoryB替换ConcreteFactoryA,创建工厂的代码必须知道该更改。但我必须以任何方式更改f()。这就是利益的来源。一旦我创建了工厂,我的其余代码就可以适应不同的具体类型而无需任何改变。

答案 1 :(得分:0)

ComputerAssembler负责组装计算机:)混合责任总是一个坏主意。通常工厂由几个独立的类共享,例如ComputerAssemblerComputerWarehouse。这就是为什么在一开始就单独选择正确的实现的原因。

建造和选择合适的工厂不是这种模式的一部分,这是一个单独的问题。在Main中使用if / else语句也不好,选择工厂并将其提供给其他对象的逻辑应该单独处理。怎么样?这取决于您的应用程序的逻辑。以下是几个例子:

1)根据应用程序启动配置正确的实现,然后您只需在配置文件中设置正确的实现。它可以通过控制反转框架来完成,这里是使用Spring的简短示例:

    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/my-context.xml");
    ComputerFactory computerFactory = applicationContext.getBean(ComputerFactory.class);
    new ComputerBuilder().build(computerFactory); 

2)您的应用应该能够在运行时切换工厂。这里有更复杂的逻辑,你可以再创建一个负责做出选择的类,并将其传递给ComputerBuilder

答案 2 :(得分:0)

为了选择抽象工厂的实现者,你也需要Selector类。

Selector有方法

Factory select() {

return new ConcreteFactory();

}

,客户端(main())将使用此方法。

之后。如果您必须选择其他实现者,则将更改选择方法