9

我见过使用静态方法的工厂实现。像这样的东西:

public class MyFactory {
    public static Product1 createProduct1() {}
    public static Product2 createProduct2() {}
}

p1 = MyFactory.createProduct1();
p2 = MyFactory.createProduct2();

我不确定我是否可以称它为抽象工厂,但这不是问题所在。我对抽象工厂的理解是,它使我们能够灵活地轻松更改产品系列。

Factory factory = new MyFactory();  // might be a global or Singleton
p1 = factory.createProduct1();
p2 = factory.createProduct2();

如果我想从 更改MyFactoryYourFactory则只需要更改一行。我也可以在运行时更改它。但是,如果它们被实现为静态方法,有可能吗?我需要更改对静态工厂的所有调用。如果我们想在运行时决定,还需要在每个地方使用 if-else 检查。

p1 = YourFactory.createProduct1();
p2 = YourFactory.createProduct2();

那么使用静态方法实现工厂有什么好处呢?我们不是失去了主要的灵活性吗?我在这里错过了什么?

请注意,没有假定特定的语言。任何帮助表示赞赏。

4

5 回答 5

11

使用这样的静态方法,您可以获得一些代码重用,但这就是好处的程度。它本质上将 oo 模式简化为程序范式。您错过的最重要的事情是根据上下文在运行时更改您的实现。

单例只是稍微好一点。它使您能够使用成员变量(状态)正常编写逻辑,然后只需进行一些调整即可将其变成单例。假设您正在工厂中进行一些实例池,单例可能很适合那里。不过,您仍然会错过上下文。

最灵活的模式是使用依赖倒置,这意味着您的类依赖于工厂抽象并且不知道也不关心它是否是单例。这使您能够在提供要使用的具体工厂时考虑上下文。

于 2011-04-18T14:56:45.930 回答
3

我正要说我看不到使用这个工厂比通过new Product1()等实例化你的对象没有任何好处。

然而,这并不完全正确。当您使用这样的工厂时,您可以为基类选择一个实现,这可能是他们实现它的原因。例如,该createProduct1()方法可以实现为return new JumboProduct1();where JumboProduct1is derived from Product1,其余代码将与此类策略决策隔离。不是很灵活,但我想它会完成工作。

我会看这个问题的答案,看看这种设置是否还有其他用途,因为我目前想不出其他任何东西。

于 2011-04-18T14:56:27.837 回答
1

这里没有抽象工厂的好处。只有当该方法是Builder- 您才能将一些条件逻辑封装到createProductX()方法中。

于 2011-04-18T14:59:17.407 回答
1

taskinoor,出于几个原因,不建议在纯 OO 编程中使用静态方法。

  1. 您无法使用静态方法实现依赖注入。
  2. 编写单元测试用例非常困难,几乎不可能。就个人而言,当我开始编程时,我在使用静态方法实现 UT 时遇到了很多困难。

话虽如此,静态方法几乎没有什么好处如果您正在创建一个在运行时往往保持不变的库函数,那么静态方法是一个不错的选择。

请在此处查看抽象工厂的实现。我认为不需要使用“静态”方法来实现抽象工厂。 http://www.dofactory.com/Patterns/PatternAbstract.aspx#_self1

于 2011-04-18T15:02:08.923 回答
0

为简洁起见,如果要配置大量对象,则使用静态方法实例化对象是最干净的。例如,比较:

textObject = new TextUI("Code Example");
textObject.move(50, 80);
textObject.size(100, 200);

和:

textObject = TextUI.make("Code Example").move(50, 80).size(100, 200);

将三行合二为一使配置更简洁,并且行更便携——只需要更改一个变量名。使用正确的 IDE 时,您还可以从每个点的自动完成中受益,从而更容易编写新行和添加新属性。

于 2014-01-03T09:57:09.110 回答