为特定行为应用设计模式

时间:2012-04-23 08:58:01

标签: php design-patterns refactoring

我想知道是否有人可以为此功能提供设计模式或更好的实施解决方案:

  public function refundAcceptedDisputes() {            
        $this->getRequestedEbayOrdersFromDB(); //get all disputes requested on ebay
        foreach ($this->orders as $order) { /* $order is a Doctrine Entity */
            try {
                if ($this->isDisputeAccepted($order)) {
                    $order->setStatus('accepted');
                    $order->refund(); //refunds the order on ebay and internally in my system
                    $this->insertRecordInOrderHistoryTable($order,'refunded');                        
                } else if ($this->isDisputeCancelled($order)) {
                    $order->setStatus('cancelled');
                    $this->insertRecordInOrderHistory($order,'cancelled');
                    $order->rollBackRefund(); //cancels the refund on ebay and internally in my system
                } else if ($this->isDisputeOlderThan7Days($order)) {
                    $order->closeDispute(); //closes the dispute on ebay
                    $this->insertRecordInOrderHistoryTable($order,'refunded');
                    $order->refund(); //refunds the order on ebay and internally in my system
                }
            } catch (Exception $e) {
                $order->setStatus('failed');
                $order->setErrorMessage($e->getMessage());
                $this->addLog();//log error
            }
            $order->setUpdatedAt(time());
            $order->save();
        }
    }

功能目的:

  • 我在ebay上卖游戏。
  • 如果客户希望取消订单并获得退款 (即退款)我必须先在ebay上开一个“争议”。
  • 一旦发生争议,我必须等待客户确认 他同意退款(愚蠢,因为他是那个告诉我退款的人, 但这就是它在ebay上的运作方式。)
  • 此功能可以解决我打开的所有争议,并定期检查其状态,以确定客户是否已回复争议。
  • 客户可能同意(然后我退款)或拒绝(然后我回滚)或者可能不会回复7天(我自己关闭争议然后退款)。

问题

  1. 正如您所看到的,代码构建在if/else结构上,这意味着新状态(例如客户关闭其帐户)将意味着我需要添加else if语句,这是一个违反开放封闭原则
  2. 我感觉这个函数有不同的抽象层。 getRequestedEbayOrdersFromDB()非常抽象,而其余代码有很多细节。
  3. 有些功能会重复insertRecordInOrderHistoryTable(),只会在历史实体表中添加新记录。
  4. 解决方案

    我考虑过将多个if/else转换为工厂模式,但我只使用工厂来创建不改变行为的对象。

    接下来我考虑使用策略模式,但未能建立一个好的解决方案。

    感谢任何帮助。 感谢。

1 个答案:

答案 0 :(得分:3)

如何创建退款订单处理程序工厂?

我提供的代码中没有足够的信息,但我假设order中有一些内容可用作处理程序类型的键,因此您可以在refundAcceptedDisputes中执行以下操作: (我是一个C ++人,很抱歉伪代码)

refundOrderHandler = RefundOrderHandlerFactory.getHandler(order);
refundOrderHandler.doRefund(); // Name this method accordingly

然后你的工厂会有一个简单的if / else来获取处理程序的类型,如下所示:

RefundOrderHandlerFacotry::getHandler(order)) {
  if(isDisputAccepted(order) {
    return handlerA(order);
  }
  else if(isDisputCancelled(order)) {
    return handlerB(order);
  }
  else if(isDisputOlderThan7Days(order)) {
    return handlerC(order);
  }
  // Add new handlers here
}

确定处理程序类型的逻辑必须放在Factory中,或者可以访问它。

然后,您必须为RefundHandler的每个类型创建一个类RefundHandlerBase作为基类,它将具有抽象方法doRefund() 请注意,与退款相关的所有逻辑都包含在相应的类中。要添加更多退款处理程序,您必须创建一个类来处理它,向工厂添加else if,并使用适当的逻辑来确定RefundHandler的类型。