2

これは、「問題が発生している」というよりも、スタイルに関する質問です。ヌルプレースホルダーオブジェクトの場合(私は正しい用語を使用していますか?)、一般的にシングルトンパターンを使用することが好ましいですか?説明を簡単にするために、次に例を示します。

public interface Foo {
    void myMethod();
}

public class RealFoo implements Foo {
    void myMethod() { /* Do something productive */ }
}

public class MyUniverse {
    public static void main(String args[]) {
        Foo[] fooArray = new Foo[10];
        // do something productive that might result in Null objects in the array
        for (Foo f : fooArray) {
            f.myMethod(); // I DONT WANT TO DO if (f != null) blah blah
        }
    }
}

さて、それが私のシナリオです。AとBのどちらを実行するのが好ましいですか?

// A
public class NullFoo implements Foo {
    public NullFoo() {}       
    public void myMethod() { /* don't need to do anything */ }
}

// B
public class NullFoo implements Foo {
    private static NullFoo _instance = null;
    protected NullFoo() {}
    public static NullFoo getInstance() {
        if (_instance == null) _instance = new NullFoo();
        return _instance;
    }
    public void myMethod() {  /* don't need to do anything */ }
}

ありがとう!Bはほとんどの場合優れているという私の本能ですが、何かが足りないかもしれないので、私は尋ねます...

4

5 に答える 5

3

私は後者に行きます。私はこれに関してトレンドバッカーのようなものかもしれませんが、シングルトンを本質的に悪とは見ていません。クラスに可変状態がない場合は、シングルトンで問題ありません。

ただし、コンストラクターはプライベートにしますが、保護されていません。また、遅延読み込みは人種が発生しやすいです。宣言行(private static final Foo instance = new NullFoo();)でNullFooをインスタンス化するだけです。そして最後に、クラスに実際にインターフェースを実装させることを忘れないでください。:)

于 2012-10-23T14:58:47.513 に答える
1

仮想マシンの観点からは、Javaが最大で1つのオブジェクトをインスタンス化するため、Bソリューションの方が優れています。

于 2012-10-23T15:02:07.657 に答える
0

まあ、面白い。私がこれに直面したことがあるとは言えませんが...

インスタンスを一貫して使用する場合(つまり、常に同じことを行う場合)は、Bを使用することをお勧めします。そうすると、nullオブジェクトを表す共有インスタンスが1つだけになります。これは、スペースを節約する最適化です(メモリを乱雑にするのではなく、NullFoos。とほとんど同じCollections#emptyListです。

ただし、dsignに関しては、//配列内にNullオブジェクトが含まれる可能性のある生産的な処理を実行して、Fooを取り込んfooArrayでnullに置き換える理由がわかりません。でもあなたには理由があると思います。

于 2012-10-23T15:05:15.753 に答える
-1

ここではインターフェースを使うべきではないと思います。インターフェイスは、それを実装するクラスがサポートする必要のある一連の操作を記述します。ただし、基本的にその要件を回避するためにNullFooクラスを使用しています。

では、myMethodの実装で何もしない基本クラスを使用しないのはなぜですか。

public class BaseFoo
{
    public void myMethod()
    {
        // do nothing
    }
}

public class DerivedFoo extends BaseFoo
{
    public void myMethod()
    {
        // do actual work
    }
}

または、実際の状況でインターフェイスが必要な場合は、先に進んでif (foo != null) ...テストを記述してください。

于 2012-10-23T15:05:54.007 に答える
-1

シングルトンを列挙型として実装します。

enum NullFoo implements Foo{
  INSTANCE{
    // implement methods here
  }
}

参照:シングルトン>列挙型ウェイまたは項目3:JoshuaBlochによるEffectiveJava2ndEd
のプライベートコンストラクターまたは列挙型
を使用してシングルトンプロパティを適用する

于 2012-10-23T15:02:54.903 に答える