C#プロジェクトのクラス階層を設計する必要があります。基本的に、クラスの機能はWinFormsクラスに似ているため、WinFormsツールキットを例に取りましょう。(ただし、WinFormsやWPFは使用できません。)
すべてのクラスが提供する必要があるいくつかのコアプロパティと機能があります。寸法、位置、色、可視性(true / false)、Drawメソッドなど。
設計上のアドバイスが必要です。抽象ベースクラスと実際には型ではなく、動作に似たインターフェイスを持つ設計を使用しました。これは良いデザインですか?そうでない場合、より良いデザインになります。
コードは次のようになります。
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();
}
一部のコントロールには他のコントロールを含めることができ、一部は(子として)のみ含めることができるため、これらの機能のために2つのインターフェイスを作成することを考えています。
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とButtonのDrawText()メソッドは、ITextHolderインターフェイスから派生するか、子のIContainer管理から派生したすべてのクラスで派生します。
この問題に対する私の解決策は、専用アダプターにこの「重複した」機能を実装し、呼び出しをそれらに転送することです。したがって、LabelとButtonの両方に、ITextHolderインターフェイスから継承されたメソッド内で呼び出されるTextHolderAdapterメンバーがあります。
この設計は、仮想メソッドと不必要な「ノイズコード」ですぐに肥大化する可能性のある基本クラスの多くの一般的な機能を持たないようにする必要があると思います。動作の変更は、Control派生クラスではなくアダプターを拡張することで実現されます。
これは「戦略」パターンと呼ばれ、そのトピックに関する数百万の質問と回答がありますが、この設計で考慮すべきことと考えられる欠陥について意見を求めたいと思います。私のアプローチ。
将来の要件で新しいクラスと新しい機能が必要になる可能性がほぼ100%あることを付け加えます。
IChild
恐ろしい名前のようです。
System.ComponentModel.Component
またはSystem.Windows.Forms.Control
他の既存の基本クラスから単純に継承しないのですか?独自のコントロール階層を作成し、これらすべての機能をゼロから再度定義する必要があるのはなぜですか?