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 : Componentmewakili kelas asas (atau mungkin antara muka) untuk objek primitif, dan Compositemewakili kelas komposit. Contohnya, Componentkelas mungkin mewakili kelas asas untuk primitif grafik, sedangkan Compositekelas mungkin mewakili Drawingkelas. Kelas Rajah 1 Leafmewakili objek primitif konkrit; contohnya, Linekelas atau Textkelas. Yang Operation1()dan Operation2()kaedah mewakili kaedah domain khusus yang dilaksanakan oleh kedua-dua Componentdan Compositekelas.

The Compositekelas mengekalkan koleksi komponen. Biasanya, Compositekaedah dilaksanakan dengan melakukan iterasi pada koleksi tersebut dan menggunakan kaedah yang sesuai untuk setiap Componentkoleksi tersebut. Sebagai contoh, Drawingkelas 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 Componentkelas, Compositekelas menerapkan kaedah dengan tandatangan yang sama yang berulang pada komponen komposit, seperti yang digambarkan oleh draw()kaedah yang disenaraikan di atas.

The Compositekelas memanjangkan Componentkelas, 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 Compositekelas 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 Componentkelas. Kaedah itu mengembalikan falsekomponen dan diganti dalam Compositekelas untuk dikembalikan true. Selain itu, anda juga mesti memberikan Componentrujukan ke Compositecontoh, seperti ini:

... if (komponen.isComposite ()) {Komposit komposit = (Komposit) komponen; komposit.addComponent (someComponentThatCouldBeAComposite); } ...

Perhatikan bahawa addComponent()kaedah ini diberikan Componentrujukan, 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 Componentrujukan ke sebuah Compositecontoh. Oleh itu, fragmen kod yang disenaraikan di atas menjadi satu baris:

... komponen.addComponent (someComponentThatCouldBeAComposite); ...

Tetapi, jika Componentrujukan 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 --%>
   
Links

Home

Products

Downloads

White papers

Contact us

Welcome to Sabreware, Inc.
Kandungan khusus halaman terdapat di sini

Terima kasih kerana berhenti!

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 :