1

私のプロジェクトにはポリモーフィズム構造があり、それを書き換えて使用する価値があるかどうかを考えていますVisitor Pattern

基本的な構造は次のとおりです。いくつかの描画オブジェクトがあります(Rectangle, Ellipse, Lineが、もちろんいくつかの動作が共通しています。動作はインターフェイスによって定義されますDrawable。これまでのところ、ドラッグは常に同じように動作するはずですが、選択したものを描画すると異なるはずです。

abstract Figureそのため、既に を実装しているが、 の実装を拡張クラスにdrag()委譲するクラスを導入しました。drawSelected()

もちろん、インターフェイスは後で必要な機能を追加して拡張され、Figure の追加の実装も行われる予定です。

ここで私の質問: このデザインに固執するか、に切り替えるかVisitor。もしそうなら、なぜですか?特に、現在のアプローチが、オブジェクト自体の内部で選択を描画するためのロジック/アルゴリズムを持つのに適しているかどうかはわかりません。

interface Drawable {
    void drag();
    void drawSelected();
}


abstract class Figure implements Drawable {
    protected int x, y, w, h;

    @Override
    void drag() {
        //implementation always the same for different figures
    }
}


class Rectangle extends Figure {
    @Override
    drawSelected() {
        //draw a dashed rectangle around this object
    }
}

class Ellipse extends Figure {
    @Override
    drawSelected() {
        //draw a dashed ellipse around this object
    }
}

class Line extends Figure {
    @Override
    drawSelected() {
        //draw the line itself dashed
    }
}
4

4 に答える 4

3

あなたが抱えている問題は、時間の経過とともに変化する可能性が低いオブジェクト構造を使用する必要があります。追加される可能性のある新しい構造 (図) が存在する可能性がありますが、特定のオブジェクト構造 (図) が変更される可能性は低いです。構造は変わらないかもしれませんが、構造にさらに多くの操作を追加することができ、これらの操作は構造全体で共通する場合とそうでない場合があります。Visitorこれらのことは、パターンを使用するためのユースケースになると思います。

さらに詳しく説明するために、図の 1 つのグループに対して 1 つの実装が必要であり、別のグループに対して別の実装が必要な新しい操作を追加するシナリオを考えてみましょう。現在の設計では、抽象クラスで共通の実装を 1 つしか持つことができず ( を使用しない限りinstanceOf、しかし、これも良い習慣とは見なされません)、他の各クラスでその実装をオーバーライドする必要があります。パターンを使用する場合と同様に、 (実行時にバインドされる) メソッドVisitorを常に呼び出し、visitその中でどの実装を呼び出すかを決定できます。

現在の設計では、異なるクラスに共通のロジックが存在する状況に到達する可能性もあります。ただし、Visitorパターンでは、さまざまな実装を訪問者クラス内で維持し、それらを訪問メソッドで再利用できるため、コードの重複はありません。

Visitorパターンを使用すると、必要に応じて、特定の Figure をある実装から別の実装に簡単に切り替えることもできます。

新しいクラスを追加する際には、ビジター インターフェイスに新しい実装を追加する必要がありますが、既存のクラス (フィギュア) やその実装には影響しません。

于 2013-03-16T14:00:02.443 に答える
1

[...] Figure の追加実装も予定されています

この理由だけでも、訪問者パターンはシナリオには適していないと思います。新しいクラスを階層に追加するたびに、ビジター インターフェイスとそのすべての実装を変更する必要があります。ビジターは、階層が安定していて、新しいビジターの実装を作成するだけで簡単に動作を追加できる場合に適しています。

別の方法として、非環式ビジターを見てください。しかし、これらのパターンの使用についてよく考えてみてください。設計が必要以上に複雑になる可能性があります。

于 2013-03-16T13:33:26.980 に答える
1

GoF からのパターンの使用法を見ると、Visitorあなたのケースでそのパターンを使用するのは不適切なようです。

用途

  • オブジェクト構造には、異なるインターフェイスを持つオブジェクトのクラスが多数含まれており、具象クラスに依存するこれらのオブジェクトに対して操作を実行したい場合。
  • オブジェクト構造内のオブジェクトに対して、多くの別個の無関係な操作を実行する必要があり、これらの操作でクラスを「汚染」することを避けたい場合。Visitor を使用すると、関連する操作を 1 つのクラスに定義することでまとめて保持できます。オブジェクト構造が多くのアプリケーションで共有されている場合は、Visitor を使用して、操作を必要とするアプリケーションだけに操作を配置します。
  • オブジェクト構造を定義するクラスが変更されることはめったにありませんが、構造に対する新しい操作を定義したい場合がよくあります。オブジェクト構造クラスを変更するには、すべての訪問者へのインターフェースを再定義する必要があり、コストがかかる可能性があります。オブジェクト構造クラスが頻繁に変更される場合は、それらのクラスで操作を定義することをお勧めします。
于 2013-03-16T13:10:55.010 に答える