【问题标题】:How to use a factory to create objects which use Strategy pattern?如何使用工厂创建使用策略模式的对象?
【发布时间】:2017-06-16 01:15:58
【问题描述】:

假设我们在网上商店有一个简单的支付功能。我们想用不同的交易处理器来管理不同的交易:

  • 交易可以是付款或退款。
  • 交易处理器可以是 Paypal 或 Payplug。

所以我们有以下类:

class PaymentTransaction implements Transaction {

}

class RefundTransaction implements Transaction {

}

class PaypalProcessor implements Processor {

}

class PayplugProcessor implements Processor {

}

正如this answer 中所建议的,我们可以使用以下使用策略 和多态性的类。

class PaymentProcessor {
     private Processor processor;
     private Transaction transaction;

     public PaymentProcessor(Processor processor, Transaction transaction) {
          this.processor = processor;
          this.transaction = transaction;
     }

     public void processPayment() {
         processor.process(transaction);
     }
}

我们假设要使用的处理器和事务是从数据库中给出的。我想知道如何创建 PaymentProcessor 对象。

似乎只有一个方法的抽象工厂类仍然是有效的抽象工厂模式。所以,在这种情况下,我想知道使用 Abstract Factory 是否相关。

  • 如果是,如何实现?
  • 如果不是,我们是否应该使用 Factory Method 模式和 PaymentProcessorFactory 类根据数据库中给出的详细信息创建具有他的两个属性的 PaymentProcessor

在这种情况下使用工厂的最佳做法是什么?

【问题讨论】:

    标签: oop design-patterns polymorphism factory


    【解决方案1】:

    我们假设要使用的处理器和事务是从数据库中给出的。我想知道如何创建 PaymentProcessor 对象。

    我会定义一个接口,我可以适应数据库结果或任何其他可以提供创建PaymentProcessor 所需数据的源。这对于单元测试也很有用。

    public interface PaymentProcessorFactoryArgs {
      String getProcessorType();
      String getTransactionType();
    }
    

    然后实现这样的工厂。

    public class PaymentProcessorFactory {
    
      private Map<String, Processor> processorMap = new HashMap<>();
      private Map<String, Transaction> transactionMap = new HashMap<>();
    
      public PaymentProcessorFactory() {
        processorMap.put("paypal", new PaypalProcessor());
        processorMap.put("payplug", new PayplugProcessor());
    
        transactionMap.put("refund", new RefundTransaction());
        transactionMap.put("payment", new PaymentTransaction());
      }
    
      public PaymentProcessor create(PaymentProcessorFactoryArgs factoryArgs) {
        String processorType = factoryArgs.getProcessorType();
        Processor processor = processorMap.get(processorType);
        if(processor == null){
          throw new IllegalArgumentException("Unknown processor type " + processorType);
        }
    
        String transactionType = factoryArgs.getTransactionType();
        Transaction transaction = transactionMap.get(transactionType);
        if(transaction == null){
          throw new IllegalArgumentException("Unknown transaction type " + processorType);
        }
    
        return new PaymentProcessor(processor, transaction);
      }
    }
    

    这只是一个简单的例子。如果能注册Processors和Transactions就更好了。例如

    public void register(String processorType, Processor processor){
       ...
    }
    public void register(String transactionType, Transaction transaction){
       ...
    }
    

    您可能还想使用另一个类型然后 String 作为键,也许是一个枚举。

    在此示例中,ProcessorTransaction 对象在每次创建 PaymentProcessor 时都会被重新使用。如果要为每个PaymentProcessor创建新对象,可以替换Maps类型

    private Map<String, Factory<Processor>> processorMap = new HashMap<>();
    private Map<String, Factory<Transaction>> transactionMap = new HashMap<>();
    

    带有花药工厂界面。例如

    public interface Factory<T> {
      public T newInstance();
    }
    

    【讨论】:

    • 如果我没记错的话,这是Factory Method模式的实现吧?
    【解决方案2】:

    也许您可以使用构建器模式。在builder模式中有一个类叫做director,它知道创建复杂对象的算法。为了创建组件,director 的复杂对象是使用构建器构建的。像这样,您可以更改特定组件来构建整个复杂对象。

    在您的情况下,PaymentProcessor(复杂对象)由 Payment 和 Processor 组成,因此算法是将它们注入 PaymentProcessor。建造者应该建造零件。要构建 paypal-refund 组合,您应该创建一个返回 PaypalProcessor 和 RefundTransaction 的构建器。当您要创建 payplug-payment 时,构建器应返回 PaymentTransaction 和 PayPlugProcessor。

    public interface PaymentProcessorBuilder {
        public Transaction buildTransaction();
        public Processor buildProcessor();
    }
    
    public class PaypalRefundProcessorBuilder implements PaymentProcessorBuilder {
        public Transaction buildTransaction {
            return new RefundTransaction();
        }
        public Processor buildProcessor {
            return new PayPalProcessor();
        }
    }
    
    public class PayPlugPaymentProcessorBuilder implements PaymentProcessorBuilder {
        public Transaction buildTransaction {
            return PaymentTransaction();
        }
        public Processor buildProcessor {
            return new PayPlugProcessor();
        }
    }
    

    现在 Director 可以使用构建器来构建 PaymentProcessor:

    publi PaymentProcessorDirector {
        public PaymentProcessor createPaymentProcessor(PaymentProcessorBuilder builder) {
            PaymentProcessor paymentProcessor = new PaymentProcessor();
    
            paymentProcessor.setTransaction(builder.buildTransaction());
            paymentProcessor.setProcessor(builder.buildProcessor());
    
            return paymentProcessor;
        }
    }
    

    创建的 PaymentProcessor 现在依赖于传递的 Builder:

    ...
    PaymentProcessorDirector director = new PaymentProcessorDirector();
    PaymentProcessorBuilder builder = new PaypalRefundProcessorBuilder();
    
    PaymentProcessor paymentProcessor = director.createPaymentProcessor(builder);
    ...
    

    您可以为每个组合创建一个构建器。如果您将正确的构建器传递给主管,您将获得所需的 PaymentProcessor。

    现在的问题是如何找到合适的构建器。因此,您可以使用工厂,它接受一些事件参数,然后决定必须制作哪个构建器。这个构建器你传入director,得到想要的PaymentProcessor。

    注意:这只是此问题的一种可能解决方案。每个解决方案都有优点和缺点。要找到正确的解决方案来平衡好与坏。

    PS:希望语法正确。我不是 java 开发者。

    编辑: 您可以将构建器模式的主管解释为 PaymentProcessorFactory,而构建器本身就是构建 PaymentProcessor 各部分的策略

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-14
      • 1970-01-01
      • 1970-01-01
      • 2022-12-07
      • 1970-01-01
      • 2013-04-30
      • 1970-01-01
      相关资源
      最近更新 更多