ส่วนใหญ่เวลาที่ฉันเขียนโค้ดบางอย่างที่จัดการการตอบสนองสำหรับการเรียกใช้ฟังก์ชันบางฉันได้รับโครงสร้างรหัสต่อไปนี้:
ตัวอย่าง: นี่คือฟังก์ชันที่จะจัดการการรับรองความถูกต้องสำหรับระบบเข้าสู่ระบบ
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 และอย่าลังเลที่จะใช้ภาษาที่คุณต้องการ
UPDATE
อีกตัวอย่างรหัสที่ซับซ้อนมากขึ้นเพียงเพื่อชี้แจงคำถามของฉัน:
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)
?