Eu preciso criar uma hierarquia de classes para o meu projeto c #. Basicamente, as funcionalidades da classe são semelhantes às classes WinForms, portanto, tomemos o kit de ferramentas WinForms como exemplo. (No entanto, não posso usar o WinForms ou o WPF.)
Existem algumas propriedades e funcionalidades essenciais que toda classe precisa fornecer. Dimensões, posição, cor, visibilidade (verdadeiro / falso), método Draw, etc.
Preciso de conselhos de design. Utilizei um design com uma classe base abstrata e interfaces que não são realmente tipos, mas sim comportamentos. Esse é um bom design? Caso contrário, qual seria um design melhor.
O código fica assim:
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();
}
Alguns controles podem conter outros controles, alguns podem ser contidos apenas (como filhos), por isso estou pensando em fazer duas interfaces para essas funcionalidades:
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);
}
Os controles WinForms exibem o texto, então isso também entra na interface:
interface ITextHolder
{
string Text { get; set; }
int TextPositionX { get; set; }
int TextPositionY { get; set; }
int TextWidth { get; }
int TextHeight { get; }
void DrawText();
}
Alguns controles podem ser encaixados dentro do controle pai, portanto:
enum Docking
{
None, Left, Right, Top, Bottom, Fill
}
interface IDockable
{
Docking Dock { get; set; }
}
... e agora vamos criar algumas classes concretas:
class Panel : Control, IDockable, IContainer, IChild {}
class Label : Control, IDockable, IChild, ITextHolder {}
class Button : Control, IChild, ITextHolder, IDockable {}
class Window : Control, IContainer, IDockable {}
O primeiro "problema" em que posso pensar aqui é que as interfaces são basicamente definidas quando são publicadas. Mas vamos supor que poderei tornar minhas interfaces boas o suficiente para evitar a necessidade de fazer alterações nelas no futuro.
Outro problema que vejo neste design é que todas essas classes precisariam implementar suas interfaces e a duplicação de código ocorrerá rapidamente. Por exemplo, em Label e Button, o método DrawText () deriva da interface ITextHolder ou em todas as classes derivadas do gerenciamento de filhos do IContainer.
Minha solução para esse problema é implementar essas funcionalidades "duplicadas" em adaptadores dedicados e encaminhar chamadas para eles. Portanto, Label e Button teriam um membro TextHolderAdapter que seria chamado dentro de métodos herdados da interface ITextHolder.
Eu acho que esse design deve me impedir de ter muitas funcionalidades comuns na classe base, que podem rapidamente ficar inchadas com métodos virtuais e "código de ruído" desnecessário. Alterações de comportamento seriam realizadas estendendo adaptadores e não classes derivadas de controle.
Acho que isso é chamado de padrão "Estratégia" e, embora existam milhões de perguntas e respostas sobre esse tópico, gostaria de pedir suas opiniões sobre o que levo em consideração para esse design e quais falhas você pode encontrar em minha abordagem.
Devo acrescentar que há quase 100% de chance de que requisitos futuros exijam novas classes e novas funcionalidades.
IChild
parece um nome horrível.
System.ComponentModel.Component
ou deSystem.Windows.Forms.Control
qualquer outra classe base existente? Por que você precisa criar sua própria hierarquia de controle e definir todas essas funções novamente do zero?