Ikhtisar Cepat
Solusi 3: Pola Desain Perangkat Lunak "Parallel Class Hierarchy" adalah teman Anda.
Jawaban Panjang
Desain Anda MULAI BENAR. Ini dapat dioptimalkan, beberapa kelas atau anggota dapat dihapus, tetapi, ide "hierarki paralel" yang Anda terapkan untuk menyelesaikan masalah IS BENAR.
Sudah beberapa kali berurusan dengan konsep yang sama, biasanya dalam hierarki kontrol.
Setelah beberapa saat, saya BERAKHIRNYA MELAKUKAN SOLUSI SAMA DARI PEMBANGUN LAINNYA, yang kadang-kadang disebut Pola Desain "Paralel Hierarki" atau Pola Desain "Dual Hierarki".
(1) Apakah Anda pernah membagi satu kelas menjadi satu hirarki kelas?
(2) Apakah Anda pernah membagi satu kelas menjadi beberapa kelas, tanpa hierarki?
Jika Anda telah menerapkan solusi sebelumnya, secara terpisah, maka itu adalah cara untuk menyelesaikan beberapa masalah.
Tapi, bagaimana jika kita menggabungkan dua solusi ini secara bersamaan?
Gabungkan mereka, dan, Anda akan mendapatkan "Pola Desain" ini.
Penerapan
Sekarang, mari kita terapkan Pola Desain Perangkat Lunak "Parallel Class Hierarchy", untuk kasus Anda.
Saat ini Anda memiliki 2 atau lebih hierarki kelas independen, yang sangat mirip, memiliki asosiasi atau tujuan yang sama, memiliki properti atau metode yang serupa.
Anda ingin menghindari duplikasi kode atau anggota ("konsistensi"), namun, Anda tidak dapat menggabungkan kelas ini secara langsung menjadi satu, karena perbedaan di antara mereka.
Jadi, hierarki Anda sangat mirip dengan angka ini, namun, ada lebih dari satu:
................................................
...............+----------------+...............
...............| Common:: |...............
...............| Composite |...............
...............+----------------+...............
...............| ... |...............
...............+-------+--------+...............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
...............+-------+--------+...............
...............| Common:: |...............
...............| Viewee |...............
...............+----------------+...............
...............| ... |...............
...............+-------+--------+...............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..| Common:: |........| Common:: |..
..| Visual |........| Structural |..
..+----------------+........+----------------+..
..| ... |........| ... |..
..+----------------+........+----------------+..
................................................
Figure 1
Dalam hal ini, belum disertifikasi, Pola Desain, BEBERAPA HIERARCHI SIMILAR, BERGABUNG, DALAM SEBUAH TUNGGAL TUNGGAL, dan masing-masing kelas bersama atau umum diperluas dengan subklasifikasi.
Perhatikan, bahwa solusi ini rumit, karena Anda sudah berurusan dengan beberapa hierarki, oleh karena itu skenario yang kompleks.
1 Kelas Root
Di setiap hierarki ada kelas "root" bersama.
Dalam kasus Anda, ada kelas "Komposit" yang independen, untuk setiap hierarki, yang dapat memiliki beberapa properti yang serupa, dan beberapa metode yang serupa.
Beberapa anggota tersebut dapat digabung, beberapa anggota tersebut tidak dapat digabung.
Jadi, apa yang bisa dilakukan pengembang, adalah membuat kelas root base, dan mensubklasifikasikan kasus yang setara untuk setiap hierarki.
Pada Gambar 2, Anda dapat melihat diagram hanya untuk kelas ini, di mana setiap kelas, menyimpannya namespace.
Anggota, dihilangkan, sekarang.
................................................
...............+-------+--------+...............
...............| Common:: |...............
...............| Composite |...............
...............+----------------+...............
...............| ... |...............
...............+-------+--------+...............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..| Canvas:: |........| SVG:: |..
..| Composite |........| Composite |..
..+----------------+........+----------------+..
..| ... |........| ... |..
..+----------------+........+----------------+..
................................................
Figure 2
Seperti yang Anda perhatikan, setiap kelas "Komposit" tidak lagi berada dalam hierarki yang terpisah, tetapi digabung menjadi satu hierarki bersama atau umum.
Kemudian, mari kita tambahkan anggota, mereka yang sama, dapat dipindahkan ke superclass, dan mereka yang berbeda, untuk setiap kelas dasar.
Dan seperti yang sudah Anda ketahui, metode "virtual" atau "kelebihan beban" didefinisikan dalam kelas dasar, tetapi diganti dalam subkelas. Seperti Gambar 3.
................................................
.............+--------------------+.............
.............| Common:: |.............
.............| Composite |.............
.............+--------------------+.............
.............| [+] void AddChild()|.............
.............+---------+----------+.............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..| Canvas:: |........| SVG:: |..
..| Composite |........| Composite |..
..+----------------+........+----------------+..
..| ... |........| ... |..
..+----------------+........+----------------+..
................................................
Figure 3
Perhatikan bahwa mungkin ada beberapa kelas tanpa anggota, dan, Anda mungkin tergoda untuk menghapus kelas-kelas itu, DONT. Mereka disebut "Kelas Hollow", "Kelas Enumeratif", dan nama lainnya.
2 Subclass
Mari kita kembali ke diagram pertama. Setiap kelas "Composite", memiliki subclass "Viewee", di setiap hierarki.
Proses ini diulang untuk setiap kelas. Catatan dari Gambar 4, kelas "Common :: Viewee" turun dari "Common :: Composite", tetapi, untuk kesederhanaan, kelas "Common :: Composite" dihilangkan, dari diagram.
................................................
.............+--------------------+.............
.............| Common:: |.............
.............| Viewee |.............
.............+--------------------+.............
.............| ... |.............
.............+---------+----------+.............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..| Canvas:: |........| SVG:: |..
..| Viewee |........| Viewee |..
..+----------------+........+----------------+..
..| ... |........| ... |..
..+----------------+........+----------------+..
................................................
Figure 4
Anda akan mencatat, bahwa "Canvas :: Viewee" dan "SVG :: Viewee", TIDAK LEBIH LAMA dari masing-masing "Composite", tetapi, dari "Common :: Viewee" yang umum.
Anda dapat menambahkan anggota, sekarang.
......................................................
.........+------------------------------+.............
.........| Common:: |.............
.........| Viewee |.............
.........+------------------------------+.............
.........| [+] bool Validate() |.............
.........| [+] Rect GetAbsoluteBounds() |.............
.........+-------------+----------------+.............
.......................|..............................
.......................^..............................
....................../.\.............................
.....................+-+-+............................
.......................|..............................
..........+------------+----------------+.............
..........|.............................|.............
..+-------+---------+........+----------+----------+..
..| Canvas:: |........| SVG:: |..
..| Viewee |........| Viewee |..
..+-----------------+........+---------------------+..
..| |........| [+] Viewee Element |..
..+-----------------+........+---------------------+..
..| [+] void Paint()|........| [+] void addChild() |..
..+-----------------+........+---------------------+..
......................................................
Figure 5
3 Ulangi Prosesnya
Proses akan berlanjut, untuk setiap kelas, "Canvas :: Visual" tidak akan turun dari "Canvas :: Viewee", buit dari "Commons :: Visual", "Canvas :: Structural" tidak akan turun dari "Canvas :: Viewee ", buit dari" Commons :: Structural ", dan sebagainya.
4 Diagram Hirarki 3D
Anda akan selesai mendapatkan semacam diagram 3D, dengan beberapa lapisan, lapisan atas, memiliki hierarki "Umum" dan lapisan bawah, memiliki setiap hierarki tambahan.
Hirarki kelas independen asli Anda, tempat sesuatu yang mirip dengan ini (Gambar 6):
.................................................
..+-----------------+.......+-----------------+..
..| Common:: |.......| SVG:: |..
..| Composite |.......| Composite |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+--------+--------+.......+--------+--------+..
...........|.........................|...........
...........^.........................^...........
........../.\......................./.\..........
.........+-+-+.....................+-+-+.........
...........|.........................|...........
..+--------+--------+.......+--------+--------+..
..| Common:: |.......| SVG:: |..
..| Viewee |.......| Viewee |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+--------+--------+.......+--------+--------+..
...........|.........................|...........
...........^.........................^...........
........../.\......................./.\..........
.........+-+-+.....................+-+-+.........
...........|.........................|...........
..+--------+--------+.......+--------+--------+..
..| Common:: |.......| SVG:: |..
..| Visual |.......| Visual |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+--------+--------+.......+--------+--------+..
...........|.........................|...........
...........^.........................^...........
........../.\......................./.\..........
.........+-+-+.....................+-+-+.........
...........|.........................|...........
..+--------+--------+.......+--------+--------+..
..| Common:: |.......| SVG:: |..
..| Rect |.......| Rect |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+-----------------+.......+-----------------+..
.................................................
Figure 6
Perhatikan bahwa beberapa kelas dihilangkan, dan seluruh hierarki "Kanvas" dihilangkan, untuk secara sederhana.
Hirarki kelas terintegrasi akhir mungkin sesuatu yang mirip dengan ini:
.................................................
..+-----------------+.../+..+-----------------+..
..| Common:: +--<.+--+ SVG:: |..
..| Composite |...\+..| Composite |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+--------+--------+.......+-----------------+..
...........|.....................................
...........^.....................................
........../.\....................................
.........+-+-+...................................
...........|.....................................
..+--------+--------+.../+..+-----------------+..
..| Common:: +--<.+--+ SVG:: |..
..| Viewee |...\+..| Viewee |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+--------+--------+.......+-----------------+..
...........|.....................................
...........^.....................................
........../.\....................................
.........+-+-+...................................
...........|.....................................
..+--------+--------+.../+..+-----------------+..
..| Common:: +--<.+--+ SVG:: |..
..| Visual |...\+..| Visual |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+--------+--------+.......+-----------------+..
...........|.....................................
...........^.....................................
........../.\....................................
.........+-+-+...................................
...........|.....................................
..+--------+--------+.../+..+-----------------+..
..| Common:: +--<.+--+ SVG:: |..
..| Rect |...\+..| Rect |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+-----------------+.......+-----------------+..
.................................................
Figure 7
Perhatikan bahwa beberapa kelas dihilangkan, dan seluruh kelas "Kanvas" dihilangkan, untuk secara sederhana, tetapi, akan mirip dengan kelas "SVG".
Kelas "Biasa" dapat direpresentasikan sebagai satu lapisan diagram 3D, kelas "SVG" di lapisan lain, dan kelas "Kanvas", di lapisan ketiga.
Periksa, bahwa setiap lapisan terkait dengan yang pertama, di mana, setiap kelas memiliki kelas induk dari hierarki "Umum".
Implementasi kode mungkin perlu menggunakan salah satu, warisan antarmuka, warisan kelas, atau "mixins", tergantung pada apa yang didukung oleh Bahasa Pemrograman Anda.
Ringkasan
Seperti solusi pemrograman apa pun, jangan terburu-buru ke optimasi, optimasi sangat penting, namun, optimasi yang buruk, dapat menjadi masalah yang lebih besar, daripada masalah aslinya.
Saya tidak merekomendasikan menerapkan "Solusi 1" atau "Solusi 2".
Dalam "Solusi 1" tidak berlaku, karena, warisan, diperlukan dalam setiap kasus.
"Solusi 2", "Mixins" dapat diterapkan, tetapi, setelah mendesain kelas dan hierarki.
Mixins, adalah alternatif untuk pewarisan berbasis antarmuka, atau beberapa pewarisan berbasis kelas.
Usulan saya, Solusi 3, kadang-kadang disebut Pola Desain "Parallel Hierarchy" atau Pola Desain "Dual Hierarchy".
Banyak pengembang / desainer tidak akan setuju dengan itu, dan percaya itu seharusnya tidak ada. Tapi, saya telah menggunakan oleh diri sendiri, dan pengembang lain, sebagai solusi umum untuk masalah, seperti salah satu pertanyaan Anda.
Satu hal lagi yang hilang. Dalam solusi Anda sebelumnya, masalah utama bukanlah lebih baik menggunakan "mixin" atau "interface", tetapi, untuk memperbaiki, pertama, model kelas Anda, dan kemudian menggunakan fitur Bahasa Pemrograman yang ada.