假设我们在网上商店有一个简单的付款功能。我们希望使用不同的交易处理器管理不同的交易:
所以我们有以下几个类:
class PaymentTransaction implements Transaction {
}
class RefundTransaction implements Transaction {
}
class PaypalProcessor implements Processor {
}
class PayplugProcessor implements Processor {
}
对OOP有什么好理解?
Processor.process(transaction);
或Transaction.process(processor);
例如,如果我们采用示例1,如何避免以下switch
语句?
class PaypalProcessor {
function process(Transaction transaction) {
switch(transaction.getType()) {
case payment:
//..
break;
case refund:
//..
}
}
在所有情况下,如何管理“嵌套”多态,策略或其他能够管理不同处理器的不同事务的东西?
PS:如果标题不合适,请告诉我我会编辑它。
答案 0 :(得分:3)
你似乎走在了正确的轨道上。您需要的是用于执行操作的第三类(为了讨论而在Java中使用示例代码):
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);
}
}
然后,您可以将Processor
和Transaction
的适当实施注入<{1}}:
PaymentProcessor
注意如何PaymentProcessor paymentProcessor = new PaymentProcessor(new PayPalDepositProcess(),new PaypalDepositTransaction());
PaymentProcessor refundProcessor = new PaymentProcessor(new PayPalRefundProcess(),new PayPalRefundTransaction());
可以传递 Processor 和 Transaction 的不同组合,而无需使用开关声明。
请注意,PaymentProcessor
听起来比processor.process(transaction);
更直观。另请注意,您可以考虑使用抽象工厂模式,因为您似乎正在创建一系列相关对象(处理不同类型事务的不同类型的处理器)
答案 1 :(得分:1)
我会让交易对象负责处理付款和退款。
interface Transaction
{
public function pay();
public function refund();
}
然后你会有这样的具体内容:
class PaypalTransaction implements Transaction
{
public function pay()
{
//process payment in a paypale way
}
public function refund()
{
//process refund in a paypale way
}
}
class PayplugTransaction implements Transaction
{
public function pay()
{
//process payment the way Payplug do
}
public function refund()
{
//process refund the way Payplug do
}
}
处理交易付款的客户端代码可能如下所示:
$customer = new Customer();
//concrete factory producing an abstract product (transaction)
$transaction = $customer->prepareTransaction('100 USD');
//process payment
$transaction->pay();
//in a similar fashion you would go about processing a refund
$transaction->refund();
请注意客户端代码是如何处理货币转移的具体方式(实施细节,paypal或payplug)。换句话说,客户端正在多态地处理事务,因为它被编码为抽象而不是具体对象。
此示例中的客户是客户端代码的具体工厂:
class Customer implements Shopper
{
/**
* @param string $amount
* @return Transaction
*/
public function prepareTransaction($amount)
{
//use either paypal or payplug depending on the customer's preference
}
}
如果客户端以预期使用抽象对象(例如“Shopper”)的方式编码,那么我们就会看到抽象工厂模式。
interface Shopper
{
/**
* @param string $amount
* @return Transaction
*/
public function prepareTransaction($amount);
}