【GoFデザインパターン】アプリの基幹となるクラスSingletonパターンを説明

アプリの基幹となるクラスSingletonパターン

今回のデザインパターンは超シンプルです。

Singletonパターンは、インスタンスをたった一つにするパターンです。

これはDBやメーラー接続など基幹となるクラスを生成するときに利用します。

なので、ぜひ理解していきましょう!

目次

コードの例

今回は本当にシンプルなのでコードから見ていきましょう

コードの例は下記になります。

<?php

class Singleton
{
    private static $instance = null;

    private function __construct()
    {
        // インスタンス生成
    }

    /**
     * このクラスの唯一のインスタンスを取得
     *
     * @return self
     */
    public static function getInstance(): self
    {
        if(self::$instance) {
            return self::$instance;
        }

        return self::$instance = new self();
    }
}

または

<?php

class Singleton
{
    private static $instance = new self();

    private function __construct()
    {
        // インスタンス生成
    }

    /**
     * このクラスの唯一のインスタンスを取得
     *
     * @return self
     */
    public static function getInstance(): self
    {
        return self::$instance;
    }
}

内容としては非常にシンプルですよね

コンストラクタはprivateにする。

唯一性を出すために、コンストラクタはprivate関数にします。

そして、インスタンスが存在しないときだけ生成します。


    /**
     * このクラスの唯一のインスタンスを取得
     *
     * @return self
     */
    public static function getInstance(): self
    {
        if(self::$instance) {
            return self::$instance;
        }

        return self::$instance = new self();
    }

これで一度しかインスタンスが生成されずにすみます。

最初はnullなのでnew self()でインスタンスを生成しますが、その後は生成したインスタンスをreturnします。

これでインスタンスの唯一性を維持されます。

使い道は基幹となるクラス

今回のこのパターンの重要な箇所は、使い道です。

どういったときに使うのか?

という話です。

結論、基幹となるクラスに利用します。

  • DB接続ドライバ
  • メーラー接続ドライバ
  • キャッシュ管理
  • スレッドプール管理
  • ソケット制御ドライバ

などです。

これらは複数インスタンスが必要がありません。

何度もDBに接続するのは無駄です。DBに接続するのはたった1回で十分です。あとはその接続の維持すればいい。

こういったときに利用します。

実例:DIコンテナ

Laravelで調べるとDIコンテナで利用されています。

<?php

/*
 * This file is part of SwiftMailer.
 * (c) 2004-2009 Chris Corbyn
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/**
 * Dependency Injection container.
 *
 * @author  Chris Corbyn
 */
class Swift_DependencyContainer
{
    /** Constant for literal value types */
    const TYPE_VALUE = 0x00001;

    /** Constant for new instance types */
    const TYPE_INSTANCE = 0x00010;

    /** Constant for shared instance types */
    const TYPE_SHARED = 0x00100;

    /** Constant for aliases */
    const TYPE_ALIAS = 0x01000;

    /** Constant for arrays */
    const TYPE_ARRAY = 0x10000;

    /** Singleton instance */
    private static $instance = null;

    /** The data container */
    private $store = [];

    /** The current endpoint in the data container */
    private $endPoint;

    /**
     * Constructor should not be used.
     *
     * Use {@link getInstance()} instead.
     */
    public function __construct()
    {
    }

    /**
     * Returns a singleton of the DependencyContainer.
     *
     * @return self
     */
    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new self();
        }

        return self::$instance;
    }

このようにSingletonパターンでDIコンテナを実装されているので、LaravelはDIを簡単に実現できます。

    public array $singletons = [
        ExampleRepository::class => ExampleRepositoryImpl::class,
    ]

この技術は本当にすごいですよね

まとめ

ということで今回はSingletonパターンでした。

DB接続などに利用するため、フレームワークを使わず、自分達で一からアプリを構築する際に必須になります。

1度接続したら、あとはそれを使い回す。

そういった際に利用するパターンでした。

ぎゅう
WEBエンジニア
渋谷でWEBエンジニアとして働く。
LaravelとVue.jsをよく取り扱い、誰でも仕様が伝わるコードを書くことを得意とする。
先輩だろうがプルリクにコメントをして、リファクタしまくる仕様伝わるコード書くマン
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次
閉じる