Saya telah bertanya-tanya apa yang membuat Iterator istimewa jika dibandingkan dengan konstruksi serupa lainnya, dan yang membuat Gang of Four mencantumkannya sebagai pola desain.
Iterator didasarkan pada polimorfisme (hierarki koleksi dengan antarmuka umum) dan pemisahan masalah (iterasi pada koleksi harus independen dari cara data disusun).
Tetapi bagaimana jika kita mengganti hirarki koleksi dengan, misalnya, hirarki objek matematika (integer, float, complex, matrix dll) dan iterator oleh kelas yang mewakili beberapa operasi terkait pada objek-objek ini, misalnya fungsi daya. Diagram kelas akan sama.
Kami mungkin dapat menemukan banyak contoh serupa seperti Writer, Painter, Encoder, dan mungkin yang lebih baik, yang bekerja dengan cara yang sama. Namun saya belum pernah mendengar ini disebut Pola Desain.
Jadi apa yang membuat Iterator spesial?
Apakah ini fakta yang lebih rumit karena memerlukan keadaan yang bisa berubah untuk menyimpan posisi saat ini dalam koleksi? Tapi kemudian, keadaan yang bisa berubah biasanya tidak dianggap diinginkan.
Untuk memperjelas poin saya, izinkan saya memberikan contoh yang lebih rinci.
Inilah masalah desain kami:
Katakanlah kita memiliki hierarki kelas dan operasi yang didefinisikan pada objek kelas ini. Antarmuka operasi ini sama untuk setiap kelas, tetapi implementasinya dapat sangat berbeda. Juga diasumsikan bahwa masuk akal untuk menerapkan operasi beberapa kali pada objek yang sama, katakan dengan parameter yang berbeda.
Berikut adalah solusi yang masuk akal untuk masalah desain kami (praktis generalisasi dari pola iterator):
Untuk pemisahan masalah, implementasi operasi tidak boleh ditambahkan sebagai fungsi ke hierarki kelas asli (objek operan). Karena kita ingin menerapkan operasi beberapa kali pada operan yang sama, itu harus diwakili oleh objek yang memegang referensi ke operan, bukan hanya oleh fungsi. Oleh karena itu objek operan harus menyediakan fungsi yang mengembalikan objek yang mewakili operasi. Objek ini menyediakan fungsi yang melakukan operasi aktual.
Sebuah contoh:
Ada kelas dasar atau antarmuka MathObject
(nama bodoh, saya tahu, mungkin seseorang memiliki ide yang lebih baik.) Dengan kelas turunan MyInteger
dan MyMatrix
. Untuk setiap MathObject
operasi Power
harus didefinisikan yang memungkinkan perhitungan kuadrat, kubus dan sebagainya. Jadi kita bisa menulis (di Jawa):
MathObject i = new MyInteger(5);
Power powerOfFive = i.getPower();
MyInteger square = powerOfFive.calculate(2); // should return 25
MyInteger cube = powerOfFive.calculate(3); // should return 125
sumber
Jawaban:
Sebagian besar pola dari buku GoF memiliki kesamaan berikut:
Masalah yang dipecahkan oleh pola-pola ini sangat mendasar sehingga banyak pengembang memahaminya terutama sebagai solusi untuk fitur bahasa pemrograman yang hilang , yang merupakan sudut pandang IMHO yang valid (perhatikan bahwa buku GoF berasal dari 1995, di mana Java dan C ++ tidak menawarkan begitu banyak fitur seperti hari ini).
Pola iterator cocok dengan deskripsi ini: itu memecahkan masalah dasar yang terjadi sangat sering, terlepas dari domain tertentu, dan seperti yang Anda tulis sendiri itu adalah contoh yang baik untuk "pemisahan masalah". Seperti yang sudah pasti Anda ketahui, dukungan iterator langsung adalah sesuatu yang Anda temukan dalam banyak bahasa pemrograman kontemporer saat ini.
Sekarang bandingkan ini dengan masalah yang Anda pilih:
Selain itu, saya tidak melihat apa pun dalam contoh fungsi kekuasaan Anda yang tidak dapat diartikan sebagai penerapan pola strategi atau pola perintah, yang berarti bagian-bagian dasar sudah ada dalam buku GoF. Solusi yang lebih baik mungkin berisi kelebihan operator atau metode ekstensi, tetapi hal-hal itu tunduk pada fitur bahasa, dan itulah yang tidak dapat disediakan oleh "OO" yang digunakan oleh "Gang".
sumber
The problems solved by these patterns are so basic that many developers think their main purpose is to be workarounds for missing programming language features
- Ironisnya adalah bahwa pengembang perangkat lunak secara rutin menggunakan pola desain perangkat lunak yang berusia 20 tahun sementara masih percaya bahwa mereka sedang menulis kode canggih.IEnumerable
danyield
). Tetapi untuk pola GoF lainnya, apa yang Anda tulis mungkin benar.workarounds for missing programming language features:
blog.plover.com/prog/johnson.htmlThe Gang of Four mengutip definisi pola Christopher Alexander:
Apa masalah yang dipecahkan oleh iterator?
Jadi orang dapat berargumen bahwa pola iterator adalah menurut domain-spesifik untuk koleksi. Dan itu tidak masalah. Pola lain seperti pola interpreter adalah domain-spesifik untuk domain-spesifik-bahasa, pola pabrik adalah domain-spesifik untuk pembuatan objek,…. Tentu saja ini adalah pemahaman yang agak konyol tentang "domain-spesifik". Selama ini adalah pasangan masalah-solusi yang berulang, kita dapat menyebutnya sebuah pola.
Dan ada baiknya pola Iterator ada. Hal-hal buruk terjadi jika Anda tidak menggunakannya. Anti-example favorit saya adalah Perl. Di sini, setiap koleksi (array atau hash) menyertakan status iterator sebagai bagian dari koleksi. Kenapa ini buruk? Kita dapat dengan mudah beralih pada hash dengan sementara – setiap loop:
Tetapi bagaimana jika kita memanggil fungsi dalam loop body?
Fungsi ini sekarang dapat melakukan hampir semua yang diinginkan, kecuali:
Jika fungsi yang dipanggil harus menggunakan iterator, perilaku loop kami menjadi tidak terdefinisi. Itu masalah. Dan pola iterator memiliki solusi: letakkan semua status iterasi dalam objek terpisah yang dibuat per-iterasi.
Ya, tentu saja pola iterator terkait dengan pola lainnya. Misalnya, bagaimana iterator dipakai? Di Jawa, kami memiliki generik
Iterable<T>
danIterator<T>
antarmuka. Tipe iterable yang konkritArrayList<T>
menciptakan jenis iterator tertentu, sedangkan yangHashSet<T>
mungkin menyediakan tipe iterator yang sama sekali berbeda. Itu mengingatkan saya pada pola pabrik abstrak, di manaIterable<T>
pabrik abstrak danIterator
produknya.Iterator polimorfik juga dapat diartikan sebagai contoh dari pola strategi. Misalnya pohon mungkin menawarkan berbagai jenis iterator (pre-order, in-order, post-order, ...). Secara eksternal, ini semua akan berbagi antarmuka iterator dan menghasilkan elemen dalam beberapa urutan. Kode klien hanya perlu bergantung pada antarmuka iterator, bukan pada algoritma traversal pohon tertentu.
Pola-pola tidak ada dalam isolasi, terpisah satu sama lain. Beberapa pola adalah solusi yang berbeda untuk masalah yang sama, dan beberapa pola menggambarkan solusi yang sama dalam konteks yang berbeda. Beberapa pola menyiratkan yang lain. Selain itu, ruang pola tidak ditutup ketika Anda membalik halaman terakhir buku Pola Desain (lihat juga pertanyaan Anda sebelumnya. Apakah Gang Empat secara menyeluruh mengeksplorasi "Pola Ruang"? ). Pola-pola yang dijelaskan dalam buku Pola Desain sangat fleksibel dan luas, terbuka untuk variasi yang tak terbatas, dan jelas bukan satu-satunya pola yang ada.
Konsep yang Anda daftarkan (menulis, melukis, menyandikan) bukanlah pola karena tidak menggambarkan kombinasi masalah-solusi. Tugas seperti "Saya perlu menulis data" atau "Saya harus menyandikan data" bukan masalah desain dan tidak termasuk solusi; "solusi" yang hanya terdiri dari "Saya tahu, saya akan membuat kelas Writer" tidak ada artinya. Tetapi jika kita memiliki masalah seperti "Saya tidak ingin gambar yang dibuat setengah jadi dilukis di layar", maka sebuah pola mungkin ada: "Saya tahu, saya akan menggunakan gambar buffer ganda!"
sumber