대부분의 경우 특정 함수 호출에 대한 응답을 처리하는 코드를 작성할 때 다음 코드 구조를 얻습니다.
예 : 로그인 시스템의 인증을 처리하는 기능입니다
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
구조를 기반으로 빌드 됨을 의미합니다. 즉, 새로운 실패 상태는 Open Closed Principle에else if
위반 되는 문장 을 추가해야 함을 의미합니다 . - 한 처리기에서 로그인 시도 카운터를 증가시킬 수 있지만 다른 처리기에서 더 심각한 작업을 수행 할 수 있으므로 함수에 다른 추상화 계층이 있다는 느낌이 들었습니다.
- 일부 기능은
increase the login trials
예를 들어 반복 됩니다.
다중 if/else
을 팩토리 패턴으로 변환하는 것에 대해 생각 했지만 동작을 변경하지 않는 객체를 만들기 위해 팩토리 만 사용했습니다. 누구든지 이것에 대한 더 나은 해결책이 있습니까?
노트 :
이것은 로그인 시스템을 사용하는 예일뿐입니다. 잘 구축 된 OO 패턴을 사용 하여이 동작에 대한 일반적인 솔루션을 요청하고 있습니다. 이런 종류의 if/else
핸들러는 내 코드의 너무 많은 곳에 나타나며 로그인 시스템을 간단한 설명하기 쉬운 예제로 사용했습니다. 내 실제 사용 사례는 여기에 게시하기가 너무 복잡합니다. :디
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에서 "분쟁"을 열어야합니다.
- 분쟁이 시작되면 고객이 환불에 동의한다는 것을 확인할 때까지 기다려야합니다 (환불하라고 말한 사람이 아니라 이베이에서 작동하는 방식 임).
- 이 기능은 본인이 공개 한 모든 분쟁을 가져오고 고객이 분쟁에 응답했는지 여부를 정기적으로 확인합니다.
- 고객이 동의 (환불)하거나 거부 (환불)하거나 7 일 동안 응답하지 않을 수 있습니다 (분쟁을 직접 종료 한 다음 환불).
getOrderStrategy
반환하는 팩토리 메소드입니다strategy
주문 상태에 따라 개체를하지만, 무엇preProcess()
과preProcess()
기능을. 왜도를 통과 않았다$this
하려면updateOrderHistory($this)
?