假设我们在网上商店有一个简单的付款功能。我们希望使用不同的交易处理器管理不同的交易:
所以我们有以下几个类:
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
对象。
似乎只有一个方法的抽象工厂类仍然是有效的抽象工厂模式。所以,在这种情况下,我想知道使用抽象工厂是否相关。
PaymentProcessorFactory
类的 Factory Method 模式根据数据库中提供的详细信息创建具有两个属性的PaymentProcessor
?在这种情况下,使用工厂的最佳做法是什么?
答案 0 :(得分:2)
也许您可以使用构建器模式。在构建器模式中,有一个名为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。
现在问题是如何获得正确的构建器。因此,您可以使用工厂,它接受一些事件参数并决定必须制作哪个构建器。您在导演中传递的此构建器将获得所需的PaymentProcessor。
注意:这只是此问题的一种可能解决方案。每种解决方案都有优点和缺点。找到正确的解决方案,你可以平衡好事和坏事。
PS:希望语法正确。我不是一个java开发人员。
编辑: 您可以将构建器模式的director解释为PaymentProcessorFactory,其中构建器本身作为构建PaymentProcessor部分的策略
答案 1 :(得分:2)
我们假设处理器和要使用的事务是从数据库中提供的。我想知道如何创建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);
}
}
这只是一个简单的例子。如果您可以注册Processor
和Transaction
,那会更好。 E.g。
public void register(String processorType, Processor processor){
...
}
public void register(String transactionType, Transaction transaction){
...
}
你也可能想要使用花药类型然后String
作为键,也许是枚举。
在此示例中,每次创建Processor
时都会重复使用Transaction
和PaymentProcessor
个对象。如果要为每个PaymentProcessor
创建新对象,可以替换Map
类型
private Map<String, Factory<Processor>> processorMap = new HashMap<>();
private Map<String, Factory<Transaction>> transactionMap = new HashMap<>();
使用花药工厂界面。 E.g。
public interface Factory<T> {
public T newInstance();
}