Hầu hết khi tôi viết một số mã xử lý phản hồi cho một lệnh gọi hàm nhất định, tôi nhận được cấu trúc mã sau:
Ví dụ: Đây là chức năng sẽ xử lý xác thực cho hệ thống đăng nhập
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.
}
}
Vấn đề
- Như bạn có thể thấy mã được xây dựng trên một
if/else
cấu trúc, điều đó có nghĩa là trạng thái lỗi mới sẽ có nghĩa là tôi cần thêm mộtelse if
câu lệnh vi phạm Nguyên tắc Đóng mở . - Tôi có cảm giác rằng hàm này có các lớp trừu tượng khác nhau vì tôi có thể chỉ cần tăng bộ đếm thử nghiệm đăng nhập trong một trình xử lý, nhưng làm những thứ nghiêm trọng hơn trong một lớp khác.
- Một số chức năng được lặp lại
increase the login trials
chẳng hạn.
Tôi đã nghĩ về việc chuyển đổi nhiều if/else
thành một mô hình nhà máy, nhưng tôi chỉ sử dụng nhà máy để tạo ra các đối tượng không thay đổi hành vi. Có ai có một giải pháp tốt hơn cho điều này?
Ghi chú:
Đây chỉ là một ví dụ sử dụng một hệ thống đăng nhập. Tôi đang yêu cầu một giải pháp chung cho hành vi này bằng cách sử dụng mẫu OO được xây dựng tốt. Kiểu if/else
xử lý này xuất hiện ở quá nhiều vị trí trong mã của tôi và tôi chỉ sử dụng hệ thống đăng nhập như một ví dụ đơn giản dễ giải thích. Trường hợp sử dụng thực tế của tôi là rất nhiều phức tạp để gửi ở đây. : D
Vui lòng không giới hạn câu trả lời của bạn cho mã PHP và thoải mái sử dụng ngôn ngữ bạn thích.
CẬP NHẬT
Một ví dụ mã phức tạp hơn chỉ để làm rõ câu hỏi của tô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();
}
}
mục đích chức năng:
- Tôi đang bán trò chơi trên ebay.
- Nếu khách hàng muốn hủy đơn đặt hàng của mình và lấy lại tiền của mình (ví dụ: Hoàn tiền), trước tiên tôi phải mở "Tranh chấp" trên ebay.
- Khi tranh chấp được mở, tôi phải đợi khách hàng xác nhận rằng anh ta đồng ý hoàn tiền (ngớ ngẩn vì anh ta là người bảo tôi hoàn lại tiền, nhưng đó là cách nó hoạt động trên ebay).
- Chức năng này nhận được tất cả các tranh chấp do tôi mở và kiểm tra trạng thái của họ theo định kỳ để xem khách hàng có trả lời tranh chấp hay không.
- Khách hàng có thể đồng ý (sau đó tôi hoàn lại tiền) hoặc từ chối (sau đó tôi quay lại) hoặc có thể không trả lời trong 7 ngày (tôi tự đóng tranh chấp sau đó hoàn lại tiền).
getOrderStrategy
một phương thức xuất xưởng trả về mộtstrategy
đối tượng tùy thuộc vào trạng thái đơn hàng, nhưng chức năngpreProcess()
vàpreProcess()
chức năng là gì . Cũng tại sao bạn vượt qua$this
đểupdateOrderHistory($this)
?