Мені потрібно розробити ієрархію класів для мого проекту C #. В основному, функції класу схожі на класи WinForms, тому давайте візьмемо інструментарій WinForms як приклад. (Однак я не можу використовувати WinForms або WPF.)
Є деякі основні властивості та функції, які повинен надати кожен клас. Розміри, положення, колір, видимість (справжня / хибна), метод малювання тощо.
Мені потрібні поради щодо дизайну. Я використав дизайн з абстрактним базовим класом та інтерфейсами, які насправді не типи, але більше схожі на поведінку. Це хороший дизайн? Якщо ні, то який би кращий дизайн.
Код виглядає так:
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();
}
Деякі елементи управління можуть містити інші елементи керування, деякі можуть міститись лише (як діти), тому я думаю створити два інтерфейси для цих функцій:
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 керує відображенням тексту, і це також переходить в інтерфейс:
interface ITextHolder
{
string Text { get; set; }
int TextPositionX { get; set; }
int TextPositionY { get; set; }
int TextWidth { get; }
int TextHeight { get; }
void DrawText();
}
Деякі елементи керування можуть бути приєднані до їх батьківського контролю, щоб:
enum Docking
{
None, Left, Right, Top, Bottom, Fill
}
interface IDockable
{
Docking Dock { get; set; }
}
... а тепер давайте створимо кілька конкретних занять:
class Panel : Control, IDockable, IContainer, IChild {}
class Label : Control, IDockable, IChild, ITextHolder {}
class Button : Control, IChild, ITextHolder, IDockable {}
class Window : Control, IContainer, IDockable {}
Перша «проблема», яку я можу тут придумати, - це те, що інтерфейси в основному встановлюються в камені, як тільки вони публікуються. Але припустимо, що я зможу зробити свої інтерфейси досить хорошими, щоб уникнути необхідності вносити зміни до них у майбутньому.
Ще одна проблема, яку я бачу в цій конструкції, полягає в тому, що кожному з цих класів потрібно буде реалізувати свої інтерфейси, і дублювання коду швидко відбудеться. Наприклад, у Label and Button метод DrawText () походить від інтерфейсу ITextHolder або від кожного класу, що походить від управління дітьми IContainer.
Моє рішення цього питання полягає в реалізації цих «дублюваних» функцій у виділених адаптерах та переадресації дзвінків до них. Отже, і Label, і Button матимуть член TextHolderAdapter, який буде викликаний всередині методів, успадкованих від інтерфейсу ITextHolder.
Я думаю, що ця конструкція повинна захищати мене від безлічі загальних функціональних можливостей базового класу, які можуть швидко роздутись віртуальними методами та непотрібним "шумовим кодом". Зміни поведінки будуть досягнуті за допомогою розширення адаптерів, а не класів, що походять від контролю.
Я думаю, що це називається "стратегія", і хоча на цю тему є мільйони запитань і відповідей, я хотів би попросити ваших думок щодо того, що я беру до уваги під цим дизайном і які вади ви можете думати. мій підхід.
Додам, що є майже 100% шанс, що майбутні вимоги вимагатимуть нових класів та нових функціональних можливостей.
IChild
здається жахливим ім'ям.
System.ComponentModel.Component
або відSystem.Windows.Forms.Control
будь-якого з інших існуючих базових класів? Чому вам потрібно створити власну ієрархію управління та знову визначити всі ці функції з нуля?