2016-11-30 6 views
6

以下のクラスはシングルトンですか?コンストラクタはpublicとして宣言されているので、クラスが間違った実装を持つシングルトンであると推測できますか?このクラスはシングルトンですか?

public class CreateDevice extends Functionality{ 

    private static Simulator simulator; 
    ConnectionDB connect = ConnectionDB.getInstance(); 


    public CreateDevice(Simulator simulator){ 
    this.simulator = simulator; 
    } 

    private static CreateDevice instance; 
    synchronized public static CreateDevice getInstance() { 
    if(instance == null){ 
     instance = new CreateDevice(simulator); 
    }  
     return instance; 
    } 
} 
+0

クラスをシングルトンにすることはできません。オブジェクトは、1つの種類のオブジェクトである可能性があります。しかし、クラスはインスタンス化を1つのオブジェクトに制限するためにシングルトンパターンを実装することができます:) – zapl

+0

サイドノート: '' CreateDevice' - コンストラクタで初期化された '' simulator''は静的であってはなりません - 静的にしてclassname 'CreateDevice.simulator'または' static'キーワードを削除してください。 (これは実際にシングルトンであるという問題とは関係ありません) – Hulk

+0

あなたは正しいです。これは変更が必要な問題のコードです。 –

答えて

1

シングルトンにすることはできますが、次にシミュレータを注入する別の方法を見つける必要があります。

現在の実装では、誰かがコンストラクタを初めて呼び出すときにシミュレータが設定されます。そのコンストラクタは静的フィールドを設定するので非常に奇妙です。また、シングルトンインスタンスで使用されている接続とは別の接続もすぐに開きます。

コンストラクタが少なくとも1回呼び出される前にgetInstance()メソッドが呼び出された場合、シミュレータは決して設定されません。

これを適切なシングルトンにするには、コンストラクタを削除し、プライベートのno-argsコンストラクタを追加します。また、静的フィールドを設定する静的setSimulator()メソッドが必要です。また、シミュレータとの他の相互作用が必要になる前に呼び出されていることを確認してください。

シングルトン間の依存関係がある場合は、IoCコンテナがサービスオブジェクトを作成してそれらを結ぶInversion-of-Controlパターンを使用することをお勧めします。

+0

あなたは正しいですが、問題は本当のシングルトンに変更する必要があるかどうかです。 –

+0

これを適切なシングルトンに変更すると、現在の状況よりも改善されます。しかし、IoCを使用することはさらに改善されるでしょう。 – greyfairer

7

一言で言えば、コンストラクタはpublicなので、誰でもどこでもいつでも新しいインスタンスを作成できます。コンストラクタprivateを作成して問題を解決し、クラスをシングルトンにする必要があります。

+0

問題はコードが間違っている可能性があり、このクラスがシングルトンである可能性があるということを他のコードから推測しています(その機能は複数のインスタンスを必要としないようにデバイスを作成するだけです)それを実際のシングルトンに変更する必要があります。 –

2

私はあなたが現在の実装ではシングルトンではないと言っても間違いないと言います。

コンストラクタをプライベートにする必要があります(これは通常行われています)。または従来の理由からパブリックコンストラクタが必要な場合は、インスタンスがnullかどうかを確認し、例外をスローするコンストラクタを作成する必要がありますそれがすでに存在する場合、または別のプライベートコンストラクタを呼び出してインスタンスを作成し、インスタンスに割り当てて返します。最初のオプションは、リファクタが高価すぎるほとんどのプロジェクトでうまく動作します。

関連する問題