Pola pabrik (atau setidaknya penggunaan FactoryFactory..
) adalah bagian dari banyak lelucon, seperti di sini .
Selain memiliki nama verbose dan "kreatif" seperti RequestProcessorFactoryFactory.RequestProcessorFactory , apakah ada yang salah secara mendasar dengan pola pabrik jika Anda harus memprogram di Java / C ++ dan ada usecase untuk Abstract_factory_pattern ?
Bagaimana bahasa populer lain (misalnya, Ruby atau Scala ) menghindari keharusan menggunakannya sambil mengelola kompleksitas yang sama?
Alasan saya bertanya adalah saya melihat sebagian besar kritik dari pabrik yang disebutkan dalam konteks ekosistem Jawa / Jawa EE , tetapi mereka tidak pernah menjelaskan bagaimana bahasa / kerangka kerja lain menyelesaikannya.
java
design-patterns
senseiwu
sumber
sumber
Jawaban:
Pertanyaan Anda ditandai dengan "Java", tidak heran Anda bertanya mengapa pola Pabrik diejek: Java sendiri dilengkapi dengan penyalahgunaan pola yang dikemas dengan baik.
Misalnya, coba memuat dokumen XML dari file dan jalankan permintaan XPath terhadapnya. Anda memerlukan sekitar 10 baris kode hanya untuk mengatur Pabrik dan Pembangun:
Saya bertanya-tanya apakah orang-orang yang merancang API ini pernah bekerja sebagai pengembang atau mereka hanya membaca buku dan melempar barang-barang. Saya mengerti mereka hanya tidak ingin menulis parser sendiri dan menyerahkan tugas kepada orang lain tetapi masih membuat implementasi yang jelek.
Karena Anda bertanya apa alternatifnya, memuat file XML di C #:
Saya menduga pengembang Java yang baru menetas melihat kegilaan Pabrik dan berpikir tidak apa-apa untuk melakukan itu - jika para genius yang membangun Jawa sendiri telah menggunakan mereka sebanyak itu.
Pabrik dan pola lainnya adalah alat, masing-masing cocok untuk pekerjaan tertentu. Jika Anda menerapkannya pada pekerjaan, mereka tidak cocok karena Anda pasti memiliki kode jelek.
sumber
XmlDocument xml = new XmlDocument(); xml.Load("c:\\employees.xml"); XmlNodeList nodes = xml.SelectNodes(expression);
(Secara keseluruhan, LINQ ke XML jauh lebih mudah digunakan, meskipun sebagian besar di daerah lain.) Dan inilah artikel KB Saya menemukan, dengan metode yang direkomendasikan MS: support.microsoft.com/kb/308333Seperti yang sering terjadi, orang salah mengerti apa yang sedang terjadi (dan itu termasuk banyak yang tertawa).
Bukan pola pabrik itu sendiri yang seburuk yang dilakukan oleh banyak orang (bahkan mungkin sebagian besar) orang.
Dan itu tidak diragukan lagi berasal dari cara pemrograman (dan pola) diajarkan. Anak-anak sekolah (sering menyebut diri mereka sendiri "siswa") diminta untuk "membuat X menggunakan pola Y" dan setelah beberapa iterasi berpikir bahwa itulah cara untuk mendekati masalah pemrograman apa pun.
Jadi mereka mulai menerapkan pola tertentu yang kebetulan mereka sukai di sekolah terhadap apa pun dan semua, apakah itu sesuai atau tidak.
Dan itu termasuk profesor universitas yang menulis buku tentang desain perangkat lunak, sayangnya.
Puncak dari ini adalah sistem saya memiliki ketidaksenangan yang berbeda karena harus memelihara yang telah dibuat oleh orang seperti itu (orang itu bahkan memiliki beberapa buku tentang desain berorientasi objek dengan namanya, dan posisi mengajar di departemen CS dari sebuah universitas besar. ).
Itu didasarkan pada pola 3 tier, dengan masing-masing tier itu sendiri sistem 3 tier (harus decouple ...). Pada antarmuka antara setiap set tingkatan, di kedua sisi, adalah pabrik untuk menghasilkan objek untuk mentransfer data ke tingkat lainnya, dan pabrik untuk menghasilkan objek untuk menerjemahkan objek yang diterima ke salah satu milik lapisan penerima.
Untuk setiap pabrik ada pabrik abstrak (siapa tahu, pabrik mungkin harus berubah dan kemudian Anda tidak ingin kode panggilan harus berubah ...).
Dan kekacauan itu tentu saja benar-benar tidak berdokumen.
Sistem memiliki database dinormalisasi ke bentuk normal ke-5 (I kid you not).
Sebuah sistem yang pada dasarnya sedikit lebih dari sebuah buku alamat yang dapat digunakan untuk mencatat dan melacak dokumen yang masuk dan keluar, ia memiliki basis kode 100MB di C ++ dan lebih dari 50 tabel database. Mencetak 500 surat formulir akan memakan waktu 72 jam menggunakan printer yang terhubung langsung ke komputer yang menjalankan perangkat lunak.
Itulah sebabnya orang-orang mencemooh pola, dan khususnya orang yang berfokus sendirian pada satu pola tertentu.
sumber
Pabrik memiliki banyak keunggulan yang memungkinkan desain aplikasi yang elegan dalam beberapa situasi. Salah satunya adalah Anda dapat mengatur properti objek yang nanti ingin Anda buat di satu tempat dengan membuat pabrik, lalu menyerahkan pabrik itu ke mana-mana. Tetapi seringkali Anda sebenarnya tidak perlu melakukan itu. Dalam hal menggunakan Pabrik hanya menambah kompleksitas tambahan tanpa benar-benar memberi Anda imbalan. Mari kita ambil pabrik ini, misalnya:
Salah satu alternatif dari pola Pabrik adalah pola Builder yang sangat mirip. Perbedaan utama adalah bahwa properti dari objek yang dibuat oleh Pabrik diatur ketika Pabrik diinisialisasi, sedangkan Builder diinisialisasi dengan keadaan default dan semua properti diatur setelahnya.
Tetapi ketika overengineering adalah masalah Anda, mengganti Pabrik dengan Builder kemungkinan tidak banyak perbaikan.
Penggantian paling sederhana untuk kedua pola tentu saja untuk membuat instance-objek dengan konstruktor sederhana dengan
new
operator:Konstruktor, bagaimanapun, memiliki kelemahan penting dalam sebagian besar bahasa berorientasi objek: Mereka harus mengembalikan objek dari kelas yang tepat dan tidak dapat mengembalikan sub-tipe.
Ketika Anda perlu memilih sub-tipe saat runtime tetapi tidak ingin menggunakan untuk membuat kelas Builder atau Factory baru untuk itu, Anda dapat menggunakan metode pabrik sebagai gantinya. Ini adalah metode statis kelas yang mengembalikan contoh baru dari kelas itu atau salah satu sub-kelasnya. Pabrik yang tidak memiliki status internal apa pun seringkali dapat diganti dengan metode pabrik seperti itu:
Fitur baru di Java 8 adalah referensi metode yang memungkinkan Anda untuk meneruskan metode, sama seperti yang Anda lakukan dengan pabrik stateless. Dengan mudah, apa pun yang menerima referensi metode juga menerima objek apa pun yang mengimplementasikan antarmuka fungsional yang sama, yang juga bisa menjadi Pabrik lengkap dengan keadaan internal, sehingga Anda dapat dengan mudah memperkenalkan pabrik nanti, ketika Anda melihat alasan untuk melakukannya.
sumber
foo = new Bar(23);
setara denganfoo = Bar._createInstance(23);
. Suatu objek harus dapat secara andal menanyai tipenya sendiri menggunakangetRealType()
metode pribadi , tetapi objek harus mampu menunjuk suatu supertype untuk dikembalikan oleh panggilan luar kegetType()
. Kode luar seharusnya tidak peduli apakah panggilan untuknew String("A")
benar - benar mengembalikan instanceString
[sebagai lawan dari misalnya instanceSingleCharacterString
].draw(OutputStream out)
tetapi menghasilkan html yang sedikit berbeda, pabrik metode statis menciptakan kelas yang tepat untuk situasi dan kemudian penelepon hanya dapat menggunakan metode menggambar.[[SomeClass alloc] init]
. Dimungkinkan untuk mengembalikan instance kelas yang sama sekali berbeda atau objek lain (seperti nilai cache)Berbagai jenis pabrik ditemukan dalam hampir semua bahasa berorientasi objek dalam keadaan yang sesuai. Terkadang Anda hanya butuh cara untuk memilih objek apa yang akan dibuat berdasarkan parameter sederhana seperti string.
Beberapa orang mengambilnya terlalu jauh dan mencoba merancang kode mereka untuk tidak perlu memanggil konstruktor kecuali di dalam pabrik. Hal-hal mulai menjadi konyol ketika Anda memiliki pabrik pabrik.
Apa yang mengejutkan saya ketika saya belajar Scala, dan saya tidak tahu Ruby, tetapi percaya bahwa itu adalah cara yang sama, adalah bahwa bahasa tersebut cukup ekspresif sehingga programmer tidak selalu mencoba untuk mendorong pekerjaan "plumbing" ke file konfigurasi eksternal . Alih-alih tergoda untuk membuat pabrik pabrik untuk menyatukan kelas-kelas Anda dalam konfigurasi yang berbeda, di Scala Anda menggunakan objek yang bercampur. Ini juga relatif mudah untuk membuat DSL sederhana dalam bahasa untuk tugas-tugas yang sering direkayasa secara berlebihan di Jawa.
Juga, seperti yang ditunjukkan oleh komentar dan jawaban lainnya, fungsi penutupan dan kelas satu meniadakan kebutuhan akan banyak pola. Untuk alasan itu, saya percaya banyak dari anti-pola akan mulai menghilang ketika C ++ 11 dan Java 8 mendapatkan adopsi luas.
sumber
Secara umum, ada kecenderungan bahwa program-program Java sangat direkayasa berlebihan. Memiliki banyak pabrik adalah salah satu gejala over-engineering yang paling umum; itu sebabnya orang mengolok-olok mereka.
Secara khusus, masalah Jawa dengan pabrik adalah bahwa di Jawa a) konstruktor bukan fungsi dan b) fungsi bukan warga negara kelas satu.
Bayangkan Anda bisa menulis sesuatu seperti ini (biarlah
Function
antarmuka JRE yang terkenal )Lihat, tidak ada antarmuka pabrik atau kelas. Banyak bahasa dinamis memiliki fungsi kelas satu. Sayangnya, ini tidak mungkin dengan Java 7 atau sebelumnya (menerapkan hal yang sama dengan pabrik dibiarkan sebagai latihan untuk pembaca).
Jadi, alternatifnya bukanlah "menggunakan pola yang berbeda", tetapi lebih "menggunakan bahasa dengan model objek yang lebih baik" atau "jangan merekayasa masalah sederhana".
sumber