4

Tool という名前の 1 つの基本クラスを持ついくつかのクラスがあります。フォームには、言及されたクラスのインスタンスの 1 つを含む 1 つのツール参照があります。フォームで MouseDown イベントが発生すると、現在のツール メソッドを呼び出します。"CurrentTool.MethodWhenMouseDown()".

ほとんどのツールには 3 つの方法があります。

MethodWhenMouseDown()
MethodWhenMouseUp()
MethodWhenMouseMove()

しかし、1つまたは2つのクラスには次のものがあります。

MethodWhenMouseDown()

今どちらが良いですか:

1. Tool に 3 つのメソッドすべてとそれらを必要としないクラスを含めるには、空のメソッドを呼び出すだけです。

2.インターフェースを実装するには MouseMove イベントが発生したときに動作する必要があるクラスによってのみ実装される IMouseMoveListener。このようにして、MouseMove イベントが発生した場合、次のように尋ねます。

if(CurrentTool is MouseMoveListener)
{
(CurrentTool as IMouseMoveListener).MethodWhenMouseMove();
}

追加情報:
プログラムは Ms Paint のようなものです - ツールはブラシ、バケット (MethodWhenMouseMove を必要としないもの)、LineTool など
です。イベントを発生させるのは、pictureBox です。

ツールがサブスクライブするイベントを検討しましたか? – CodesInChaos

イベントが発生し、そのメソッドが CurrentTool の siutable メソッドを呼び出した後に呼び出される形式のメソッドを用意することをお勧めします。元:

void MouseMoveSubscriber(object sender, MouseEventArgs e)
{
CurrentTool.MethodWhenMouseMove(e);
}

CurrentTool が変更されるたびに CurrentTool のメソッドをサブスクライブおよびサブスクライブ解除するのは悪い習慣だと思いますか?
また、すべてのツール参照を Form に含めることも考えました。イベントは各ツールによってサブスクライブされ、サブスクライブを解除する必要はありません。私の意見では、大きな欠点は、各ツールが CurrentTool であるかどうかを確認する必要があることです。
あなたはそれについてどう思いますか?助けてくれてありがとう。

4

3 に答える 3

2

パフォーマンスは問題ではありません (ユーザーがクリックしたとき、空の関数を不必要に呼び出すオーバーヘッドは重要ではありません)。したがって、これは実際にはコーディングの容易さとコードの明瞭さ/複雑さ/保守性に関するものです。

だから私はそれをできるだけシンプルに保ちます。

これはクリーンでシンプルなので、空の実装で基本クラスを実装します。必要な結果を得るには、派生クラスに最小限のコードが必要です。それも理にかなっています (クリックアップコールをオーバーライドしない場合、本質的に「マウスがクリックされたとき、私はそれについて何もしたくない」と言っています)。

次のオプションは、マウスのアップ/ダウン/クリックのイベントを提供し、必要に応じて派生クラスにイベントをサブスクライブさせることです。イベントを使用するのは標準的なパターンですが、見苦しいサブスクリプションとアンサブスクリプションの呼び出しをいじる必要があるという欠点があります。これの利点は、それらを公開すると、派生クラスだけでなく、誰でもこれらのイベントを処理できることです。

インターフェイスとキャストの使用は避けたいと思います - 私にはこれは不格好なアプローチのように感じます - 実際に達成されるのは、単純な 3 つの仮想メソッドのセットではなく、さまざまなタイプにまたがる「空の関数」アプローチを断片化することだけです。そして、単にメソッドを呼び出してそれらが機能することを知る代わりに、最初に多くの型キャストとチェックを行う必要があります。

編集 質問にさらに追加したので、もう一度読み直しましたが、別の可能性が思い浮かびました。すべての派生クラスがオーバーライドする必要がある仮想 MouseDown ハンドラーを提供する基本ツール クラスを作成します。すべての通常のツールはこれから派生します。

追加の DragTool クラスは、特別な 2 つのドラッグ ツールに必要な MouseMove および MouseUp ハンドラーを追加する中間クラスとして派生できます。

すなわち

ToolBase (abstract MouseDown)
  |
  +- ClickTool1
  +- ClickTool2
  +- DragToolBase (abstract MouseMove + MouseUp)
      |
      +- DragTool1
      +- DragTool2

これは、どのツールにも空の実装がないことを意味します。

于 2012-08-31T12:46:57.360 に答える
1

あなたのシナリオを知らなくても、インターフェイスと基本クラスの組み合わせを使用します
。基本クラスは、すべてのインターフェイスを空の仮想メソッドで実装します。基本クラスは純粋な便利な構造です。ツール クラスが基本クラスから継承したいが、メソッドを必要としない場合は、それをオーバーライドしません。

ツールを使用するコードでは、インターフェイスのみを使用します。このように、他のクラスは自由にインターフェースを直接実装できます。このように、犠牲を払うことなく最大限の柔軟性を得ることができます。

var mouseMoveListener = CurrentTool as IMouseMoveListener;
var mouseDownListener = CurrentTool as IMouseDownListener;
// ...

if(mouseMoveListener != null)
    mouseMoveListener.MethodWhenMouseMove();
if(mouseDownListener != null)
    mouseDownListener.MethodWhenMouseDown();

注意: との組み合わせではasなく、代わりにのみ使用しました。isas

于 2012-08-31T12:28:58.353 に答える
0

実際のケースによります。しかし、あなたの特定のケース (UI イベント) では、空のハンドラー (仮想メソッド) を持つ基本クラスを持つことは、多くのインターフェイスよりも優れていると思います。実際、すべてのツールは ToolBase から継承されます。また、呼び出しコードは、インターフェイスにキャストすることなく、より小さくシンプルになります。

于 2012-08-31T12:41:58.213 に答える