这个设计模式是什么?

3

我阅读了工厂方法抽象工厂的维基百科文章,但以下代码似乎不适合任何地方。有人能解释一下以下模式是什么或者它是否是反模式吗?

interace PaymentGateway{
  void makePayment();
}

class PaypalPaymentGateway implements PaymentGateway
{
  public void makePayment()
  {
    //some implementation
  }
}


class AuthorizeNetPaymentGateway implements PaymentGateway
{
  public void makePayment()
  {
    //some implementation
  }
}

class PaymentGatewayFactory{
  PaymentGateway createPaymentGateway(int gatewayId)
  {
    if(gatewayId == 1)
      return PaypalPaymentGateway();
    else if(gatewayId == 2)
      return AuthorizeNetPaymentGateway();
  }
}

假设用户在HTML页面上使用单选按钮选择付款方式,gatewayId是从单选按钮值中派生的。
我看到过这样的代码,认为它是抽象工厂模式,但在阅读维基百科文章后,我开始怀疑。

是的,它是一种策略模式。 - Oliver Watkins
@Juvanis 这不是策略模式,策略模式可以通过向其方法传递参数来改变实例的行为,从而使您有可能随时更改其行为。 - Mifmif
3个回答

2
该网关类实现了策略模式,其中选择被委托给我所谓的参数化工厂。
如果您想将其简化为GOF模式之一,我会说它更像是一个生成器模式,缩写成一个简短的调用而不是设置策略并在之后调用build()。
如果您想扩展到Fowler模式,可以将其与注册表进行比较。

1
这不是工厂模式、抽象工厂模式或生成器模式。它们都有特定的意图,而且没有一个与代码匹配。
但是正如一些人提出的那样,接口PaymentGateway和具体类实现了策略模式。策略模式的意图完全匹配:“定义一系列算法,将每个算法封装起来,并使它们可以互换。策略模式使得算法可独立于使用它的客户端而变化。”
策略模式不一定需要具有即时行为更改。这取决于客户端代码(使用策略模式抽象的代码)。
PaymentGatewayFacotry不符合任何GoF模式。它不符合工厂模式、抽象工厂模式或生成器模式的意图。正如Lorenzo所建议的,也许你可以将其称为参数化工厂或参数化选择器。虽然它是一个编码糟糕的类。它违反了开-闭原则。

我不明白为什么PaymentGatewayFactory的代码写得很糟糕。你能解释一下吗? - Can't Tell
因为如果您向系统添加另一个PaymentGateway,您需要修改现有的PaymentGatewayFactory代码。这永无止境,对吧?然而,如果您对这种麻烦感到满意,那么您可以停止设计工作。如果您希望解决这个问题,您将考虑修改PaymentGatewayFactory。您想使用只能制造两种对象类型的工厂吗?还是您想要一种可以制造许多特定类型(PaymentGateway)对象类型的工厂? - user2920760
谢谢您的解释。您认为如何使该类符合开闭原则?为了工厂在不预先知道类型的情况下实例化PaymentGateways,我认为它必须获取其他对象来为其构建PaymentGateways。而那个其他对象将是一个接口/抽象类型? - Can't Tell

1
在Craig Larman的书"应用UML和模式"(第26.4节)中,他将其称为“简单工厂”或“具体工厂”,并表示这不是GoF模式,但非常普遍。 "Head First设计模式"也花费了一些篇幅介绍了这个模式:
简单工厂模式并不是一个设计模式,更像是一种编程习惯。但它被广泛使用,因此我们将其列为Head First Pattern的荣誉提名。有些开发人员会将这种习惯误认为是“工厂模式”,所以下次当你和另一个开发人员之间出现尴尬的沉默时,你就有了一个不错的话题来打破僵局。
[编辑]我喜欢这篇博客文章,它解释了简单工厂、工厂方法和抽象工厂之间的区别。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接