Sebagian besar waktu ketika saya sedang menulis beberapa kode yang menangani respons untuk panggilan fungsi tertentu saya mendapatkan struktur kode berikut:
contoh: Ini adalah fungsi yang akan menangani otentikasi untuk sistem login
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.
}
}
Masalah
- Seperti yang Anda lihat, kode tersebut dibuat berdasarkan
if/else
struktur yang berarti status kegagalan baru akan berarti bahwa saya perlu menambahkanelse if
pernyataan yang merupakan pelanggaran terhadap Prinsip Terbuka Terbuka . - Saya merasa bahwa fungsi ini memiliki lapisan abstraksi yang berbeda karena saya hanya dapat meningkatkan penghitung percobaan masuk di satu handler, tetapi melakukan hal-hal yang lebih serius di yang lain.
- Beberapa fungsi diulang
increase the login trials
misalnya.
Saya berpikir untuk mengubah banyak if/else
ke pola pabrik, tapi saya hanya menggunakan pabrik untuk membuat objek tidak mengubah perilaku. Adakah yang punya solusi yang lebih baik untuk ini?
catatan:
Ini hanya contoh menggunakan sistem login. Saya meminta solusi umum untuk perilaku ini menggunakan pola OO yang dibangun dengan baik. Semacam ini if/else
penangan muncul di terlalu banyak tempat di kode saya dan saya hanya menggunakan sistem login sebagai sederhana mudah untuk menjelaskan contoh. Kasing asli saya sangat rumit untuk dikirim di sini. : D
Tolong jangan membatasi jawaban Anda ke kode PHP dan jangan ragu untuk menggunakan bahasa yang Anda inginkan.
MEMPERBARUI
Contoh kode lain yang lebih rumit hanya untuk memperjelas pertanyaan saya:
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();
}
}
tujuan fungsi:
- Saya menjual game di ebay.
- Jika seorang pelanggan ingin membatalkan pesanannya dan mendapatkan kembali uangnya (yaitu Pengembalian Uang), saya harus membuka "Perselisihan" di ebay terlebih dahulu.
- Setelah perselisihan dibuka, saya harus menunggu pelanggan untuk mengkonfirmasi bahwa dia setuju untuk pengembalian dana (konyol karena dia orang yang mengatakan kepada saya untuk mengembalikan uang, tetapi begitulah cara kerjanya di ebay).
- Fungsi ini membuat semua sengketa dibuka oleh saya dan memeriksa status mereka secara berkala untuk melihat apakah pelanggan telah menjawab perselisihan atau tidak.
- Pelanggan dapat menyetujui (lalu saya mengembalikan) atau menolak (kemudian saya kembalikan) atau mungkin tidak menanggapi selama 7 hari (saya menutup sendiri perselisihan lalu mengembalikan uang).
getOrderStrategy
adalah metode pabrik yang mengembalikanstrategy
objek tergantung pada status pesanan, tetapi apa sajapreProcess()
danpreProcess()
fungsinya. Juga mengapa Anda lulus$this
keupdateOrderHistory($this)
?