Tôi cần thiết kế một hệ thống phân cấp lớp cho dự án C # của mình. Về cơ bản, các chức năng của lớp tương tự như các lớp WinForms, vì vậy hãy lấy bộ công cụ WinForms làm ví dụ. (Tuy nhiên, tôi không thể sử dụng WinForms hoặc WPF.)
Có một số tính chất và chức năng cốt lõi mà mỗi lớp cần cung cấp. Kích thước, vị trí, màu sắc, khả năng hiển thị (đúng / sai), phương pháp Vẽ, v.v.
Tôi cần lời khuyên thiết kế Tôi đã sử dụng một thiết kế với lớp cơ sở trừu tượng và các giao diện không thực sự kiểu nhưng giống các hành vi hơn. Đây có phải là một thiết kế tốt? Nếu không, những gì sẽ là một thiết kế tốt hơn.
Mã trông như thế này:
abstract class Control
{
public int Width { get; set; }
public int Height { get; set; }
public int BackColor { get; set; }
public int X { get; set; }
public int Y { get; set; }
public int BorderWidth { get; set; }
public int BorderColor { get; set; }
public bool Visible { get; set; }
public Rectangle ClipRectange { get; protected set; }
abstract public void Draw();
}
Một số Điều khiển có thể chứa các Điều khiển khác, một số Điều khiển chỉ có thể được chứa (khi còn nhỏ) vì vậy tôi đang nghĩ đến việc tạo hai giao diện cho các chức năng này:
interface IChild
{
IContainer Parent { get; set; }
}
internal interface IContainer
{
void AddChild<T>(T child) where T : IChild;
void RemoveChild<T>(T child) where T : IChild;
IChild GetChild(int index);
}
WinForms điều khiển văn bản hiển thị để điều này cũng đi vào giao diện:
interface ITextHolder
{
string Text { get; set; }
int TextPositionX { get; set; }
int TextPositionY { get; set; }
int TextWidth { get; }
int TextHeight { get; }
void DrawText();
}
Một số Điều khiển có thể được neo trong Kiểm soát cha mẹ của chúng vì vậy:
enum Docking
{
None, Left, Right, Top, Bottom, Fill
}
interface IDockable
{
Docking Dock { get; set; }
}
... và bây giờ hãy tạo một số lớp cụ thể:
class Panel : Control, IDockable, IContainer, IChild {}
class Label : Control, IDockable, IChild, ITextHolder {}
class Button : Control, IChild, ITextHolder, IDockable {}
class Window : Control, IContainer, IDockable {}
"Vấn đề" đầu tiên tôi có thể nghĩ đến ở đây là các giao diện về cơ bản được thiết lập một khi chúng được xuất bản. Nhưng hãy giả sử rằng tôi sẽ có thể làm cho giao diện của mình đủ tốt để tránh phải thay đổi chúng trong tương lai.
Một vấn đề khác tôi thấy trong thiết kế này là mọi lớp trong số này sẽ cần phải thực hiện các giao diện và việc sao chép mã sẽ nhanh chóng xảy ra. Ví dụ, trong Nhãn và Nút, phương thức DrawText () xuất phát từ giao diện ITextHolder hoặc trong mọi lớp có nguồn gốc từ quản lý trẻ em IContainer.
Giải pháp của tôi cho vấn đề này là triển khai các chức năng "trùng lặp" này trong các bộ điều hợp chuyên dụng và chuyển tiếp cuộc gọi đến chúng. Vì vậy, cả Nhãn và Nút sẽ có một thành viên TextHolderAd CHƯƠNG sẽ được gọi bên trong các phương thức được kế thừa từ giao diện ITextHolder.
Tôi nghĩ rằng thiết kế này sẽ bảo vệ tôi khỏi phải có nhiều chức năng phổ biến trong lớp cơ sở, thứ có thể nhanh chóng bị phồng lên với các phương thức ảo và "mã nhiễu" không cần thiết. Thay đổi hành vi sẽ được thực hiện bằng cách mở rộng các bộ điều hợp và không phải các lớp có nguồn gốc Kiểm soát.
Tôi nghĩ rằng đây được gọi là mẫu "Chiến lược" và mặc dù có hàng triệu câu hỏi và câu trả lời về chủ đề đó, tôi muốn hỏi bạn ý kiến của bạn về những gì tôi xem xét cho thiết kế này và những sai sót bạn có thể nghĩ đến cách tiếp cận của tôi.
Tôi nên nói thêm rằng có khả năng gần như 100% rằng các yêu cầu trong tương lai sẽ yêu cầu các lớp mới và các chức năng mới.
IChild
có vẻ như một cái tên kinh khủng
System.ComponentModel.Component
hoặcSystem.Windows.Forms.Control
hoặc bất kỳ của các lớp cơ sở khác hiện có? Tại sao bạn cần tạo phân cấp điều khiển của riêng mình và xác định lại tất cả các chức năng này từ đầu?