Çoğu zaman belirli bir işlev çağrısı için yanıt işleme bazı kod yazarken aşağıdaki kod yapısı olsun:
örnek: Bu, bir giriş sistemi için kimlik doğrulamasını yapacak bir işlevdir
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.
}
}
Sorun
- Gördüğünüz gibi
if/else
yeni bir başarısızlık durumu açık Kapalı Prensibi'ninelse if
ihlali olan bir ifade eklemem gerektiği anlamına gelir . - Bir işleyicide oturum açma denemeleri sayacını artırabildiğimden, ancak başka bir işte daha ciddi şeyler yapabileceğimden, işlevin farklı soyutlama katmanlarına sahip olduğunu hissediyorum.
- Örneğin bazı işlevler tekrarlanır
increase the login trials
.
Katları if/else
bir fabrika modeline dönüştürmeyi düşündüm , ancak sadece davranışları değiştirmeyen nesneleri oluşturmak için fabrikayı kullandım. Bunun için daha iyi bir çözümü olan var mı?
Not:
Bu sadece bir giriş sistemi kullanan bir örnektir. İyi yapılandırılmış bir OO deseni kullanarak bu davranışa genel bir çözüm istiyorum. Bu tür if/else
işleyiciler kodumda çok fazla yerde görünüyor ve ben sadece giriş sistemini açıklamak kolay bir örnek olarak kullandım. Benim gerçek kullanım durumları çok burada yayınlamak için karmaşıktır. : D
Lütfen yanıtınızı PHP koduyla sınırlamayın ve tercih ettiğiniz dili kullanmaktan çekinmeyin.
GÜNCELLEME
Sorumu açıklığa kavuşturmak için bir başka daha karmaşık kod örneği:
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();
}
}
fonksiyon amacı:
- Ebay'de oyun satıyorum.
- Bir müşteri siparişini iptal etmek istiyor ve parasını geri alırsa (yani geri ödeme) önce ebay'de bir "Anlaşmazlık" açmalıyım.
- Bir anlaşmazlık açıldığında, müşterinin geri ödemeyi kabul ettiğini onaylaması için beklemeliyim (aptallık bana geri ödemeyi söyleyen kişidir, ancak ebay'da bu şekilde çalışır).
- Bu işlevler benim açtığım tüm anlaşmazlıkları alır ve müşterinin anlaşmazlığa yanıt verip vermediğini görmek için durumlarını düzenli olarak kontrol eder.
- Müşteri kabul edebilir (sonra iade ederim) veya reddedebilir (sonra geri alırım) veya 7 gün boyunca yanıt vermeyebilir (anlaşmazlığı kendim kapatıp geri ödeme yaparım).
getOrderStrategy
birstrategy
nesneyi döndüren bir fabrika yöntemidir , ancakpreProcess()
vepreProcess()
işlevleri nelerdir . Neden Ayrıca geçtin$this
içinupdateOrderHistory($this)
?