大多数时候,当我编写一些代码来处理某个函数调用的响应时,我会得到以下代码结构:
示例:此功能将处理登录系统的身份验证
class Authentication{
function login(){ //This function is called from my Controller
$result=$this->authenticate($username,$password);
if($result=='wrong password'){
//increase the login trials counter
//send mail to admin
//store visitor ip
}else if($result=='wrong username'){
//increase the login trials counter
//do other stuff
}else if($result=='login trials exceeded')
//do some stuff
}else if($result=='banned ip'){
//do some stuff
}else if...
function authenticate($username,$password){
//authenticate the user locally or remotely and return an error code in case a login in fails.
}
}
问题
- 如您所见,代码建立在一个
if/else
结构上,这意味着新的故障状态将意味着我需要添加else if
一条违反开放式封闭原则的声明。 - 我感觉到该函数具有不同的抽象层,因为我可能只是在一个处理程序中增加了登录试验计数器,而在另一个处理程序中做了更严肃的事情。
- 例如,某些功能被重复
increase the login trials
。
我曾考虑过将倍数if/else
转换为工厂模式,但我仅使用工厂来创建对象,而不能改变行为。有谁对此有更好的解决方案?
注意:
这只是使用登录系统的示例。我要求使用构建良好的OO模式对此行为的一般解决方案。这种if/else
处理程序出现在我的代码中的太多地方,我只是使用登录系统作为一个简单易懂的示例。我的实际用例在这里发布要复杂得多。:D
请不要将答案限于PHP代码,并随时使用您喜欢的语言。
更新
另一个更复杂的代码示例只是为了澄清我的问题:
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)) { //returns true if dispute was accepted
$order->setStatus('accepted');
$order->refund(); //refunds the order on ebay and internally in my system
$this->insertRecordInOrderHistoryTable($order,'refunded');
} else if ($this->isDisputeCancelled($order)) { //returns true if dispute was cancelled
$order->setStatus('cancelled');
$this->insertRecordInOrderHistory($order,'cancelled');
$order->rollBackRefund(); //cancels the refund on ebay and internally in my system
} else if ($this->isDisputeOlderThan7Days($order)) { //returns true if 7 days elapsed since the dispute was opened
$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天内没有响应(我自己关闭争议然后退款)。
getOrderStrategy
是一种工厂方法,该方法strategy
根据订单状态返回对象,但preProcess()
andpreProcess()
函数是什么。你为什么还要$this
去updateOrderHistory($this)
?