2012-07-03 35 views
8

Tôi có cấu trúc cây thể loại/tệp. Cả hai loại và tệp đều có thể có cha mẹ, vì vậy tôi bắt nguồn từ một lớp cơ sở chung có thuộc tính Gốc. Vì tất cả các bậc cha mẹ rõ ràng sẽ luôn là các loại (các tệp không thể là cha mẹ), có vẻ như có ý nghĩa để làm cho thuộc tính Gốc của nút là loại CategoryNode.Có phải biểu mẫu không đúng để chỉ một loại có nguồn gốc trong một loại cơ sở không?

Biểu mẫu xấu cho lớp cơ sở có đề cập đến lớp dẫn xuất không? Nếu vậy, tại sao? Cách tốt hơn để cấu trúc cái này là gì?

class Node { 
    public CategoryNode Parent {get; set;} 
} 

class File : Node { 
    ... 
} 

class CategoryNode : Node { 
    ... 
} 
+0

AFAIU, cả hai đều mở rộng cùng một lớp cơ sở để chia sẻ các thuộc tính, vậy tại sao không sử dụng trên lớp đơn lẻ có tham chiếu đệ quy cho chính nó? với các thuộc tính bổ sung để phân biệt chúng. –

+0

yes thats bad. Gây phụ thuộc vòng tròn. Cơ sở không nên biết gì về Derived. – Tilak

+0

@Furqan, nút Tệp không cần thêm nội dung mà CategoryNode có, chẳng hạn như trẻ em, vì vậy tôi không nghĩ rằng nó sẽ lấy được từ CategoryNode. – Kelsie

Trả lời

4

Nếu thuộc tính Parentthực sự là thuộc tính chung của tất cả các hậu duệ và luôn luôn là loại CategoryNode, nó không phải là vấn đề. Về mặt ngữ nghĩa nói nó đúng và về mặt kỹ thuật, tôi nghĩ rằng nó chính xác quá sớm khi bạn vẫn còn trong cùng một thư viện (để tránh tham khảo vòng tròn).

Đây có thể là một vấn đề khi bạn viết mã như thế này:

// BAD CODE 
if(myProp is subclassA) 
{ ... 
} 
else if (myProp is syubclassB) 
{ ... 
} 

Mã này là xấu, bởi vì bạn mất lợi thế của việc thừa kế.

Ngay cả trong .Net Framework cũng có cấu trúc như vậy. Ví dụ đầu tiên xuất hiện trong tâm trí của tôi là thuộc tính XObject.Parent.

XElement kế thừa XObject và XObject xuất bản thuộc tính kiểu XElement. Giống như đoạn mã của bạn.

1

Lớp cơ sở không được biết ai xuất phát từ nó.

Nếu bạn có trường hợp như vậy, có thể bạn không muốn kế thừa. Bạn chỉ nên sử dụng một số hình thức khớp nối.

Tệp và danh mục phải giữ thành viên nút trong trường hợp của bạn.

+0

Tôi không thể đồng ý với bạn. Điều gì về nếu phụ huynh luôn luôn là một CategoryNode? Nó có thể là một vấn đề trong lớp cơ sở có những thứ như 'if (myProp là subclassA) {...} else if (myProper là syubclassB) {...}'. Những thứ như vậy là bẩn. Nhưng không phải mẫu OP cho thấy –

+0

Nhưng nó không phải. chúng ta chỉ thấy rằng cha mẹ có thể là File, mà không có cách nào liên quan đến CategoryNode. –

+0

OP cho biết rằng 'các tệp không thể là cha mẹ' –

1

Các tùy chọn khác sẽ là thay đổi thứ bậc lớp để làm cho CategoryNode thành lớp gốc (a) hoặc thay đổi loại thuộc tính thành Nút (b).

Cả hai khả năng này đều không tốt: (a) Tệp sẽ có tất cả chức năng CategoryNode mà nó không cần. (b) Nó sẽ ẩn loại đối tượng (luôn luôn là CategoryNode). Điều này có thể xảy ra với các lỗi truyền không hợp lệ ở một nơi khác trong mã của bạn. Ví dụ, nếu bạn quên luôn luôn có một thể loại CategoryNode.

Xem xét điều này, tôi tin rằng mã hiện tại là OK.

7

Bạn có thể làm ...

interface IParent { 
    ... 
} 

class Node { 
    public IParent Parent {get; set;} 
} 

class File : Node { 
    ... 
} 

class CategoryNode : Node, IParent { 
    ... 
} 

Bằng cách này, bạn không cần phải đề cập đến một đối tượng có nguồn gốc trong lớp cơ sở, cộng thêm, bạn linh hoạt hơn trong những gì thực sự có thể trở thành cha mẹ , trong trường hợp bạn nhận được các loại đối tượng bổ sung tại một thời điểm sau đó. Ngoài ra, bất kỳ chức năng nào có liên quan chỉ dành cho cha/mẹ đều có thể được khai báo trong giao diện đó.

+0

Có thể bạn có thể thêm vào giao diện: 'IEnumerable ChildNodes'? –

+0

@Steve Đây là một câu hỏi thiết kế. Chắc chắn là có thể, nhưng sau đó tôi sẽ không gọi giao diện 'IParent' nữa. OP muốn tham chiếu đến một đối tượng cha, và không cho một (các) đối tượng con của (danh sách). Đối với tôi, có vẻ như có một số thứ giống như đã được khai báo là 'IEnumerable Children', và cá nhân tôi sẽ đổi tên giao diện thành một cái gì đó phù hợp hơn ... nếu bạn có một dự án lớn với nhiều ví dụ về kiểu đặt tên đó, bạn đang trên đường đến địa ngục IMHO ... – takrl

+0

bạn đúng ... điều này có thể dẫn đến sự nhầm lẫn –

Các vấn đề liên quan