2

Shape基本クラスを拡張するオブジェクトがいくつかあります。オブジェクトごとに、異なるオブジェクトを表示したいと思いますeditor。たとえば、aLineは編集するプロパティが。とは異なりますRectangle

class Shape;
class Line extends Shape;
class Rectangle extends Shape;

List<Shape> shapes;

void onEditEvent(Shape shape) {
    new ShapeEditorPopup(shape);
    //how to avoid instanceof checks here
}

のすべての実装に対して、Shape単一のEditor実装のみがあります。ここで使用できるパターンは次のとおりです。図形の実装タイプ(instanceof)に従って、図形に適切なエディターを表示しますか?

Shapes私は(ドメインモデル)自身に正しいエディタがどれであるかを知られたくありません。

StrategyPatternonEditEvent()形状がどの実装であるかを知る必要があり、それに応じて戦略を渡す必要があるため、ここでは使用できません。

VisitorPatternShapesある種のinterface Visitable実装でメソッドの実装を強制するため、ここでは使用できません。edit(IEditorVisitor)これにより、UIでの表示方法に関する情報でドメインモデルが汚染されます。

ここで他に何ができますか?

アップデート:

ビジターパターンへの移行方法の例(ただし、メソッドなどでドメインモデルを「汚染」する必要があるため、これは好きではありませんedit(editor)。これは避けたいと思います。

interface Editable {
    public void edit(IEditor editor);
}

public interface IEditor {
    public void edit(Shape shape);
}


class Line extends Shape implements Editable {  
    @Override
    public void edit(IEditor editor) {
        editor.edit(this);
    }
}

class EditorImpl implements IEditor {
    void edit(Line line) {
        //show the line editor
    }
    void edit(Rectangle rect) {
        //shwo the rectangle editor
    }
}
4

1 に答える 1

3

ここではVisitorPatternを使用できません。これは、Shapesに何らかのインターフェイスVisitableを実装させて、edit(IEditorVisitor)メソッドを実装するように強制するためです。これにより、ドメインモデルがUIでの表示方法に関する情報で汚染されます。

いいえ、ドメインモデルに表示または編集方法に関する情報を提供する必要はありません。訪問したことをドメインモデルに知らせるだけで済みます。

ビジターインターフェイスIEditorVisitorに名前を付けたり、IVisitableメソッドに名前を付けたりしないでくださいedit

訪問者はこの種の問題に非常に適しています。

私はそれをもっと次のようにします:

public interface IVisitableShape {
    void accept(IShapeVisitor v);
}

public interface IShapeVisitor {
    void visit(Line line);
    void visit(Rectangle rectangle);
}

public class Line extends Shape implements IVisitableShape {

    @Override
    public void accept(IShapeVisitor v) {
        v.visit(this);
    }
}

public class EditorImpl implements IShapeVisitor {
    public void visit(Line line) {
        //show the line editor
    }
    public void visit(Rectangle rect) {
        //show the rectangle editor
    }
}

これは基本的に実装スケッチと同等であり、名前を変更するだけなので、編集機能はエディターのみにあることに注意してください。

関数名acceptvisitは、このパターンの説明で一般的に使用され、パターンを反映しています。もちろん変更することもできますが、その必要性はわかりません。編集機能に明示的に結び付けられないようにする方が確かに良いでしょう。

于 2013-03-16T16:34:12.373 に答える