2016-12-19 4 views
3

プログラム全体(さまざまなクラス)に表示されるオブジェクトを作成する必要があります。そのようなクラスのためにシングルトンを作成したくないのは、私はいくつかのインスタンスが必要な場合があるからです。だから私はコンテナとしてSingleton型のクラスを作成し、その中に私はプログラムのどの時点でも使用できるオブジェクトを作成しました。 以下は、何が起こっているかを見るサンプルコードです。 Containerのインスタンスを参照すると、私はそこで作成された施設に常にアクセスします。私は勉強するプログラムを作っています。大きなものになるだろうが、私は問題の解決策を持っているアイデアを思いついた。問題は、異なるコントローラーが明示的なオブジェクトを必要とすることです。そして、完全なオブジェクトに基づいて計算を実行します。オブジェクトのコンテナとしての型Singletonのクラス

public class Person { 

    String name; 
    String surname; 
    int age; 

    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public String getSurname() { 
     return surname; 
    } 
    public void setSurname(String surname) { 
     this.surname = surname; 
    } 
    public int getAge() { 
     return age; 
    } 
    public void setAge(int age) { 
     this.age = age; 
    } 
    public Person(String name, String surname, int age) { 
     this.name = name; 
     this.surname = surname; 
     this.age = age; 
    } 

    public Person(){  
    } 
} 

public class Container { 

    private Person person1; 
    private Person person2; 

    private static Container singleton = new Container(); 

    public Container() { 
     person1 = new Person(); 
     person2 = new Person(); 
    } 

    public Person getPerson1(){ 
     return person1; 
    } 

    public Person getPerson2(){ 
     return person2; 
    } 


    public static Container getInstance() { 
      return singleton; 
     }  
} 

public class Test { 

    public static void main(String[] args) { 
     Person person; 
     Container singleton = Container.getInstance(); 
     person = singleton.getPerson1(); 

     person.setName("John"); 


     Person personTest1; 
     Container singleton2 = Container.getInstance(); 
     personTest1 = singleton2.getPerson1(); 

     System.out.println(personTest1.getName()); 
    } 
} 

出力:

ジョン

それは最善の解決策ではないかもしれませんが、このような単純かつ迅速なソリューションとして見つかっていません。どう思いますか?

+0

なぜ本当にコンテナが必要なのですか?デフォルトのPersonsを作成するということは、使用するビジネスロジックがないことを意味し、そうであれば工場設計パターンよりも優先されます。 – Rotem

+0

IoC/DIフレームワークを使用しない場合、このソリューションは非常に妥当です。私は 'person1'と' person2'宣言に 'final'を加えて、再割り当てを制限します。 1. 'person1'と' person2'を 'static'フィールドとして宣言し、それらを静的ブロックまたは正しい場所に作成します。2.' getPerson'メソッドを 'static'として宣言します。3.この場合、コンテナインスタンスの作成などを削除できます。 –

+0

コンテナクラスがシングルトンの場合は、プライベートコンストラクタが必要です。 –

答えて

3

Containerあなたの工場はPersonです。これはクライアントによってインスタンス化されるべきではありません。
それ以外の場合、クライアントはperson1person2の複数のバージョンを作成する可能性があります。

Container singleton = Container.getInstance(); 
    Person person = singleton.getPerson1(); 
    person.setName("John"); 


    Container singleton2 = new Container(); 
    Person personTest1 = singleton2.getPerson1(); 
    System.out.println(personTest1.getName()); 

はそれを避けるために、あなたは、コンストラクタをプライベートにする必要があります。

は、このコードを想像してみてください。

public class Container { 

    ... 
    private Container() { 
     person1 = new Person(); 
     person2 = new Person(); 
    } 
    ... 
} 
+0

@Bartek lazyでシングルトンを作成する必要はありません。'private static Container singleton = new Container();' – davidxxx

+0

@programmerJavaPL 'Person'フィールドで静的を使用するかどうかの第2の点を削除しました。それは本当に味の問題です。私が最初に言ったのは本当に重要なことです。シングルトンを破壊しないようにコンストラクタをプライベートにすることです。 – davidxxx

0

ここでは列挙型を使用します。

コードはきれいで、別のオブジェクトを追加するたびにゲッターを作成する必要がないので、より多くのオブジェクトで拡張する方が簡単です。

ボーナスとして、スレッドの安全性、熱心な起動またはコンストラクタの公開について心配する必要はありません。

public enum Container { 
     PERSON1(new Person()), 
     PERSON2(new Person()), 
     PERSON3(new Person()), 
     PERSON4(new Person()), 
     PERSONN(new Person()); 

     private final Person singleton; 

     Container(final Person person) { 
      this.singleton = Objects.requireNonNull(person); 
     } 
     public Person get(){ 
      return singleton; 
     } 
    } 

    public static void main(String[] args) { 
     Person singletonA = Container.PERSON1.get(); 
     singletonA.setName("John"); 
     Person singletonB = Container.PERSON1.get(); 
     System.out.println(singletonB.getName()); 
    } 
関連する問題