0

私の質問は少し長いです。私は抽象的なファクトリパターンを学んでいます。

抽象ファクトリの抽象クラスがあります。具体的な工場に必要な「資源」を共有したい。したがって、AbstractFactory内の変数を静的として作成するだけです。

public class AbstractFactory{
    private static Vector vector = new Vector();

    protected Vector void getVector() {
        return vector;
    }

    protected void setVector(Vector v){
        this.vector = v;
    }

    public abstract Circle createCircle();
}

そして、そのサブクラスは次のようになります。

public class ConcreteFactory extends AbstractFactory{
    public ConcreteFactory(){
        super();
    }

    public Circle createCircle(){
        Circle circle = new Circle();
        getVector().add(circle);
        return circle;
    }
}

ただし、静的変数は定数に使用されることが多いため、先生は静的オブジェクトインスタンスを使用すべきではないと言いました。

したがって、Vectorには静的変数の代わりインスタンス変数instanceを使用 し、具象ファクトリをインスタンス化するときに外部からベクトルを渡します。

したがって、私のクラスの新しいデザインは次のようになります。

public class AbstractFactory{
    private Vector vector;

    protected Vector void getVector() {
        return vector;
    }

    protected void setVector(Vector v){
        this.vector = v;
    }

    public abstract Circle createCircle();
}

public class ConcreteFactory extends AbstractFactory{
    public ConcreteFactory(Vector v){
        super();
        setVector(v);
    }

    public Circle createCircle(){
        Circle circle = new Circle();
        getVector().add(circle);
        return circle;
    }
}

**

私の質問は:オブジェクトを共有するために静的変数を使用すべきではないのはなぜですか?

**

具体的なファクトリのインスタンスを作成するときに、Vectorを渡さなくても、具体的なファクトリ間でリソースを共有する方が簡単です。

4

3 に答える 3

2

時には、今日の生活を楽にしていることが、将来の生活をより困難にすることがあります。

いくつかの例: クラスが使用される環境を常に知っているわけではありません。おそらく、ファクトリのさまざまなインスタンスが、さまざまなクラス ローダーによってロードされることになります (これは Web アプリケーションでよく発生します)。そのように静的インスタンス変数を使用すると、完全に予測不可能な動作が発生する可能性があります。ほとんどの場合、静的変数は悪い考えです。

そうは言っても、あなたがクラスで本当にやりたいことはこれだと思います:

public class AbstractFactory{
    private final Vector vector;

    protected AbstractFactory(Vector vector){
        this.vector = vector;
    }

    protected Vector void getVector() {
        return vector;
    }

    public abstract Circle createCircle();
}

public class ConcreteFactory extends AbstractFactory{
    // USE THIS IF YOU NEED TO SHARE THE VECTOR AMONGST MULTIPLE FACTORY INSTANCES
    public ConcreteFactory(Vector vector){
        super(vector);
    }
    // OR USE THIS IF THE VECTOR IS SPECIFIC TO THE FACTORY
    public ConcreteFactory(){
        super(new Vector());
    }    

    public Circle createCircle(){
        Circle circle = new Circle();
        getVector().add(circle);
        return circle;
    }
}

インスタンス変数で final を使用することは、この種のことには良い考えです。これにより、コードの他の場所で変数を誤って変更することがなくなります。しかし、それはオプションです。私が行った重要な変更は、ベクトルを抽象基本クラスのコンストラクターに追加し、それをスーパークラスから渡すことです。

于 2012-11-11T18:05:24.180 に答える
1

static属性は、そのように使用することを意図していません。
statics は、実行時に一度だけ使用できるものです。
あなたの場合、それはあなたから派生したすべてのAbstractFactory工場がこの単一のベクトルを共有することを意味します。

次の例を参照してください。

ConcreteFactory a = new ConcreteFactory();
ConcreteFactory b = new ConcreteFactory();
a.createCircle();
b.createCircle();

両方のオブジェクトは、同じ静的ベクトルを共有するため、ベクトルに 2 つのエントリを持ちますab

また、そう思いますか

protected void setVector(Vector v){
    this.vector = v;
}

vectorはファクトリのインスタンスの属性ではなく、ファクトリ自体の属性である ため、不正です!

それに加えて、それは単に悪い、エラーが発生しやすい (大規模なデバッグを試してください)、単純な醜いコーディング スタイルです。

そこの先生を信頼してください - 彼は正しいです ;)

于 2012-11-11T18:04:34.543 に答える
1

静的な最終変数が定数として使用されることがあるという事実は、サーバーが最適な場所であればどこでも同じメカニズムを使用することを妨げるものではありません (ロガーは私が示すことができる唯一の他の例です)。

ただし、外界に結合する暗黙のコンポーネントがない場合は、常に良いことです。vector を静的変数として定義すると、ファクトリをコンテキストベースにし、互いに独立させることができなくなります。ベクターをファクトリの引数にする場合、ベクターを共有するファクトリと共有しないファクトリを定義するのは、ファクトリの作成者 (現在は通常、Spring コンテキスト ローダー) 次第です。

あなたのケースでベクトルを引数として渡すもう1つの理由は、単体テストの側面に関連しています。クラスが外部からベクトルを取得するように設計されている場合は、それをモックして、クラスをより徹底的にテストできます。

于 2012-11-11T18:17:24.390 に答える