Mengapa ShapeFactory ini menggunakan pernyataan kondisional untuk menentukan objek apa yang akan dipakai. Jangan kita harus memodifikasi ShapeFactory jika kita ingin menambahkan kelas lain di masa depan? Mengapa ini tidak melanggar prinsip tertutup terbuka?
design
design-patterns
factory-method
factory
Armon Safai
sumber
sumber
Jawaban:
Kebijaksanaan berorientasi objek konvensional adalah untuk menghindari
if
pernyataan dan menggantinya dengan pengiriman dinamis metode override dalam subkelas kelas abstrak. Sejauh ini baik.Tetapi inti dari pola pabrik adalah membebaskan Anda dari keharusan mengetahui tentang masing-masing subkelas dan hanya bekerja dengan superclass abstrak . Idenya adalah bahwa pabrik tahu lebih baik daripada Anda yang kelas khusus untuk instantiate, dan Anda akan lebih baik bekerja hanya dengan metode yang dipublikasikan oleh kelas super. Ini sering benar dan merupakan pola yang berharga.
Oleh karena itu, tidak mungkin menulis kelas pabrik dapat mengabaikan
if
pernyataan. Ini akan menggeser beban memilih kelas tertentu ke penelepon, yang persis apa yang seharusnya dihindari pola. Tidak semua prinsip bersifat absolut (pada kenyataannya, tidak ada prinsip yang absolut), dan jika Anda menggunakan pola ini Anda akan menganggap bahwa manfaat darinya lebih besar daripada manfaat tidak menggunakanif
.sumber
if
. Lihat jawaban @ BЈовић untuk contoh sederhana tentang cara mencapai ini. Diturunkan.Contohnya mungkin menggunakan pernyataan kondisional karena itu adalah yang paling sederhana. Implementasi yang lebih kompleks mungkin menggunakan peta atau konfigurasi atau (jika Anda ingin benar-benar mewah) semacam registri di mana kelas dapat mendaftar sendiri. Namun tidak ada yang salah dengan menggunakan kondisi jika jumlah kelas kecil dan perubahan jarang terjadi.
Memperluas persyaratan untuk menambah dukungan untuk subkelas baru di masa depan memang akan menjadi pelanggaran prinsip terbuka / tertutup. Solusi "benar" adalah membuat pabrik baru dengan antarmuka yang sama. Yang mengatakan, kepatuhan terhadap prinsip O / C harus selalu ditimbang terhadap prinsip-prinsip desain lainnya seperti KISS dan YAGNI.
Yang mengatakan, kode yang ditampilkan jelas contoh kode yang dirancang untuk menunjukkan konsep pabrik dan tidak ada yang lain. Misalnya itu adalah gaya yang benar-benar buruk untuk mengembalikan nol seperti contohnya, tetapi penanganan kesalahan yang lebih rumit hanya akan mengaburkan intinya. Kode contoh bukan kode kualitas produksi, kode apa pun yang tidak Anda harapkan.
sumber
Pola itu sendiri tidak melanggar Prinsip Terbuka / Tertutup (OCP). Namun, kami melanggar OCP ketika kami menggunakan pola yang salah.
Jawaban sederhana untuk pertanyaan ini adalah sebagai berikut:
Dalam contoh yang diberikan, fungsionalitas dasar Anda mendukung tiga bentuk: Lingkaran, Kotak, dan Kotak. Misalkan Anda perlu mendukung Triangle, Pentagon, dan Hexagon di masa depan. Untuk melakukan ini TANPA melanggar OCP, Anda harus membuat pabrik tambahan untuk mendukung bentuk baru Anda (sebut saja
AdvancedShapeFactory
) dan kemudian gunakan AbstractFactory untuk memutuskan pabrik apa yang perlu Anda buat untuk membuat bentuk apa pun yang Anda butuhkan.sumber
Jika Anda berbicara tentang pola Abstrak Pabrik, pengambilan keputusan sering bukan di Pabrik itu sendiri tetapi dalam kode aplikasi. Kode itulah yang memilih pabrik beton apa yang akan dipakai dan memberikan kode klien yang akan menggunakan objek yang diproduksi oleh Pabrik. Lihat akhir dari contoh Java di sini: https://en.wikipedia.org/wiki/Abstract_factory_pattern
Pengambilan keputusan tidak selalu berarti
if
pernyataan. Itu bisa membaca jenis Pabrik beton dari file konfigurasi, berasal dari struktur peta, dll.sumber
Jika Anda berpikir tentang Open-Close di tingkat kelas dengan pabrik ini, Anda membuat kelas lain di sistem Anda Open-Close, misalnya jika Anda memiliki kelas lain yang mengambil satu Shape dan menghitung area (contoh umum) kelas ini adalah OpenClose karena dapat menghitung luas untuk tipe bentuk baru tanpa modifikasi. Kemudian Anda memiliki kelas lain yang menggambar bentuk, kelas lain yang mengambil bentuk N dan mengembalikan yang lebih besar dan Anda dapat berpikir secara umum bahwa kelas-kelas lain di sistem Anda yang berhubungan dengan bentuk adalah Open-Close (setidaknya tentang bentuk). Melihat desain pabrik memungkinkan sisa sistem menjadi Open-Close dan tentunya pabrik itu sendiri TIDAK Open-Close.
Tentu saja Anda dapat membuat pabrik ini buka-tutup juga, melalui semacam pemuatan dinamis dan seluruh sistem Anda bisa Terbuka-Tutup (misalnya, Anda dapat menambahkan bentuk baru dengan menjatuhkan beberapa toples di classpath). Anda perlu mengevaluasi apakah kompleksitas tambahan ini layak tergantung pada sistem yang Anda bangun, tidak semua sistem perlu fitur yang dapat dicolokkan dan tidak semua sistem harus sepenuhnya Terbuka-Tutup.
sumber
Prinsip tertutup-terbuka, sebagai prinsip substitusi Liskov, berlaku untuk pohon kelas, untuk hierarki warisan. Dalam contoh Anda, kelas pabrik tidak di pohon keluarga dari kelas yang instantiate sehingga tidak bisa melanggar aturan ini. Akan ada pelanggaran jika GetShape Anda (atau lebih tepatnya, CreateShape) diimplementasikan di kelas basis bentuk.
sumber
Itu semua tergantung bagaimana Anda menerapkannya. Anda bisa menggunakan
std::map
untuk menahan fungsi pointer ke fungsi membuat objek. Maka prinsip buka / tutup tidak dilanggar. Atau beralih / kasing.Lagi pula, jika Anda tidak menyukai pola pabrik, Anda selalu dapat menggunakan injeksi ketergantungan.
sumber