1

さて、私は1つのグラフィックオブジェクトがグループと長方形で拡張される合成パターンを使用しています。グループには多くの長方形を含めることができ、paint()メソッドはグループを呼び出し、長方形でpaintメソッドを呼び出し、各長方形はそれ自体を描画します。

次に、長方形を左側または右側に揃えるために、その上でデコレータパターンを使用する必要があります。ここで、グループでデコレータを使用すると、グループの座標が整列するだけですが、すべての長方形がそれ自体を描画するため、それらには影響しません。

では、ここでデコレータパターンをどのように使用できるかについてのアイデアはありますか?

つまり、これを使用することを考えることができる唯一の方法は、整列する必要があるグループ内のすべての長方形とすべての要素の周りにデコレータラッパーを使用することです。しかし、これはデコレータパターンのポリシーに反しませんか?つまり、グループはリストに何が含まれているかを技術的に知りません。つまり、要素は単なるGraphicObjectインスタンスであり、長方形は、長方形のペイントを呼び出す前に座標を変更するデコレータでラップされていることを知りません。 )メソッド。

それが唯一の方法である場合、それらのアイテムを装飾するためにどのように使用しますか?ここでリフレクションを使用する必要がありますか、それとも他の/より正しい方法がありますか?

いくつかのコード:

if (mainGroup == null) {
        mainGroup = new Group();

        // first line
        currentBounds = convertToBoundsForLine(x, y, width, lineHeight, 1);
        //System.out.format("current bounds: x1=%d, y1=%d, x2=%d, y2=%d%n", currentBounds.getX(), currentBounds.getY(), currentBounds.getX2(), currentBounds.getY2());
        GraphicObject rect1 = new Rectangle(currentBounds);
        mainGroup.addChild(rect1);

        // other lines...

        // fifth line
        currentBounds = convertToBoundsForLine(x, y, width, lineHeight, 5);
        //System.out.format("current bounds: x1=%d, y1=%d, x2=%d, y2=%d%n", currentBounds.getX1(), currentBounds.getY1(), currentBounds.getX2(), currentBounds.getY2());
        GraphicObject rect5 = new Rectangle(currentBounds);

        // this is with the decorator wrapper around - should I use reflection here?
        GraphicObject blabla = new DecoratorLeft(rect5);
        mainGroup.addChild(blabla);

5行目で、グループに追加する前にデコレータ内のどこに長方形を配置しているかがわかります。したがって、反射を使用して、グループに追加されるすべての長方形でそれらを使用する必要があります。それともそれを行うためのより良い方法はありますか?

それとも、ここでのデコレータの使用方法は一般的にまったく間違っていますか?

前もって感謝します。

編集:

グループでのペイントメソッドの実装方法は次のとおりです。

public void draw(Graphics g, AlignStrategy align) {
    for (GraphicObject graphic: children) {
        graphic.draw(g, align);
    }
}

このグループは、子の描画メソッドを呼び出すだけです。

問題は、デコレータは私の意見ではユニバーサルでなければならないということです。あなたが与えた提案によると、それは依存するように思われますか?つまり、グループは基本的に配置に依存していますか?オブジェクトを回転させたり、座標xをyに切り替えたりするデコレータを作成したとしたらどうでしょうか。つまり、左、右、または中央に位置合わせすることではなく、コードをデコレータにあまり適合させなくてもデコレータが機能することです。

4

1 に答える 1

1

コード ビハインドGraphicObjectGroup、などを完全に制御Rectangleできる場合 (つまり、それがすべて自分のコードである場合)、デコレータ パターンを使用するのは難しいと思います。AWT のLayoutアプローチと同様のコードを使用して描画の配置を実装する方が簡単です。親オブジェクト (おそらくあなたの場合は a) には、親の子の配置を管理Groupする単一のオブジェクトが与えられます。Layoutデフォルトのレイアウトは子には影響しません。「左揃え」および「右揃え」レイアウトは、ペイントの前に行われるレイアウト フェーズ中に必要な位置変更を子に行います。GroupLayout

描画オブジェクトの背後にあるコードを制御できない場合は、Groupすべての子を装飾するよりもデコレータを使用する方がうまくいくと思います。-levelGroupデコレーターのpaint()メソッドが呼び出されたときに、子の配置を管理します。このようにして、Groupドローアブル オブジェクトごとに 1 つのデコレータではなく、1 つのデコレータのみを使用できます。これは基本的に、デコレーター クラスに組み込まれたレイアウト コードですが、いつでもレイアウト コードを分割して、デコレーターにそれを呼び出させることができます。

編集:これは2番目のケースの例です。簡単にするために、詳細ではなく、必要な部分のみをリストします。

public class GroupDecorator extends GraphicObject { //or extends whatever is best
    public GroupDecorator(Group wrappedGroup) { 
        myGroup = wrappedGroup;
    }

    public void paint() { //Assume this is your common paint() method
        //note I'm making up the names here, since I don't know them
        List groupsChildren = myGroup.getChildren(); 

        //The type of alignment is stored somewhere in this object
        //or is hard-coded. That's up to you. I'll assume it's stored somewhere...

        if (isAlignedLeft()) { 
          //align all the children to the left here
        } else if (isAlignedRight()){
          //align all the children to the right here
        } else { 
          //do nothing because no alignment is necessary
        }

        //call the wrapped Group's paint now. It will call its children's paint()s.
        myGroup.paint();

        //Unalign all the children here, if necessary, to put them back in 
        //their original state. How you implement that is up to you.
    }

}
// Somewhere in your main code...

    mainGroup = new Group();

    //Decorate mainGroup now...
    GroupDecorator decoratedGroup = new GroupDecorator(mainGroup);
    //Configure decoratedGroup to align however you want.

    // first line
    GraphicObject rect1 = new Rectangle();
    mainGroup.addChild(rect1);

    // other lines...

    // fifth line
    GraphicObject rect5 = new Rectangle();


    //Now use decoratedGroup now in place of mainGroup.
于 2012-09-29T19:53:10.090 に答える