Android設計モード(一)——単例モード

7160 ワード

このブログの内容は私がノートを勉強するために、「Androidソースデザインモデル解析と実戦」(何紅輝、愛民著)から抜粋したものです.
  • 定義
  • 使用シーン
  • 単例モードを実現するいくつかのキー
  • 単例モードの実現方式
  • 推奨方式
  • その他の方法

  • メリットとデメリット
  • の利点
  • 欠点



  • 定義#テイギ#
    ≪単一モード|Single Mode|emdw≫:クラスに1つのインスタンスしかなく、独自にインスタンス化され、システム全体にこのインスタンスが提供されていることを確認します.
    シーンの操作
    クラスに1つのオブジェクトしかないシーンがあることを確認し、複数のオブジェクトがリソースを消費しすぎたり、あるタイプのオブジェクトが1つしかないことを回避します.たとえば、IOやデータベースなどのリソースにアクセスするなど、オブジェクトを作成するのに消費されるリソースが多すぎる場合は、単一のスキーマの使用を考慮します.
    シングル・インスタンス・モードを実現するいくつかのキー
  • 構造関数は対外開放されず、一般的にprivateである.
  • は、静的方法または列挙によって単一のクラスオブジェクトを返す.
  • は、単一のクラスのオブジェクトが1つしかなく、特にマルチスレッド環境であることを保証する.
  • は、単一のクラスオブジェクトが逆シーケンス化時にオブジェクトを再構築しないことを保証します.
  • 以下で説明する前の3つの方法において、逆シーケンス化されたときに単一のオブジェクトがオブジェクトを再生成することを防止するには、この方法を追加する必要がある:
  • .
     private Object readResolve() throws ObjectStreamException {
        return sInstance;
     }

    シングルモードの実現方式
    推奨方法
  • Double Check Lock(DCL)実装単例
  • public class Singleton {
        private static Singleton sInstance = null;
        private Singleton() {
        }
        public void doSomething() {
            System.out.println("do sth.");
        }
        public static Singleton getInstance() {
            if (sInstance == null) {
                synchronized (Singleton.class) {
                    if (sInstance == null) {
                        sInstance = new Singleton();
                    }
                }
            }
            return sInstance;
        }
    }

    利点:リソースの使用率が高く、getInstanceが初めて実行されると、単一のオブジェクトがインスタンス化され、効率が高くなります.欠点:最初のロード時に反応がやや遅く、Javaメモリモデルのせいでたまに失敗し、高同時環境でも一定の欠陥がある(確率は小さいが).
  • 静的内部クラス単一モード
  • public class Singleton {
        private Singleton() {
        }
        public static Singleton getInstance() {
            return SingletonHolder.sInstance;
        }
    
        /**
        *     
        */
        private static class SingletonHolder {
            private static final Singleton sInstance = new Singleton();
        }
    }

    利点:SingletonのgetInstanceメソッドを最初に呼び出す場合にのみsInstanceが初期化され、getInstanceメソッドを最初に呼び出すと、SingletonHolderクラスが仮想マシンにロードされ、スレッドのセキュリティを確保するだけでなく、単一のオブジェクトの一意性を保証し、単一のインスタンス化を遅らせることができます.
    その他の方法
  • 怠け者モード(一般的には推奨されていない)
  • public class Singleton {
        private static Singleton sInstance;
        private Singleton() {
        }
        public static synchronized Singleton getInstance() {
            if (sInstance == null) {
                sInstance = new Singleton();
            }
            return sInstance;
        }
    }

    利点:使用時のみインスタンス化され、リソースをある程度節約できます.欠点:最初のロード時にタイムリーにインスタンス化する必要があり、反応がやや遅く、最大の問題はgetInstanceを呼び出すたびに同期し、不要な同期オーバーヘッドをもたらすことです.
  • 列挙単例
  • public enum Singleton {
        INSTANCE;
        public void doSomething() {
            System.out.println("do sth.");
        }
    }

    利点:書き方が簡単で、最も重要なのはデフォルトの列挙インスタンスの作成がスレッドで安全であり、いずれの場合も単一の例であることです.
  • コンテナを用いて、一例のモード
  • を実現する.
    public class SingletonManager {
        private static Map objMap = new HashMap();
        private SingletonManager() {}
        public static void registerService(String key, Object instance) {
            if (!objMap.containsKey(key)) {
                objMap.put(key, instance);
            }
        }
        public static Object getService(String key) {
            return objMap.get(key);
        }
    }

    利点:この方法により、複数のタイプの単一の例を管理することができ、使用時に統一されたインタフェースで操作を取得することができ、ユーザーの使用コストを低減し、ユーザーに具体的な実装を隠すことができ、結合度を低減することができます.
    メリットとデメリット
    メリット
  • シングル・インスタンス・モードはメモリに1つのインスタンスしかないため、メモリ・コストが削減されます.特に、オブジェクトが頻繁に作成、破棄される必要がある場合、作成または破棄時にパフォーマンスが最適化されないため、シングル・インスタンス・モードの利点は明らかです.
  • 単例モードでは1つのインスタンスしか生成されないため、システムのパフォーマンスオーバーヘッドを低減し、1つのオブジェクトの生成に比較的多くのリソースが必要な場合、構成の読み取り、他の依存オブジェクトの生成など、アプリケーションの起動時に直接単例対象を生成し、永続的にメモリを保持する方法で解決することができる.
  • 単一のモードは、メモリに1つのインスタンスしか存在しないため、同じリソースファイルに対する同時書き込みを回避するため、リソースの多重占有を回避することができる.
  • 単一モードは、システムにグローバルなアクセスポイントを設定し、リソースアクセスを最適化および共有することができ、例えば、すべてのデータテーブルのマッピング処理を担当する単一クラスを設計することができる.

  • 欠点
  • 単例モードは一般的に言い訳がなく、拡張が困難であり、拡張するには、コードを修正する以外に基本的に2つ目の方法が実現できない.
  • シングル・インスタンス・オブジェクトがContextを持っている場合、メモリの漏洩が発生しやすくなります.この場合、シングル・インスタンス・オブジェクトに渡されるContextはApplication Contextが望ましいことに注意してください.