Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 工厂设计模式开关语句的位置_Oop_Design Patterns - Fatal编程技术网

Oop 工厂设计模式开关语句的位置

Oop 工厂设计模式开关语句的位置,oop,design-patterns,Oop,Design Patterns,我正试图了解工厂设计模式的有用性 与此设计模式(ie)的许多实现一样,Main()中也有一个switch语句,它探测字符串以决定要创建哪个ConcreteComputerFactory(稍后将其发送到ComputerAssembler.Assembly(ComputerFactory)方法) 我对问题的看法是: 1.工厂(Main())的用户“知道”具体的工厂实现,根据设计模式的定义,这些工厂实现应该是隐藏的。 2.每当一个新的计算机工厂被引入时,抽象性就站不住脚了!我们必须转到客户机(Main

我正试图了解工厂设计模式的有用性

与此设计模式(ie)的许多实现一样,Main()中也有一个switch语句,它探测字符串以决定要创建哪个ConcreteComputerFactory(稍后将其发送到ComputerAssembler.Assembly(ComputerFactory)方法)

我对问题的看法是: 1.工厂(Main())的用户“知道”具体的工厂实现,根据设计模式的定义,这些工厂实现应该是隐藏的。 2.每当一个新的计算机工厂被引入时,抽象性就站不住脚了!我们必须转到客户机(Main())添加另一条if/case语句

提议: 将if/switch语句移到ComputerAssembler。(这有一个小问题,现在ComputerAssembler有两个原因需要更改:a.与创建相关的总体内容b.添加一个新的ConcreteComputerFactory。但是:这肯定比在客户端(主)中要好得多。)

我想我还没有完全理解这个想法。我想听听你为什么我指定的问题是不正确的,为什么我的建议不是一个更好的主意


谢谢:)

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

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

1) 每个应用程序启动都配置了正确的实现,然后您只需要在配置文件中设置正确的实现。它可以通过控制反转框架来实现,下面是使用Spring的一个简短示例:

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

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

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

例如:

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()。这就是好处所在。创建工厂后,我的代码的其余部分可以适应不同的具体类型,而无需任何更改。

要选择抽象工厂的实现者,还需要选择器类

选择器具有该方法

Factory select() {

return new ConcreteFactory();

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


在这之后。如果您必须选择另一个实现者,您将更改选择方法

谢谢您的评论,但是您回答了一个与我刚才问的问题不同的问题。正如我在问题中所写的那样,我已经知道我的提议在混合责任方面不好。但是,为什么留在客户机(Main)中是可以的,这是一个更有趣的问题。此外,将没有计算机仓库。ComputerAssembler从具体的工厂和具体的对象中抽象出来,这样就不需要创建更多的类型。IoC容器需要澄清,如果它仍然有相关版本根据您的输入,我得到一个结论:工厂是另一种表示“程序到接口,而不是具体实现”的方式。我同意这个想法,因为它将允许我们与具体的实现脱钩。但我们有吗?我不这么认为。因为即使只有一个(!)单个方法(main())耦合到特定实现也会导致耦合。我更愿意将它移出该类,让另一个类决定使用哪个特定的实现(基于它从main()获得的一些输入),然后耦合将为零。这是好还是坏?谢谢你,明白了。工厂模式与简单的“编程到接口”不同之处在于,它还将许多单独的创建决策(我应该在这里创建哪个具体P1?我应该在那里创建哪个具体P2?)整合到一个预先决策(我应该创建哪个具体工厂?)中。在某些地方,一些代码必须知道它正在创建什么具体工厂,和/或知道如何从任何可用的具体工厂中进行选择。但一旦你做出了这个决定,你就不必每次需要创建新对象时都重新研究这个决定。至于从main()分离,你可以将具体工厂选择和创建的逻辑移动到你想要的任何地方。如果您的语言支持反射,还可以使用反射来进一步解耦。我当前的项目正是这样做的——在特定的文件夹中查找DLL,询问每个DLL是否有任何factory接口的实现。