Beberapa minggu yang lalu, saya mengusahakan penyelesaian untuk Globo Player, di mana ia perlu untuk mengaktifkan dan menyahaktifkan gelagat tertentu dalam perisian semasa pelaksanaan. Keperluan jenis ini biasanya diselesaikan dengan syarat berantai, seperti if-else dan suis, tetapi pendekatan ini tidak selalunya ideal.
Dalam artikel ini, saya membentangkan penyelesaian yang memenuhi cabaran ini dengan sempurna dan boleh digunakan pada senario pengaturcaraan yang berbeza.
Bayangkan anda baru tiba di destinasi yang tidak diketahui. Apabila meninggalkan lapangan terbang, anda mempunyai beberapa pilihan untuk pergi ke hotel anda. Alternatif termurah ialah menyewa basikal, tetapi ini akan mengambil lebih banyak masa. Menaiki bas akan menjadi lebih mahal sedikit, tetapi ia akan membawa anda ke sana dengan lebih cepat dan selamat. Akhirnya, menyewa kereta akan menjadi pilihan terpantas, tetapi juga paling mahal.
Perkara yang paling penting dalam situasi ini ialah memahami bahawa, tanpa mengira strategi yang dipilih, objektif akhir adalah sama: sampai ke hotel.
Analogi ini boleh digunakan untuk pembangunan perisian. Apabila kita berurusan dengan senario di mana proses berbeza berusaha untuk mencapai objektif yang sama, kita boleh menggunakan corak reka bentuk Strategi untuk membantu kita.
Bayangkan bahawa kita perlu membangunkan sistem perbankan yang mampu mengira yuran berdasarkan jenis akaun pelanggan, seperti semasa, simpanan atau premium. Pengiraan ini perlu dilakukan pada masa jalan, yang memerlukan pelaksanaan yang betul mengarahkan aliran kod ke pengiraan yang sesuai.
Pada prinsipnya, pendekatan biasa adalah menggunakan struktur ringkas syarat berantai untuk menyelesaikan masalah dengan cepat dan berfungsi:
class Banco { calcularTaxa(tipoConta, valor) { if (tipoConta === "corrente") { return valor * 0.02; // 2% de taxa } else if (tipoConta === "poupanca") { return valor * 0.01; // 1% de taxa } else if (tipoConta === "premium") { return valor * 0.005; // 0,5% de taxa } else { throw new Error("Tipo de conta não suportado."); } } } const banco = new Banco(); const taxa = banco.calcularTaxa("corrente", 1000); // Exemplo: R00 console.log(`A taxa para sua conta é: R$${taxa}`);
Walaupun penyelesaian ini berfungsi dengan baik untuk senario mudah, apakah yang berlaku jika bank perlu menambah lima lagi jenis akaun pada masa hadapan?
calcularTaxa(tipoConta, valor) { if (tipoConta === "corrente") { return valor * 0.02; // 2% de taxa } else if (tipoConta === "poupanca") { return valor * 0.01; // 1% de taxa } else if (tipoConta === "premium") { return valor * 0.005; // 0,5% de taxa } else if (tipoConta === "estudante") { return valor * 0.001; // 0,1% de taxa } else if (tipoConta === "empresarial") { return valor * 0.03; // 3% de taxa } else if (tipoConta === "internacional") { return valor * 0.04 + 10; // 4% + taxa fixa de R } else if (tipoConta === "digital") { return valor * 0.008; // 0,8% de taxa } else if (tipoConta === "exclusiva") { return valor * 0.002; // 0,2% de taxa } else { throw new Error("Tipo de conta inválido!"); } }
Kini, kod mula menunjukkan had yang serius. Mari kita terokai masalah dengan pendekatan ini:
1. Kebolehskalaan rendah
Setiap kali jenis akaun baharu perlu ditambah, kaedah calculateRate perlu diubah suai. Ini terus meningkatkan bilangan bersyarat, menjadikan kod lebih kompleks dan sukar untuk diurus.
2. Kebergantungan yang tinggi
Logik pengiraan kadar digabungkan sepenuhnya dengan kaedah calculateRate. Perubahan pada satu jenis akaun boleh memberi kesan kepada orang lain secara tidak sengaja, meningkatkan risiko memperkenalkan pepijat.
3. Pengulangan kod
Coretan yang serupa, seperti amaun * yuran, diduplikasi untuk setiap jenis akaun. Ini mengurangkan penggunaan semula kod dan melanggar prinsip KERING (Jangan Ulang Sendiri).
Dalam langkah seterusnya, kita akan melihat bagaimana Corak Strategi boleh menyelesaikan masalah ini, mempromosikan kod yang lebih bersih, berskala dan modular.
Untuk mengelakkan masalah yang dinyatakan di atas, kami akan menganggap setiap jenis akaun sebagai entiti terpencil dalam perisian. Ini kerana setiap jenis akaun mempunyai pengiraan yuran tertentu dan mungkin mempunyai gelagat masa hadapan yang berkaitan.
Daripada membuat kelas Bank dengan kaedah calculateRate yang menyelesaikan semua operasi, mari buat kelas untuk setiap jenis akaun:
class Banco { calcularTaxa(tipoConta, valor) { if (tipoConta === "corrente") { return valor * 0.02; // 2% de taxa } else if (tipoConta === "poupanca") { return valor * 0.01; // 1% de taxa } else if (tipoConta === "premium") { return valor * 0.005; // 0,5% de taxa } else { throw new Error("Tipo de conta não suportado."); } } } const banco = new Banco(); const taxa = banco.calcularTaxa("corrente", 1000); // Exemplo: R00 console.log(`A taxa para sua conta é: R$${taxa}`);
Ini memastikan setiap operasi pengiraan disimpan dalam skop khusus untuk jenis akaun anda. Kini, kami mempunyai gelagat terpencil yang memfokuskan pada setiap jenis akaun:
Tetapi, di manakah pilihan akaun yang diingini akan ditempatkan?
calcularTaxa(tipoConta, valor) { if (tipoConta === "corrente") { return valor * 0.02; // 2% de taxa } else if (tipoConta === "poupanca") { return valor * 0.01; // 1% de taxa } else if (tipoConta === "premium") { return valor * 0.005; // 0,5% de taxa } else if (tipoConta === "estudante") { return valor * 0.001; // 0,1% de taxa } else if (tipoConta === "empresarial") { return valor * 0.03; // 3% de taxa } else if (tipoConta === "internacional") { return valor * 0.04 + 10; // 4% + taxa fixa de R } else if (tipoConta === "digital") { return valor * 0.008; // 0,8% de taxa } else if (tipoConta === "exclusiva") { return valor * 0.002; // 0,2% de taxa } else { throw new Error("Tipo de conta inválido!"); } }
Perhatikan bahawa, daripada membuat struktur keputusan berantai (jika lain), kami memilih untuk meluluskan akaun, strategi dalam pembina kelas Bank kami. Ini membenarkan kaedah setConta untuk memilih jenis akaun yang diingini pada masa jalankan apabila membuat instantiate bank. Pengiraan kadar akan dilakukan melalui ini.conta.calcularTaxa(valor).
class ContaCorrente { calcularTaxa(valor) { return valor * 0.02; // 2% de taxa } } class ContaPoupanca { calcularTaxa(valor) { return valor * 0.01; // 1% de taxa } } class ContaPremium { calcularTaxa(valor) { return valor * 0.005; // 0,5% de taxa } }
Dengan model ini, kami dapat menggunakan Corak Strategi dengan cara yang mudah, memastikan pelaksanaan yang lebih fleksibel, berskala dan gandingan rendah.
Corak Strategi ialah penyelesaian yang berkuasa apabila anda perlu mengubah gelagat operasi semasa masa jalan, tanpa menggandingkan kod pelaksanaan secara langsung kepada keadaan atau jenis yang berbeza. Corak ini sesuai untuk senario di mana gelagat operasi mungkin berbeza-beza bergantung pada konteks dan tempat alternatif adalah bebas antara satu sama lain.
Dengan menggunakan Strategi, kami menjamin bahawa kod menjadi lebih bersih, modular dan fleksibel, selain menggalakkan penyelenggaraan dan pengembangan sistem yang lebih baik.
Atas ialah kandungan terperinci Menggunakan Corak Strategi untuk Mengelak Penyaman Terlalu Banyak. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!