web-dev-qa-db-ja.com

ファクトリーJava具象オブジェクトが異なるコンストラクターパラメーターを取る場合

JavaでFactoryパターンを実装しようとしています。 CircleとTriangleが拡張するShapeというクラスがあります。問題は、Shapeコンストラクターが2つのパラメーターのみを取得し、Circleが3つのパラメーターを取得するため、Triangleも同じであるということです(Circleと同一であるため、コードセクションには表示しません)。より適切にデモンストレーションするには:

    private interface ShapeFactory{
        public Shape create(int x, int y);
    }

    private class CircleFactory implements ShapeFactory{
        public Shape create(float radius, int x, int y){ //error
            return new Circle(radius, x,y);
        }
    }

この問題を克服する方法はありますか?工場内のユーザーからの入力を受信して​​はいけません(外部から受信する必要があります)。

ありがとう!

47
Jjang

次の2つのオプションがあります。

1) 抽象ファクトリー

RectangularShape extends Shape

RoundShape extends Shape

およびRectangularShapeFactoryおよびRoundShapeFactory

2) Builder (Effective JavaのItem 2も参照)

public Shape {
    private final int x;
    private final int y;
    private final double radius;

    private Shape(Builder builder) {
        x = builder.x;
        y = builder.y;
        radius = builder.radius;
    }

    public static class Builder {
        private final int x;
        private final int y;
        private double radius;

        public Builder(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public Builder radius(double radius) {
            this.radius = radius;
            return this;
        }

        public Shape build() {
            return new Shape(this);
        }    
    }
}

//in client code 

    Shape rectangle = new Shape.Builder(x,y).build();
    Shape circle = new Shape.Builder(x,y).radius(radiusValue).build();
31
m3th0dman

あなたがやろうとしていることは、単に不可能です。コンストラクタの引数が異なる場合、クライアントコードはCircleに対してSquareと異なる作業を行う必要があり、統一コードではこれを解決できません。ファクトリーで発生するはずのコンストラクター引数を処理する以外にファクトリーが実行している他の作業がある場合は、これを質問に投稿し、この一般的なコード作業をファクタリングするのが難しいことを述べる必要があります。

8
djechlin

すべての実装は同じ数の引数を取る必要があり、3つのオプションがあります。

  • ファクトリーに追加の引数を保存して、たとえばセンターのみを提供する必要があるようにします。
  • いくつかの工場はそれらのいくつかを無視するかもしれませんが、工場にすべての引数を取ります。
  • 引数は可変長です。例えば「ダブル...」これに関する問題は、呼び出し元がファクトリーの目的を無効にするファクトリーが必要とするものを知る必要があることです。私見では。
6
Peter Lawrey