Melihat corak reka bentuk Komposit
Pada hari yang lain saya mendengar Car Talk Radio Public Public , siaran mingguan yang popular di mana pemanggil bertanya mengenai kenderaan mereka. Sebelum setiap rehat program, tuan rumah rancangan meminta pemanggil untuk menghubungi 1-800-CAR-TALK, yang sesuai dengan 1-800-227-8255. Sudah tentu, yang pertama terbukti lebih mudah diingat daripada yang terakhir, sebahagiannya kerana kata-kata "CAR TALK" adalah gabungan: dua perkataan yang mewakili tujuh digit. Manusia pada amnya lebih mudah berurusan dengan komposit, daripada komponennya masing-masing. Begitu juga, apabila anda mengembangkan perisian berorientasikan objek, selalunya mudah untuk memanipulasi komposit seperti anda memanipulasi komponen individu. Premis itu mewakili prinsip asas corak reka bentuk Komposit,topik Pola Reka Bentuk Java ini ansuran.
Corak Komposit
Sebelum kita menyelami corak Komposit, saya mesti terlebih dahulu menentukan objek komposit: objek yang mengandungi objek lain; sebagai contoh, lukisan mungkin terdiri daripada primitif grafik, seperti garis, bulatan, segi empat tepat, teks, dan sebagainya.
Pembangun Java memerlukan corak Komposit kerana kita sering mesti memanipulasi komposit dengan cara yang sama seperti kita memanipulasi objek primitif. Contohnya, primitif grafik seperti garis atau teks mesti dilukis, dipindahkan, dan diubah saiznya. Tetapi kami juga ingin melakukan operasi yang sama pada komposit, seperti gambar, yang terdiri dari primitif tersebut. Sebaik-baiknya, kami ingin melakukan operasi pada objek primitif dan komposit dengan cara yang sama, tanpa membezakan antara keduanya. Sekiranya kita mesti membezakan antara objek primitif dan komposit untuk melakukan operasi yang sama pada kedua jenis objek tersebut, kod kita akan menjadi lebih kompleks dan lebih sukar untuk dilaksanakan, dipelihara, dan diperluas.
Dalam Corak Reka Bentuk , penulis menerangkan corak Komposit seperti ini:
Susun objek ke dalam struktur pokok untuk mewakili hierarki sebahagian keseluruhan. Komposit membolehkan pelanggan memperlakukan objek dan komposisi objek secara seragam.Melaksanakan corak Komposit adalah mudah. Kelas komposit memanjangkan kelas asas yang mewakili objek primitif. Rajah 1 menunjukkan rajah kelas yang menggambarkan struktur corak Komposit.

Dalam rajah kelas Gambar 1, saya menggunakan nama kelas dari perbincangan corak Komposit Reka Bentuk Reka Bentuk : Component
mewakili kelas asas (atau mungkin antara muka) untuk objek primitif, dan Composite
mewakili kelas komposit. Contohnya, Component
kelas mungkin mewakili kelas asas untuk primitif grafik, sedangkan Composite
kelas mungkin mewakili Drawing
kelas. Kelas Rajah 1 Leaf
mewakili objek primitif konkrit; contohnya, Line
kelas atau Text
kelas. Yang Operation1()
dan Operation2()
kaedah mewakili kaedah domain khusus yang dilaksanakan oleh kedua-dua Component
dan Composite
kelas.
The Composite
kelas mengekalkan koleksi komponen. Biasanya, Composite
kaedah dilaksanakan dengan melakukan iterasi pada koleksi tersebut dan menggunakan kaedah yang sesuai untuk setiap Component
koleksi tersebut. Sebagai contoh, Drawing
kelas mungkin melaksanakan draw()
kaedahnya seperti ini:
// Kaedah ini adalah kaedah Komposit undian kekosongan awam () {// Iterate over the components for (int i = 0; i <getComponentCount (); ++ i) {// Dapatkan rujukan ke komponen dan buat undiannya kaedah Komponen komponen = getComponent (i); komponen.draw (); }}
Untuk setiap kaedah yang dilaksanakan di Component
kelas, Composite
kelas menerapkan kaedah dengan tandatangan yang sama yang berulang pada komponen komposit, seperti yang digambarkan oleh draw()
kaedah yang disenaraikan di atas.
The Composite
kelas memanjangkan Component
kelas, supaya anda boleh lulus komposit untuk kaedah yang menjangka komponen; sebagai contoh, pertimbangkan kaedah berikut:
// Kaedah ini dilaksanakan dalam kelas yang tidak berkaitan dengan // Component and Composite kelas public void repaint (Komponen komponen) {// Komponen boleh menjadi komposit, tetapi kerana ia meluas // kelas Komponen, kaedah ini tidak perlu // membezakan antara komponen dan komposit komponen.draw (); }
Kaedah sebelumnya dilewatkan komponen - baik komponen sederhana atau komposit - kemudian ia menggunakan draw()
kaedah komponen itu . Kerana Composite
kelas meluas Component
, repaint()
kaedah tidak perlu membezakan antara komponen dan komposit — ia hanya menggunakan draw()
kaedah untuk komponen (atau komposit).
Gambarajah kelas corak Komposit Gambar 1 menggambarkan satu masalah dengan corak: anda mesti membezakan antara komponen dan komposit semasa anda merujuk a Component
, dan anda mesti menggunakan kaedah khusus komposit, seperti addComponent()
. Anda biasanya memenuhi syarat itu dengan menambahkan kaedah, seperti isComposite()
, ke Component
kelas. Kaedah itu mengembalikan false
komponen dan diganti dalam Composite
kelas untuk dikembalikan true
. Selain itu, anda juga mesti memberikan Component
rujukan ke Composite
contoh, seperti ini:
... if (komponen.isComposite ()) {Komposit komposit = (Komposit) komponen; komposit.addComponent (someComponentThatCouldBeAComposite); } ...
Perhatikan bahawa addComponent()
kaedah ini diberikan Component
rujukan, yang boleh menjadi komponen primitif atau komposit. Kerana komponen itu boleh menjadi komposit, anda dapat menyusun komponen menjadi struktur pohon, seperti yang ditunjukkan oleh petikan yang disebutkan di atas dari Pola Reka Bentuk .
Gambar 2 menunjukkan pelaksanaan corak Komposit alternatif.
Sekiranya anda menerapkan corak Komposit Gambar 2, anda tidak perlu membezakan antara komponen dan komposit, dan anda tidak perlu membuat Component
rujukan ke sebuah Composite
contoh. Oleh itu, fragmen kod yang disenaraikan di atas menjadi satu baris:
... komponen.addComponent (someComponentThatCouldBeAComposite); ...
Tetapi, jika Component
rujukan pada fragmen kod sebelumnya tidak merujuk pada a Composite
, apa yang harus addComponent()
dilakukan? Itulah titik pertikaian utama dengan pelaksanaan corak Komposit Gambar 2. Oleh kerana komponen primitif tidak mengandungi komponen lain, menambahkan komponen ke komponen lain tidak masuk akal, jadi Component.addComponent()
kaedah ini boleh gagal secara senyap atau membuang pengecualian. Biasanya, menambahkan komponen ke komponen primitif yang lain dianggap sebagai kesalahan, jadi membuang pengecualian mungkin merupakan tindakan terbaik.
Oleh itu, pelaksanaan corak Komposit yang mana-mana yang ditunjukkan dalam Rajah 1 atau yang dalam Rajah 2-paling sesuai? Itu selalu menjadi topik perbahasan hebat di kalangan pelaksana corak Komposit; Corak Reka bentuk lebih suka pelaksanaan Gambar 2 kerana anda tidak perlu membezakan antara komponen dan bekas, dan anda tidak perlu melakukan pemeran. Secara peribadi, saya lebih suka pelaksanaan Gambar 1, kerana saya sangat enggan melaksanakan kaedah di kelas yang tidak masuk akal untuk jenis objek tersebut.
Sekarang setelah anda memahami corak Komposit dan bagaimana anda dapat menerapkannya, mari kita periksa contoh corak Komposit dengan kerangka Apache Struts JavaServer Pages (JSP).
Corak Komposit dan Struts Tiles
The Apache Struts framework includes a JSP tag library, known as Tiles, that lets you compose a Webpage from multiple JSPs. Tiles is actually an implementation of the J2EE (Java 2 Platform, Enterprise Edition) CompositeView pattern, itself based on the Design Patterns Composite pattern. Before we discuss the Composite pattern's relevance to the Tiles tag library, let's first review the rationale for Tiles, and how you use it. If you're already familiar with Struts Tiles, you can skim the following sections and commence reading at "Use the Composite Pattern with Struts Tiles."
Note: You can read more about the J2EE CompositeView pattern in my "Web Application Components Made Easy with Composite View" (JavaWorld, December 2001) article.
Designers often construct Webpages with a set of discrete regions; for example, Figure 3's Webpage comprises a sidebar, header, content region, and footer.
Websites often include multiple Webpages with identical layouts, such as Figure 3's sidebar/header/content/footer layout. Struts Tiles lets you reuse both content and layout among multiple Webpages. Before we discuss that reuse, let's see how Figure 3's layout is traditionally implemented with HTML alone.
Implement complex layouts by hand
Example 1 shows how you can implement Figure 3's Webpage with HTML:
Example 1. A complex layout implemented by hand
Implementing Complex Layouts by Hand <%-- One table lays out all of the content for this page --%>
|
|
JSP sebelumnya mempunyai dua kelemahan utama: Pertama, kandungan halaman disematkan di JSP, jadi Anda tidak dapat menggunakannya kembali, walaupun bar sisi, header, dan footer mungkin sama di banyak Halaman Web. Kedua, susun atur halaman juga disertakan dalam JSP itu, jadi anda juga tidak dapat menggunakannya kembali walaupun banyak Halaman Web lain di Laman web yang sama menggunakan susun atur yang sama. Kita boleh menggunakan tindakan untuk mengatasi kelemahan pertama, seperti yang saya bincangkan seterusnya.
Laksanakan susun atur yang rumit dengan JSP termasuk
Contoh 2 menunjukkan pelaksanaan Laman Web Gambar 3 yang menggunakan :