Mengapa bermanfaat untuk menggunakan pola strategi jika Anda bisa menulis kode Anda dalam kasus if / then?
Sebagai contoh: Saya memiliki kelas Wajib Pajak, dan salah satu metode menghitung pajak menggunakan algoritma yang berbeda. Jadi mengapa tidak dapat memiliki jika / kemudian case dan mencari tahu algoritma apa yang digunakan dalam metode itu, daripada menggunakan pola strategi? Juga, mengapa Anda tidak bisa menerapkan metode terpisah untuk setiap algoritma di kelas Wajib Pajak?
Juga, apa artinya bagi algoritma untuk berubah saat runtime?
Jawaban:
Untuk satu hal, gumpalan besar
if/else
balok tidak mudah diuji . Setiap "cabang" baru menambahkan jalur eksekusi lain dan dengan demikian meningkatkan kompleksitas siklomatik . Jika Anda ingin menguji kode Anda secara menyeluruh, Anda harus mencakup semua jalur eksekusi, dan setiap kondisi akan mengharuskan Anda untuk menulis setidaknya satu tes lagi (dengan asumsi Anda menulis tes kecil, fokus). Di sisi lain, kelas yang menerapkan strategi biasanya mengekspos hanya 1 metode publik, yang mudah untuk diuji.Jadi, dengan bersarang
if/else
Anda akan berakhir dengan banyak tes untuk satu bagian dari kode Anda, sementara dengan Strategi Anda akan memiliki beberapa tes untuk masing-masing dari beberapa strategi sederhana. Dengan yang terakhir, mudah untuk memiliki cakupan yang lebih baik, karena lebih sulit untuk kehilangan jalur eksekusi.Adapun ekstensibilitas , bayangkan Anda sedang menulis kerangka kerja, di mana pengguna seharusnya bisa menyuntikkan perilaku mereka sendiri. Misalnya, Anda ingin membuat semacam kerangka perhitungan pajak, dan ingin mendukung sistem pajak di berbagai negara. Alih-alih menerapkan semuanya, Anda hanya ingin memberikan kesempatan kepada pengguna kerangka untuk memberikan implementasi tentang cara menghitung beberapa pajak tertentu.
Inilah pola strateginya:
TaxCalculation
, dan kerangka kerja Anda menerima contoh jenis ini untuk menghitung pajakAnda tidak dapat melakukan hal yang sama dengan
if/else
, karena itu akan membutuhkan perubahan kode kerangka kerja, dalam hal ini tidak akan menjadi kerangka kerja lagi. Karena kerangka kerja sering didistribusikan dalam bentuk yang dikompilasi, ini mungkin satu-satunya pilihan.Namun, bahkan jika Anda hanya menulis beberapa kode biasa, Strategi bermanfaat karena membuat maksud Anda lebih jelas. Ia mengatakan "logika ini pluggable dan bersyarat", yaitu ada beberapa implementasi yang dapat bervariasi tergantung pada tindakan pengguna, konfigurasi, atau bahkan platform.
Menggunakan pola Strategi dapat meningkatkan keterbacaan karena, sementara kelas yang mengimplementasikan beberapa strategi tertentu biasanya harus memiliki nama deskriptif, misalnya
USAIncomeTaxCalculator
,if/else
blok "tanpa nama", dalam kasus terbaik hanya berkomentar, dan komentar dapat berbohong. Juga, dari selera pribadi saya, hanya memiliki lebih dari 3if/else
blok berturut-turut tidak dapat dibaca, dan menjadi sangat buruk dengan blok bersarang.Prinsip Terbuka / Tertutup juga sangat relevan, karena, seperti yang saya jelaskan dalam contoh di atas, Strategi memungkinkan Anda untuk memperluas logika di beberapa bagian kode Anda ("terbuka untuk ekstensi") tanpa menulis ulang bagian-bagian itu ("ditutup untuk modifikasi" ).
sumber
if/else
blok juga menurunkan keterbacaan kode. Adapun pola strategi, prinsip Terbuka / Tertutup layak disebut IMO.if
yang Anda miliki, semakin banyak jalur yang mungkin ada melalui kode Anda, semakin banyak tes yang harus Anda tulis dan lebih banyak cara agar metode itu gagal. Jika saya dapat mengutip almarhum Yogi Berra: "Jika Anda datang ke persimpangan jalan, ambillah." Ini berlaku cemerlang untuk pengujian unit. Selain itu, banyakif
pernyataan berarti Anda cenderung mengulangi logika untuk kondisi tersebut, semakin meningkatkan beban pengujian Anda dan meningkatkan risiko bug muncul.if/else
blok untuk memanggil mereka (atau di dalamnya, untuk menentukan apakah harus melakukan sesuatu atau tidak), jadi itu tidak banyak membantu, kecuali mungkin kode yang lebih mudah dibaca. Dan juga tidak ada ekstensibilitas bagi pengguna kerangka kerja hipotetis Anda saat itu.Terkadang Anda hanya perlu menggunakan if / then. Ini adalah kode sederhana yang mudah dibaca.
Dua masalah utama dengan kode if / then sederhana adalah bahwa hal itu dapat melanggar prinsip tertutup terbuka . Jika Anda harus masuk dan menambahkan atau mengubah suatu kondisi, Anda memodifikasi kode ini. Jika Anda berharap memiliki lebih banyak kondisi, hanya menambahkan strategi baru lebih sederhana / lebih bersih / lebih kecil kemungkinannya untuk dipatahkan.
Masalah lainnya adalah kopling. Dengan menggunakan if / then, semua implementasi terkait dengan implementasi itu, membuat mereka lebih sulit untuk berubah di masa depan. Dengan menggunakan strategi, satu-satunya sambungan adalah antarmuka dari strategi.
sumber
Strategi berguna ketika
if/then
kondisi didasarkan pada jenis , seperti dijelaskan dalam http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.htmlPengecekan tipe-ketik biasanya tidak memiliki kompleksitas siklomatik yang tinggi, jadi saya tidak akan mengatakan bahwa Strategi meningkatkan segalanya di sana.
Alasan utama Strategi dijelaskan dalam buku GoF hal.316 yang memperkenalkan pola:
Sebagaimana disebutkan dalam jawaban lain, jika diterapkan dengan tepat, pola Strategi memungkinkan penambahan ekstensi baru (strategi konkret) tanpa perlu memerlukan modifikasi dari sisa kode. Inilah yang disebut prinsip Terbuka-Tertutup atau prinsip Variasi yang Dilindungi . Tentu saja, Anda masih harus membuat kode strategi konkret baru, dan kode klien harus mengenali strategi sebagai plug-in (ini bukan hal sepele).
Dengan
if/then
conditional, perlu untuk mengubah kode kelas yang berisi logika kondisional. Seperti disebutkan dalam jawaban lain, terkadang ini OK jika Anda tidak ingin menambahkan kompleksitas untuk mendukung penambahan fungsionalitas baru (plug-in) tanpa kompilasi ulang.sumber
Itulah manfaat terbesar dari pola strategis. Tidak memiliki kondisi.
Anda ingin kelas / metode / fungsi Anda sesederhana dan sesingkat mungkin. Kode pendek sangat mudah diuji dan sangat mudah dibaca.
Kondisi (
if
/elseif
/else
) membuat kelas / metode / fungsi Anda lama, karena biasanya kode tempat satu keputusan dievaluasitrue
berbeda dari bagian di mana keputusan itu dievaluasifalse
.Manfaat besar lain dari pola strategi adalah, dapat digunakan kembali di seluruh proyek Anda.
Saat menggunakan pola desain strategi, Anda sangat mungkin memiliki semacam wadah IoC, dari mana Anda memperoleh implementasi antarmuka yang diinginkan, mungkin dengan
getById(int id)
metode, di manaid
bisa menjadi anggota enumerator.Ini berarti, pembuatan implementasi hanya di satu tempat kode Anda.
Jika Anda ingin menambahkan lebih banyak implementasi, Anda menambahkan implementasi baru ke
getById
metode dan perubahan ini tercermin di mana-mana dalam kode tempat Anda menyebutnya.Dengan
if
/elseif
/else
ini tidak mungkin dilakukan. Dengan menambahkan implementasi baru, Anda harus menambahkanelseif
blok baru dan melakukannya di mana saja di mana implementasi digunakan, atau Anda mungkin berakhir dengan kode yang tidak valid, karena Anda lupa menambahkan implementasi ke strukturnya.Dalam contoh saya,
id
bisa berupa variabel yang diisi berdasarkan input pengguna. Jika pengguna mengklik tombol A, makaid = 2
, jika dia mengklik tombol B, makaid = 8
.Karena nilai yang berbeda
id
, implementasi antarmuka yang berbeda diperoleh dari wadah IoC dan kode melakukan operasi yang berbeda.sumber
if
/elseif
/else
negara. Sama seperti sebelumnya, hanya di tempat yang berbeda.id
variabel dalamgetById
metode ini, yang akan mengembalikan implementasi spesifik. Setiap kali Anda membutuhkan implementasi antarmuka, Anda akan meminta wadah IoC untuk mengirimkannya kepada Anda.getSortByEnumType(SortEnum type)
mengembalikan implementasiSort
antarmuka, memiliki metodegetSortType
mengembalikanSortEnum
variabel dan mengambil koleksi sebagai parameter, dangetSortByEnumType
metode itu lagi akan berisi saklar padatype
parameter mengembalikan Anda algoritma pengurutan yang benar. Jika Anda perlu menambahkan algoritma pengurutan baru, Anda hanya perlu mengedit metode enum dan satu. Dan Anda sudah siap.Pola Strategi memungkinkan Anda memisahkan algoritma (detail) dari logika bisnis Anda (kebijakan tingkat tinggi). Kedua hal ini tidak hanya membingungkan untuk dibaca ketika dicampur, tetapi juga memiliki alasan yang sangat berbeda untuk berubah.
Ada juga faktor skalabilitas kerja tim utama di sini. Bayangkan sebuah tim pemrograman besar di mana banyak orang mengerjakan paket akuntansi ini. Jika algoritme pajak semuanya ada dalam kelas atau modul Wajib Pajak , maka kemungkinan menggabungkan konflik. Menggabungkan konflik memakan waktu dan mudah diselesaikan. Kali ini menguras produktivitas dari tim dan kesalahan yang diperkenalkan oleh kredibilitas buruk merusak kredibilitas dengan pelanggan.
Algoritma yang berubah saat runtime adalah yang perilakunya ditentukan oleh konfigurasi atau konteks. Pendekatan if / then di tempat tidak secara efektif mengaktifkan ini karena melibatkan memuat kembali kelas yang digunakan aktif. Dengan Pola Strategi, objek strategi yang mengimplementasikan setiap algoritma dapat dibangun pada penggunaan. Akibatnya perubahan pada algoritma ini (perbaikan bug atau peningkatan) dapat dilakukan dan dimuat kembali saat runtime. Pendekatan ini dapat digunakan untuk memungkinkan ketersediaan terus-menerus dan rilis tanpa downtime.
sumber
Tidak ada yang salah dengan
if/else
per se. Dalam banyak kasusif/else
adalah cara mengekspresikan logika yang paling sederhana dan paling mudah dibaca. Jadi pendekatan yang Anda gambarkan sangat valid dalam banyak kasus. (Ini juga sangat dapat diuji, sehingga tidak menjadi masalah.)Tetapi ada beberapa kasus tertentu di mana pola strategi dapat meningkatkan pemeliharaan kode keseluruhan. Sebagai contoh:
Agar pola strategi masuk akal, antarmuka antara logika inti dan algoritma penghitungan pajak harus lebih stabil daripada komponen individual. Jika ada kemungkinan bahwa perubahan persyaratan akan menyebabkan antarmuka berubah, maka pola strategi sebenarnya bisa menjadi kewajiban.
Itu semua bermuara jika "algoritma perhitungan pajak" dapat dipisahkan dengan bersih dari logika inti yang memanggilnya. Pola strategi memiliki beberapa overhead dibandingkan dengan
if/else
, jadi Anda harus memutuskan berdasarkan kasus per kasus jika investasi itu sepadan.sumber