Phân cấp song song - một phần giống nhau, một phần khác nhau


12

Có khá nhiều câu hỏi tương tự ngoài kia 1 ,2 ,3 ,4 , nhưng dường như không chính xác trong trường hợp này, cũng như các giải pháp có vẻ tối ưu.

Đây là một câu hỏi OOP chung, giả sử đa hình, thuốc generic và mixin có sẵn. Ngôn ngữ thực tế được sử dụng là OOP Javascript (Bản mô tả), nhưng đó là vấn đề tương tự trong Java hoặc C ++.

Tôi có hệ thống phân cấp lớp song song, đôi khi chia sẻ cùng một hành vi (giao diện và cách thực hiện), nhưng đôi khi mỗi thứ có hành vi 'được bảo vệ' của riêng nó. Minh họa như vậy:

3 hệ thống phân cấp lớp song song, cột giữa hiển thị các phần chung, cột bên trái là phân cấp canvas và cột bên phải hiển thị phân cấp SVG

Điều này chỉ nhằm mục đích minh họa ; nó không phải là sơ đồ lớp thực tế. Để đọc nó:

  • Bất cứ điều gì trong hệ thống phân cấp chung (giữa) được chia sẻ giữa cả hệ thống phân cấp Canvas (trái) và SVG (phải). Bằng cách chia sẻ tôi có nghĩa là cả giao diện và thực hiện.
  • Bất cứ điều gì chỉ trên các cột bên trái hoặc bên phải có nghĩa là một hành vi (phương thức và thành viên) cụ thể cho hệ thống phân cấp đó. Ví dụ:
    • Cả hai cấu trúc phân cấp trái và phải đều sử dụng chính xác các cơ chế xác thực, được hiển thị dưới dạng một phương thức ( Viewee.validate()) trên cấu trúc phân cấp chung.
    • Chỉ phân cấp canvas có một phương thức paint(). Phương pháp này gọi phương pháp sơn trên tất cả trẻ em.
    • Hệ thống phân cấp SVG cần ghi đè addChild()phương thức Composite, nhưng đó không phải là trường hợp với hệ thống phân cấp canvas.
  • Các cấu trúc từ hệ thống phân cấp hai bên không thể trộn lẫn. Một nhà máy đảm bảo rằng.

Giải pháp I - Tease Apart thừa kế

Sự thừa kế Tease Apart của Fowler dường như không thực hiện công việc ở đây, bởi vì có một số khác biệt giữa hai điểm tương đồng.

Giải pháp II - Mixins

Đây là người duy nhất tôi có thể nghĩ đến. Hai hệ thống phân cấp được phát triển riêng biệt, nhưng ở mỗi cấp, các lớp trộn trong lớp chung, không phải là một phần của hệ thống phân cấp lớp. Bỏ qua structuralngã ba, sẽ như thế này:

Ba cột một lần nữa, các cột bên trái và bên phải là hệ thống phân cấp song song, trong đó mỗi lớp cũng vốn có từ một lớp chung.  Các lớp chung không phải là một phần của hệ thống phân cấp

Lưu ý rằng mỗi cột sẽ nằm trong không gian tên riêng của nó, vì vậy tên lớp sẽ không xung đột.

Câu hỏi

Bất cứ ai cũng có thể nhìn thấy lỗi với phương pháp này? Bất cứ ai có thể nghĩ ra một giải pháp tốt hơn?


Phụ lục

Dưới đây là một số mã mẫu làm thế nào để sử dụng nó. Không gian tên svgcó thể được thay thế bằng canvas:

var iView        = document.getElementById( 'view' ),
    iKandinsky   = new svg.Kandinsky(),
    iEpigone     = new svg.Epigone(),
    iTonyBlair   = new svg.TonyBlair( iView, iKandinsky ),
    iLayer       = new svg.Layer(),
    iZoomer      = new svg.Zoomer(),
    iFace        = new svg.Rectangle( new Rect( 20, 20, 100, 60) ),
    iEyeL        = new svg.Rectangle( new Rect( 20, 20, 20, 20) ),
    iEyeR        = new svg.Rectangle( new Rect( 60, 20, 20, 20) );

iKandinsky.setContext( iTonyBlair.canvas.getContext( '2d' ) );
iEpigone.setContext( iTonyBlair.canvas.getContext( '2d' ) );

iFace.addChildren( iEyeL, iEyeR );
iZoomer.setZoom( new Point( 2, 2 ) );
iZoomer.addChild( iFace );
iLayer.addChild( iZoomer );
iTonyBlair.setContent( iLayer );

Về cơ bản, trong các máy khách thời gian chạy soạn thảo phân cấp các thể hiện của các lớp con Viewee; như vậy

Một hình ảnh hiển thị một hệ thống phân cấp của các đối tượng như lớp, trực tràng, thanh cuộn, v.v.

Giả sử tất cả những người xem này là từ hệ thống phân cấp canvas, chúng được hiển thị bằng cách duyệt qua hệ thống phân cấp có thể gọi paint()trên mỗi người xem. Nếu họ đến từ hệ thống phân cấp svg, người xem sẽ biết cách tự thêm vào DOM, nhưng không có paint()giao dịch.



Có thể thử mẫu thiết kế Trang trí đầy đủ tính năng (Erich Gamma et als, Mẫu thiết kế)?
Zon

Một người xem là gì? "Song song" có nghĩa là một danh từ (trái ngược với tính từ) là gì?
Tulains Córdova

Bạn có nhiều di sản?
Tulains Córdova

Các lớp Canvas hoặc SVG có chứa trạng thái hoặc dữ liệu bổ sung không phổ biến không? Làm thế nào để bạn sử dụng các lớp học? Bạn có thể hiển thị một số mã ví dụ cho thấy làm thế nào những nghiên cứu này có thể được sử dụng?
Euphoric

Câu trả lời:


5

Cách tiếp cận thứ hai tách biệt các giao diện tốt hơn, theo nguyên tắc phân tách giao diện.

Tuy nhiên, tôi sẽ thêm một giao diện Paintable.

Tôi cũng sẽ thay đổi một số tên. Không cần tạo nhầm lẫn:

// common

public interface IComposite {
    public void addChild(Composite e);
}

public interface IViewee extends IComposite{
    public void validate();
    public List<IBound> getAbsoluteBouns();
}

public interface IVisual {
    public List<IBound> getBounds();
}

public interface IRec {
}

public interface IPaintable {
    public void paint();
}

// canvas

public interface ICanvasViewee extends IViewee, IPaintable {
}

public interface ICanvasVisual extends IViewee, IVisual {
}

public interface ICanvasRect extends ICanvasVisual, IRec {
}


// SVG

public interface ISVGViewee extends IViewee {
    public void element();
}

public interface ISVGVisual extends IVisual, ISVGViewee {
}

public interface ISVGRect extends ISVGVisual, IRect {
}

Tôi nghĩ rằng Giao diện có thể giúp cho trường hợp này. Tôi muốn biết lý do tại sao câu trả lời của bạn bị từ chối.
umlcat

không phải là downvoter, nhưng giao diện theo cấp số nhân của IMHO không phải là một mô hình tốt
dagnelies

@arnaud "Ý nghĩa của giao diện theo cấp số nhân" là gì?
Tulains Córdova

@ user61852 ... tốt, hãy nói rằng đó là rất nhiều giao diện. "cấp số nhân" thực sự là một thuật ngữ sai, nó giống như "nhân". Theo nghĩa là nếu bạn có nhiều "khía cạnh" (tổng hợp, trực quan, có thể vẽ được ...) và nhiều "yếu tố" hơn (canvas, svg ...), bạn sẽ kết thúc với rất nhiều giao diện.
dagnelies

@arnaud Bạn có một điểm nhưng ít nhất có một thiết kế linh hoạt trước đó và cơn ác mộng kế thừa của OP sẽ được giải quyết khi bạn không cảm thấy bị buộc phải gia hạn. Bạn mở rộng một số lớp nếu bạn muốn và không bị ép buộc bởi một hệ thống phân cấp.
Tulains Córdova

3

Đây là một câu hỏi OOP chung, giả sử đa hình, thuốc generic và mixin có sẵn. Ngôn ngữ thực tế được sử dụng là OOP Javascript (Bản mô tả), nhưng đó là vấn đề tương tự trong Java hoặc C ++.

Điều đó thực sự không đúng chút nào. Bản đánh máy có một lợi thế đáng kể so với Java - cụ thể là, gõ cấu trúc. Bạn có thể làm một cái gì đó tương tự trong C ++ với các mẫu gõ vịt, nhưng nó nỗ lực hơn rất nhiều.

Về cơ bản, xác định các lớp của bạn, nhưng không bận tâm đến việc mở rộng hoặc xác định bất kỳ giao diện nào. Sau đó, chỉ cần xác định giao diện bạn cần và lấy nó làm tham số. Sau đó, các đối tượng có thể khớp với giao diện đó - họ không cần biết để mở rộng trước. Mỗi hàm có thể khai báo chính xác và chỉ các bit mà chúng đưa ra, và trình biên dịch sẽ cho bạn vượt qua nếu loại cuối cùng đáp ứng nó, mặc dù các lớp không thực sự mở rộng các giao diện đó một cách rõ ràng.

Điều này giải phóng bạn khỏi nhu cầu thực sự xác định một hệ thống phân cấp giao diện và xác định các lớp nào sẽ mở rộng giao diện nào.

Chỉ cần định nghĩa từng lớp và quên đi các giao diện - gõ cấu trúc sẽ chăm sóc nó.

Ví dụ:

class SVGViewee {
    validate() { /* stuff */ }
    addChild(svg: SVG) { /* stuff */ }
}
class CanvasViewee {
    validate() { /* stuff */ }
    paint() { /* stuff */ }
}
interface SVG {
    addChild: { (svg: SVG): void };
}
f(viewee: { validate: { (): boolean }; }) {
    viewee.validate();
}
g(svg: SVG) {
    svg.addChild(svg);
}
h(canvas: { paint: { (): void }; }) {
    canvas.paint();
}
f(SVGViewee());
f(CanvasViewee());
g(SVGViewee());
h(CanvasViewee());

Đây là bản đánh máy hoàn toàn hợp pháp. Lưu ý rằng các hàm tiêu thụ không biết hoặc đưa ra một shit duy nhất về các lớp cơ sở hoặc giao diện được sử dụng trong định nghĩa của các lớp.

Không quan trọng nếu các lớp có liên quan hay không bằng thừa kế. Không thành vấn đề nếu họ mở rộng giao diện của bạn. Chỉ cần xác định giao diện là tham số và bạn đã hoàn thành - tất cả các lớp đáp ứng giao diện đó đều được chấp nhận.


Nghe có vẻ hứa hẹn, nhưng tôi không thực sự hiểu đề xuất này (xin lỗi, có thể là quá nhiều sai lệch OOP). Có lẽ bạn có thể chia sẻ một số ví dụ mã? Ví dụ, cả svg.Vieweecanvas.Viewee đều cần một validate()phương thức (việc thực hiện giống hệt nhau cho cả hai); sau đó chỉ có Svg.Viewee cần ghi đè addChild () , trong khi chỉ canvas.Viewee cần paint () (gọi paint () trên tất cả trẻ em - là thành viên của lớp Composite cơ sở ). Vì vậy, tôi không thể thực sự hình dung điều này với kiểu gõ cấu trúc.
Izhaki

Bạn đang xem xét một loạt những điều hoàn toàn không quan trọng trong trường hợp này.
DeadMG

Vì vậy, tôi có lẽ đã không nhận được câu trả lời. Sẽ tốt đẹp nếu bạn xây dựng.
Izhaki

Tôi đã thực hiện một chỉnh sửa. Điểm mấu chốt là các lớp cơ sở hoàn toàn không liên quan và không ai quan tâm đến chúng. Họ chỉ là một chi tiết thực hiện.
DeadMG

1
ĐỒNG Ý. Điều này đang bắt đầu có ý nghĩa. A) Tôi biết gõ vịt là gì. B) Tôi không chắc tại sao các giao diện lại tập trung vào câu trả lời này - phân tích lớp là vì mục đích chia sẻ hành vi chung, bạn có thể bỏ qua các giao diện một cách an toàn ngay bây giờ. C) Nói trong ví dụ của bạn SVGViewee.addChild(), nhưng CanvasVieweecũng cần chính xác tính năng tương tự. Vì vậy, dường như có ý nghĩa với tôi rằng cả hai vốn có từ Composite?
Izhaki

3

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ó.


Cảm ơn câu trả lời rất kỹ lưỡng. Tôi nghĩ rằng tôi hiểu nó ổn, vì vậy hãy để tôi hỏi điều này: canvas.vieweevà tất cả con cháu của nó cần một phương pháp được gọi paint(). Cả lớp và lớp commonđều không svgcần. Nhưng trong giải pháp của bạn, hệ thống phân cấp nằm trong common, không canvashoặc svggiống như trong giải pháp của tôi 2. Vậy chính xác paint()kết thúc như thế nào trong tất cả các lớp con canvas.vieweenếu không có sự kế thừa ở đó?
Izhaki

@Izhaki Xin lỗi nếu có một vài lỗi trong câu trả lời của tôi. Sau đó paint()nên được di chuyển hoặc khai báo trong "canvas :: viewee". Ý tưởng mẫu chung vẫn tồn tại, nhưng một số thành viên có thể được yêu cầu di chuyển hoặc thay đổi.
umlcat

OK, vậy làm thế nào để các lớp con có được nó, nếu không có nguồn gốc từ canvas::viewee?
Izhaki

Bạn đã sử dụng một công cụ để tạo nghệ thuật ascii của bạn? (Tôi không chắc các dấu chấm thực sự giúp đỡ, cho những gì nó có giá trị.)
Aaron trường

1

Trong một bài viết có tiêu đề Các mẫu thiết kế để đối phó với hệ thống phân cấp thừa kế kép trong C ++ , chú Bob đã trình bày một giải pháp có tên là Nấc thang lên thiên đường . Đó là ý định đã nêu:

Mẫu này mô tả mạng lưới các mối quan hệ thừa kế cần thiết khi một hệ thống phân cấp nhất định phải được điều chỉnh, toàn bộ, cho một lớp khác.

Và sơ đồ cung cấp:

Một sơ đồ lớp với hai cấu trúc thừa kế song song, trong đó mỗi lớp bên phải cũng hầu như vốn có từ lớp sinh đôi của nó ở bên trái.  Hệ thống phân cấp bên trái cũng hoàn toàn dựa trên kế thừa ảo

Mặc dù trong giải pháp 2 không có sự kế thừa ảo, nhưng nó rất phù hợp với mô hình Nấc thang lên thiên đường . Do đó, giải pháp 2 có vẻ hợp lý cho vấn đề này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.