Tổng quan nhanh
Giải pháp 3: Mẫu thiết kế phần mềm "Phân cấp lớp song song" là bạn của bạn.
Câu trả lời dài
Thiết kế của bạn BẮT ĐẦU QUYỀN. Nó có thể được tối ưu hóa, một số lớp hoặc thành viên có thể bị xóa, nhưng, ý tưởng "phân cấp song song" mà bạn đang áp dụng để giải quyết vấn đề LÀ QUYỀN.
Đã đối phó với cùng một khái niệm nhiều lần, thường là trong hệ thống phân cấp kiểm soát.
Sau một thời gian, tôi đã KẾT THÚC LÀM GIẢI PHÁP CÙNG CÁC NHÀ PHÁT TRIỂN KHÁC, đôi khi được gọi là Mẫu thiết kế "Phân cấp song song" hoặc Mẫu thiết kế "Phân cấp kép".
(1) Bạn đã bao giờ chia một lớp duy nhất thành một hệ thống phân cấp các lớp chưa?
(2) Bạn đã bao giờ chia một lớp duy nhất thành nhiều lớp mà không có hệ thống phân cấp chưa?
Nếu bạn đã áp dụng các giải pháp trước đó, riêng rẽ, thì chúng là một cách để giải quyết một số vấn đề.
Nhưng, điều gì sẽ xảy ra nếu chúng ta kết hợp đồng thời hai giải pháp này?
Kết hợp chúng và, bạn sẽ có được "Mẫu thiết kế" này.
Thực hiện
Bây giờ, hãy áp dụng Mẫu thiết kế phần mềm "Phân cấp lớp song song" cho trường hợp của bạn.
Bạn hiện có 2 hoặc nhiều phân cấp độc lập của các lớp, rất giống nhau, có các liên kết hoặc purpouse tương tự, có các thuộc tính hoặc phương thức tương tự.
Bạn muốn tránh việc có các mã hoặc thành viên trùng lặp ("tính nhất quán"), tuy nhiên, bạn không thể hợp nhất các lớp này trực tiếp thành một lớp duy nhất, do sự khác biệt giữa chúng.
Vì vậy, hệ thống phân cấp của bạn rất giống với hình này, tuy nhiên, có nhiều hơn một:
................................................
...............+----------------+...............
...............| Common:: |...............
...............| Composite |...............
...............+----------------+...............
...............| ... |...............
...............+-------+--------+...............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
...............+-------+--------+...............
...............| Common:: |...............
...............| Viewee |...............
...............+----------------+...............
...............| ... |...............
...............+-------+--------+...............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..| Common:: |........| Common:: |..
..| Visual |........| Structural |..
..+----------------+........+----------------+..
..| ... |........| ... |..
..+----------------+........+----------------+..
................................................
Figure 1
Trong trường hợp này, chưa được chứng nhận, Mẫu thiết kế, HIERARCHIES SIMILAR, ĐƯỢC TĂNG CƯỜNG, VÀO MỘT HIERARCHY, và mỗi lớp chung hoặc chung được mở rộng bằng cách phân lớp.
Lưu ý rằng giải pháp này rất phức tạp, vì bạn đã xử lý một số cấu trúc phân cấp, do đó là một kịch bản phức tạp.
1 Lớp gốc
Trong mỗi hệ thống phân cấp có một lớp "gốc" được chia sẻ.
Trong trường hợp của bạn, có một lớp "Tổng hợp" độc lập, cho mỗi cấu trúc phân cấp, có thể có một số thuộc tính tương tự và một số phương thức tương tự.
Một số thành viên có thể được hợp nhất, một số thành viên đó không thể được hợp nhất.
Vì vậy, những gì một nhà phát triển có thể làm, là tạo một lớp gốc cơ sở và phân lớp trường hợp tương đương cho mỗi cấu trúc phân cấp.
Trong Hình 2, bạn có thể thấy một sơ đồ chỉ dành cho lớp này, trong đó mỗi lớp, giữ cho nó không gian tên.
Các thành viên, được bỏ qua, đến bây giờ.
................................................
...............+-------+--------+...............
...............| Common:: |...............
...............| Composite |...............
...............+----------------+...............
...............| ... |...............
...............+-------+--------+...............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..| Canvas:: |........| SVG:: |..
..| Composite |........| Composite |..
..+----------------+........+----------------+..
..| ... |........| ... |..
..+----------------+........+----------------+..
................................................
Figure 2
Như, bạn có thể lưu ý, mỗi cụm "Tổng hợp" không còn trong một hệ thống phân cấp riêng biệt, mà được hợp nhất thành một hệ thống phân cấp chung hoặc chung.
Sau đó, hãy thêm các thành viên, những thành viên giống nhau, có thể được chuyển đến siêu lớp và những thành viên khác nhau, cho mỗi lớp cơ sở.
Và như bạn đã biết, các phương thức "ảo" hoặc "quá tải" được định nghĩa trong lớp cơ sở, nhưng, được thay thế trong các lớp con. Giống như Hình 3.
................................................
.............+--------------------+.............
.............| Common:: |.............
.............| Composite |.............
.............+--------------------+.............
.............| [+] void AddChild()|.............
.............+---------+----------+.............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..| Canvas:: |........| SVG:: |..
..| Composite |........| Composite |..
..+----------------+........+----------------+..
..| ... |........| ... |..
..+----------------+........+----------------+..
................................................
Figure 3
Lưu ý rằng có thể có một số lớp không có thành viên, và, bạn có thể bị loại bỏ các lớp đó, KHÔNG. Chúng được gọi là "Các lớp rỗng", "Các lớp học" và các tên khác.
2 Các lớp con
Hãy quay trở lại sơ đồ đầu tiên. Mỗi lớp "Tổng hợp", có một lớp con "Người xem", trong mỗi phân cấp.
Quá trình được lặp lại cho mỗi lớp. Lưu ý hơn Hình 4, lớp "Common :: Viewee" xuất phát từ "Common :: Composite", nhưng, để đơn giản, lớp "Common :: Composite" bị bỏ qua, từ sơ đồ.
................................................
.............+--------------------+.............
.............| Common:: |.............
.............| Viewee |.............
.............+--------------------+.............
.............| ... |.............
.............+---------+----------+.............
.......................|........................
.......................^........................
....................../.\.......................
.....................+-+-+......................
.......................|........................
..........+------------+------------+...........
..........|.........................|...........
..+-------+--------+........+-------+--------+..
..| Canvas:: |........| SVG:: |..
..| Viewee |........| Viewee |..
..+----------------+........+----------------+..
..| ... |........| ... |..
..+----------------+........+----------------+..
................................................
Figure 4
Bạn sẽ lưu ý rằng "Canvas :: Viewee" và "SVG :: Viewee", KHÔNG kéo dài hơn từ "Hợp chất" tương ứng của nó, nhưng, từ "Common :: Viewee" thông thường, thay vào đó.
Bạn có thể thêm các thành viên, ngay bây giờ.
......................................................
.........+------------------------------+.............
.........| Common:: |.............
.........| Viewee |.............
.........+------------------------------+.............
.........| [+] bool Validate() |.............
.........| [+] Rect GetAbsoluteBounds() |.............
.........+-------------+----------------+.............
.......................|..............................
.......................^..............................
....................../.\.............................
.....................+-+-+............................
.......................|..............................
..........+------------+----------------+.............
..........|.............................|.............
..+-------+---------+........+----------+----------+..
..| Canvas:: |........| SVG:: |..
..| Viewee |........| Viewee |..
..+-----------------+........+---------------------+..
..| |........| [+] Viewee Element |..
..+-----------------+........+---------------------+..
..| [+] void Paint()|........| [+] void addChild() |..
..+-----------------+........+---------------------+..
......................................................
Figure 5
3 Lặp lại quy trình
Quá trình sẽ tiếp tục, đối với mỗi lớp, "Canvas :: Visual" sẽ không xuất phát từ "Canvas :: Viewee", từ "Commons :: Visual", "Canvas :: Architectural" sẽ không xuất hiện từ "Canvas :: Viewee ", Buit từ" Commons :: Architectural ", v.v.
4 Sơ đồ phân cấp 3D
Bạn sẽ hoàn thành việc sắp xếp một sơ đồ 3D, với một số lớp, lớp trên cùng, có cấu trúc phân cấp "Chung" và các lớp dưới cùng, có mỗi phân cấp bổ sung.
Hệ thống phân cấp lớp độc lập ban đầu của bạn, trong đó một cái gì đó tương tự như thế này (Hình 6):
.................................................
..+-----------------+.......+-----------------+..
..| Common:: |.......| SVG:: |..
..| Composite |.......| Composite |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+--------+--------+.......+--------+--------+..
...........|.........................|...........
...........^.........................^...........
........../.\......................./.\..........
.........+-+-+.....................+-+-+.........
...........|.........................|...........
..+--------+--------+.......+--------+--------+..
..| Common:: |.......| SVG:: |..
..| Viewee |.......| Viewee |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+--------+--------+.......+--------+--------+..
...........|.........................|...........
...........^.........................^...........
........../.\......................./.\..........
.........+-+-+.....................+-+-+.........
...........|.........................|...........
..+--------+--------+.......+--------+--------+..
..| Common:: |.......| SVG:: |..
..| Visual |.......| Visual |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+--------+--------+.......+--------+--------+..
...........|.........................|...........
...........^.........................^...........
........../.\......................./.\..........
.........+-+-+.....................+-+-+.........
...........|.........................|...........
..+--------+--------+.......+--------+--------+..
..| Common:: |.......| SVG:: |..
..| Rect |.......| Rect |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+-----------------+.......+-----------------+..
.................................................
Figure 6
Lưu ý rằng một số lớp bị bỏ qua và toàn bộ hệ thống phân cấp "Canvas" bị bỏ qua.
Hệ thống phân cấp lớp tích hợp cuối cùng có thể giống như thế này:
.................................................
..+-----------------+.../+..+-----------------+..
..| Common:: +--<.+--+ SVG:: |..
..| Composite |...\+..| Composite |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+--------+--------+.......+-----------------+..
...........|.....................................
...........^.....................................
........../.\....................................
.........+-+-+...................................
...........|.....................................
..+--------+--------+.../+..+-----------------+..
..| Common:: +--<.+--+ SVG:: |..
..| Viewee |...\+..| Viewee |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+--------+--------+.......+-----------------+..
...........|.....................................
...........^.....................................
........../.\....................................
.........+-+-+...................................
...........|.....................................
..+--------+--------+.../+..+-----------------+..
..| Common:: +--<.+--+ SVG:: |..
..| Visual |...\+..| Visual |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+--------+--------+.......+-----------------+..
...........|.....................................
...........^.....................................
........../.\....................................
.........+-+-+...................................
...........|.....................................
..+--------+--------+.../+..+-----------------+..
..| Common:: +--<.+--+ SVG:: |..
..| Rect |...\+..| Rect |..
..+-----------------+.......+-----------------+..
..| ... |.......| ... |..
..+-----------------+.......+-----------------+..
.................................................
Figure 7
Lưu ý rằng một số lớp bị bỏ qua và toàn bộ các lớp "Canvas" bị bỏ qua, đơn giản, nhưng sẽ tương tự như các lớp "SVG".
Các lớp "Chung" có thể được biểu diễn dưới dạng một lớp của sơ đồ 3D, các lớp "SVG" trong lớp khác và các lớp "Canvas", trong lớp thứ ba.
Kiểm tra xem mỗi lớp có liên quan đến lớp đầu tiên không, trong đó, mỗi lớp có một lớp cha của hệ thống phân cấp "Chung".
Việc triển khai mã có thể yêu cầu sử dụng, kế thừa giao diện, kế thừa lớp hoặc "mixins", tùy thuộc vào ngôn ngữ lập trình của bạn hỗ trợ gì.
Tóm lược
Như bất kỳ giải pháp lập trình nào, đừng vội vàng tối ưu hóa, tối ưu hóa là rất quan trọng, tuy nhiên, tối ưu hóa xấu, có thể trở thành một vấn đề lớn hơn so với vấn đề ban đầu.
Tôi không khuyên bạn nên áp dụng "Giải pháp 1" hoặc "Giải pháp 2".
Trong "Giải pháp 1" không áp dụng, bởi vì, việc thừa kế, được yêu cầu trong từng trường hợp.
"Giải pháp 2", "Mixins" có thể được áp dụng, nhưng, sau khi thiết kế các lớp và phân cấp.
Mixins, là một thay thế cho kế thừa dựa trên giao diện hoặc nhiều kế thừa dựa trên lớp.
Giải pháp 3 được đề xuất của tôi, đôi khi được gọi là Mẫu thiết kế "Phân cấp song song" hoặc Mẫu thiết kế "Phân cấp kép".
Nhiều nhà phát triển / nhà thiết kế sẽ không đồng ý với nó và tin rằng nó không nên tồn tại. Nhưng, tôi đã sử dụng bởi miself và các nhà phát triển khác, như một giải pháp chung cho các vấn đề, như câu hỏi của bạn.
Một điều còn thiếu Trong các giải pháp trước đây của bạn, vấn đề chính không phải là sử dụng "mixins" hay "giao diện", mà là để tinh chỉnh, trước tiên, mô hình các lớp của bạn và sau đó sử dụng tính năng Ngôn ngữ lập trình hiện có.