Singletonって何ですか？

## 目次
- どんな方向けに作られているか
- デザインパターンとは
- Singletonとは
- 実際にはどうやって書くの？
- 解説
- 終わりに
- 参考にさせていただいたもの

## どんな方向けに作られているか
この記事は「デザインパターンなんて知らないよ」という方向けに作っております。
筆者もデザインパターンは名前ぐらいしか知りません。

## デザインパターンとは
そもそもデザインパターンとは何なのでしょうか？

[TECHSCORE様](https://www.techscore.com/tech/DesignPattern/foundation/foundation1#dp0-2)に書かれている「デザインパターンとは」の箇所を引用してきました。

> オブジェクト指向言語で開発を行う際に、再利用性の高いクラスやライブラリが重要になることは分かりました。では、どのような設計にしておけば、再利用性が高いクラスやライブラリができるのでしょう。これに対する指針を示してくれるのが1995年に出版された「オブジェクト指向における再利用のためのデザインパターン」という本(通称「GoF本」)です。デザインパターンが広く認知されるきっかけとなったこの本では、オブジェクト指向で再利用性の高い設計とするためのパターンを23個抽出しています。

これをかみ砕いて説明すると、以下のようになります。
- オブジェクト指向で開発するときによく出てくる問題はあらかじめルールを決めて対処しよう

そのルールを定義しているのが、デザインパターンなのです。
次の章からタイトルになっているSingletonと呼ばれるデザインパターンを見ていきます。


## Singletonとは

### インスタンスを一つしか作成したくない時に使えるデザインパターン

Singletonパターンを利用することで、1~2のようなことが実現できます。
1. 指定したインスタンスが一つしかないことを想定したい。
2. インスタンスが一つしか存在しないことをプログラムで表示する時に表現したいもの

これだけではわかりにくいのでコードで実際に見ていきます。


## 実際にはどうやって書くの？
今から3つのファイルと1つの実行結果をお見せします。を見ていきます。
コードの解説は最後に行います。
環境はJava 14を使用します。

```:Main.java
public class Main {

    public static void main(String[] args) {
        //Singletonパターンを利用した場合
        SingletonServiceImpl  singletonService1 = SingletonServiceImpl.getInstance();
        SingletonServiceImpl  singletonService2 = SingletonServiceImpl.getInstance();

        //Singletonパターンを使用しない場合
        InstanceServiceImpl instanceService1 = new InstanceServiceImpl();
        InstanceServiceImpl instanceService2 = new InstanceServiceImpl();

        if(singletonService1 == singletonService2) {
            System.out.println("シングルトンで作成されたインスタンスは一致します。");
        } else {
            System.out.println("シングルトンで作成されたインスタンスは一致しません。");
        }

        if(instanceService1 == instanceService2) {
            System.out.println("Newで作成されたインスタンスは一致します。");
        } else {
            System.out.println("Newで作成されたインスタンスは一致しません。");
        }

    }

}

```

```:SingletonServiceImpl.java
public class SingletonServiceImpl implements SingletonService {

    //サービスクラス内でNewを行う・・・➁
    private static SingletonServiceImpl service = new SingletonServiceImpl();

    //コンストラクタをPrivateクラスにしてNew SingletonServiceImpl()を実行できないようにする・・・➀
    private SingletonServiceImpl() {};

    //代わりに、外部クラスからでも呼び出せるようにstaticのgetInstance関数を作成・・・➂
    public static SingletonServiceImpl getInstance() {
        return service;
    }

    @Override
    public String getTest() {
        return "Test";
    }

}

```

```:InstanceServiceImpl.java
public class InstanceServiceImpl implements InstanceService {

    @Override
    public String getTest() {
        return "Test";
    }

}

```

```:実行結果
シングルトンで作成されたインスタンスは一致します。
Newで作成されたインスタンスは一致しません。
```

見ていただいたのが簡単ではありますが、Singletonデザインパターンを採用したコードになります。

## 解説

SingletonServiceImpl.javaの解説
1. ➀のコードのようにSingletonServiceImplのコンストラクタをprivateにします。
→privateにすることで他のクラスでnew SingletonServiceImpl()を出来ないようにする。
2. ➁のコードでフィールド変数にNew SingletonServiceImpl()を行い、インスタンスを作成する。
3. ➁で作成したフィールド変数をgetできるstaticなgetInstance関数を定義する。
→➂を定義することで、すでに作成されているインスタンスを呼び出せるようにする。



出力結果からもわかるようにSingletonで作成されているインスタンスは一致しますが、
Newで作成されたインスタンスは一致していないことがわかります。

この結果から下記1~2を実現したい時に使えるデザインパターンであることが分かったと思います。
1. 指定したインスタンスが一つしかないことを想定したい。
2. インスタンスが一つしか存在しないことをプログラムで表示する時に表現したいもの


## 終わりに
最後まで読んでいただき、ありがとうございます。
今回は簡単にSingletonとは書かせていただきました。
Singletonはマルチスレッドを意識して書く際には少し難しくなります。
それについてはまた別記事で書くことになるかと思います。

至らない点や修正が必要な場合はコメントなどで教えていただければ幸いです。

## 参考にさせていただいたもの
[TECHSCORE様](https://www.techscore.com/tech/DesignPattern/foundation/foundation1)
Java言語で学ぶデザインパターン入門 著:結城　浩様