如何在OOP中设计嵌套多态?

时间:2017-01-25 18:48:27

标签: oop design-patterns polymorphism

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

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

所以我们有以下几个类:

class PaymentTransaction implements Transaction {

}

class RefundTransaction implements Transaction {

}

class PaypalProcessor implements Processor {

}

class PayplugProcessor implements Processor {

}

对OOP有什么好理解?

  1. Processor.process(transaction);
  2. Transaction.process(processor);
  3. 例如,如果我们采用示例1,如何避免以下switch语句?

    class PaypalProcessor {
    
        function process(Transaction transaction) {
            switch(transaction.getType()) {
                case payment:
                //..
                    break;
                case refund:
                //..
      }
    }
    

    在所有情况下,如何管理“嵌套”多态,策略或其他能够管理不同处理器的不同事务的东西?

    PS:如果标题不合适,请告诉我我会编辑它。

2 个答案:

答案 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);
     }
 }

然后,您可以ProcessorTransaction的适当实施注入<{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);
}