単利モードの長所と短所と使用シーン


詳細
単利モードの長所と短所と使用シーン
まず、単一のパターンについて説明します.
    単例モード(Singleton)は、単子モードとも呼ばれ、よく使われるソフトウェア設計モードである.このモードを適用する場合、単一のオブジェクトのクラスは、1つのインスタンスのみが存在することを保証する必要があります.多くの場合、システム全体が1つのグローバルオブジェクトを持つだけで、システム全体の動作を調整するのに役立ちます.たとえば、あるサーバ・プログラムでは、サーバの構成情報がファイルに格納され、これらの構成データは1つのインスタンス・オブジェクトによって統一的に読み出され、サービス・プロセス内の他のオブジェクトは、このインスタンス・オブジェクトによってこれらの構成情報を取得します.この方法により、複雑な環境での構成管理が簡素化されます.
単一のモデルを実現するための考え方は、次のとおりです.
    1つのクラスは、オブジェクトの参照(常に同じ)とインスタンスを取得する方法(通常getInstanceという名前を使用する静的メソッドでなければならない)を返すことができます.このメソッドを呼び出すと、クラスが保持する参照が空でない場合、この参照が返され、クラスが保持する参照が空である場合、クラスのインスタンスが作成され、インスタンスの参照がクラスが保持する参照に与えられます.また、クラスのコンストラクション関数をプライベートメソッドとして定義すると、他のコードはクラスのコンストラクション関数を呼び出してクラスのオブジェクトをインスタンス化することができず、クラスが提供する静的メソッドのみでクラスの唯一のインスタンスを得ることができます.
注意すべき点:
    単一のモードは、マルチスレッドの適用の場合に注意して使用する必要があります.ユニークなインスタンスがまだ作成されていない場合、2つのスレッドが同時に作成メソッドを呼び出すと、ユニークなインスタンスの存在が検出されず、それぞれ1つのインスタンスが作成され、2つのインスタンスが構築され、単一のインスタンスモードでのインスタンスのユニークな原則に違反します.この問題を解決する方法は、クラスがインスタンス化されたかどうかを示す変数に反発ロックを提供することである(これは効率を低下させるが).
メリット:
    1.単一インスタンスモードでは、アクティブな単一インスタンスは1つのインスタンスのみであり、単一インスタンスクラスのすべてのインスタンス化に対して同じインスタンスが得られる.これで
他のオブジェクトがインスタンス化されないようにし、すべてのオブジェクトがインスタンスにアクセスできるようにします.
    2.単例モードは一定の伸縮性を有し、クラス自身がインスタンス化プロセスを制御し、クラスはインスタンス化プロセスを変更する上で相応の伸縮性を有する.
    3.一意のインスタンスへの管理されたアクセスを提供します.
    4.システムメモリにオブジェクトが1つしか存在しないため、
システム資源を節約し、
頻繁にオブジェクトを作成および破棄する必要がある場合、単一のモードはシステムのパフォーマンスを向上させるに違いありません.
    5.可変数のインスタンスを許可します.
    6.共有リソースの多重占有を避ける.
欠点:
    1.変更されたオブジェクトには適用されません.同じタイプのオブジェクトが常に異なるインスタンスシーンで変更されると、単一のインスタンスではデータのエラーが発生し、互いの状態を保存できません.
    2.単利モードには抽象層がないため,単例クラスの拡張が困難である.
    3.単例類の職責が重すぎて、ある程度「単一職責原則」に背いている.
    4.単一インスタンスを悪用すると、リソースを節約するためにデータベース接続プールオブジェクトを設計した単一インスタンスクラスのような負の問題が発生し、接続プールオブジェクトを共有するプログラムが多すぎて接続プールがオーバーフローする可能性があります.インスタンス化されたオブジェクトが長時間利用されない場合、システムはゴミとして回収され、オブジェクトの状態が失われます.
使用上の注意事項:
    1.反射モードで単一のインスタンスを作成することはできません.そうしないと、新しいオブジェクトがインスタンス化されます.
    2.怠け者モードを使用する際のスレッドセキュリティの問題に注意
    3.空腹単例モードと怠け者単例モードの構造方法はいずれも私有であるため継承できず、一部の単例モードは継承できる(例えば登録式モード)
適用シーン:
    シングル・インスタンス・モードでは、1つのオブジェクトのみを作成できます.したがって、メモリを節約し、オブジェクトへのアクセスを高速化するため、複数のモジュールが同じデータ・ソースを使用してオブジェクトを接続するなど、オブジェクトが共通の場合に適している必要があります.次のようになります.
    1.頻繁にインスタンス化して破棄するオブジェクト.
    2.オブジェクトの作成に時間がかかりすぎたり、リソースがかかりすぎたりしますが、よく使用されるオブジェクトです.
    3.ステータスのあるツールクラスオブジェクト.
    4.データベースまたはファイルに頻繁にアクセスするオブジェクト.
以下は、単例モードの一般的な使用シーンです.
    1.資源共有の場合、資源操作による性能や損失などを避ける.上記のログファイルのように、構成を適用します.
    2.制御リソースの場合、リソース間の相互通信を容易にする.スレッドプールなどです.
適用シーンの例:
    1.外部リソース:各コンピュータには複数のプリンタがありますが、PrinterSpoolerは1つしかありません.2つの印刷ジョブが同時にプリンタに出力されないようにします.内部リソース:ほとんどのソフトウェアには、1つ(または複数)のプロパティファイルがシステム構成を格納しています.このようなシステムには、オブジェクトがこれらのプロパティファイルを管理する必要があります.
    2.WindowsのTask Manager(タスクマネージャ)は典型的な単例モード(これはよく知っているでしょう)ですが、考えてみてください.windows task managerを2つ開けてもらえますか.信じないなら自分でやってみろよ~
    3.windowsのRecycle Bin(ごみ箱)も典型的な単例応用である.システム全体の稼働中、ごみ箱はわずかなインスタンスを維持しています.
    4.ウェブサイトのカウンタは、一般的には単例モードで実現され、そうでないと同期しにくい.
    5.アプリケーションのログアプリケーションは、一般的には単例モードで実装されます.これは、共有されたログファイルが常に開いているためです.1つのインスタンスしか操作できないため、コンテンツが追加されにくいためです.
    6.Webアプリケーションのコンフィギュレーションオブジェクトの読み取りは、コンフィギュレーションファイルが共有リソースであるため、一般的には単一のモードも適用される.
    7.データベース接続プールの設計は、データベース接続がデータベースリソースであるため、一般的には単一のモードを採用します.データベース・ソフトウェア・システムでは、主にデータベース接続プールを使用して、データベース接続を開いたり閉じたりすることによる効率損失を節約します.この効率的な損失は、単一のモードで維持することで、この損失を大幅に低減することができます.
    8.マルチスレッドのスレッドプールの設計も一般的に単例モードを採用している.これは、スレッドプールがプール内のスレッドを制御するのに便利であるからである.
    9.オペレーティングシステムのファイルシステムは、大きな単例モード実現の具体例でもあり、1つのオペレーティングシステムには1つのファイルシステムしかない.
    10.HttpApplicationも単位例の典型的な応用である.ASP.Net(IIS)の要求ライフサイクル全体を熟知している人は、HttpApplicationも単一のモードであり、すべてのHttpModuleがHttpApplicationのインスタンスを共有していることを知っているはずだ.
  
単利モデルを実現する原則と過程:
    1.単一のモード:クラスが1つのインスタンスしかないことを確認し、自分でインスタンス化し、システムにこのインスタンスを提供する
    2.単例モード分類:空腹単例モード(クラスロード時に1つのオブジェクトを自分の参照にインスタンス化)、怠け者単例モード(getInstanceのような取得インスタンスを呼び出す方法でオブジェクトをインスタンス化する)(java中空腹単例モードの性能は怠け者単例モードより優れ、c++では一般的に怠け者単例モードを使用する)
    3.単一モード要素:
        a.私有構造方法
        b.プライベート静的参照が自分のインスタンスを指す
        c.自己インスタンスを戻り値とする公有静的メソッド
1.餓漢式:一例のインスタンスはクラスのロード時に構築され、急いで初期化される.(プリロード法)
/**
*    (  )
*
*/
public class Test {
        private Test() {
        }
        public static Test instance = new Test();
        public Test getInstance() {
                return instance;
        }
}

メリット
    1.スレッドセキュリティ
    2.クラスをロードしながら静的オブジェクトを作成し、呼び出すと反応速度が速い
欠点
    リソース効率が高くなく、getInstance()は永遠に実行されないかもしれませんが、クラスの他の静的メソッドを実行したり、クラス(class.forName)をロードしたりすると、このインスタンスは初期化されます.
2.怠け者:単一のインスタンスは、最初に使用されたときに構築され、初期化が遅延します.
class Test {
        private Test() {
        }
        public static Test instance = null;
        public static Test getInstance() {
                if (instance == null) {
              //      instance  null ,   new             
                        instance = new Singleton2();
                }
                return instance;
        }
}

メリット:
    餓漢的な使用なしで事例を作成することを回避し,資源利用率が高くgetInstance()を実行しないとインスタンスされず,このクラスの他の静的手法を実行することができる.
欠点:
    怠け者は単一スレッドでは問題ありませんが、複数のスレッドの同僚がアクセスすると、同僚が複数のインスタンスを作成する可能性があります.また、この複数のインスタンスは同じオブジェクトではありません.後で作成したインスタンスは、先に作成したインスタンスを上書きしますが、異なるオブジェクトを取得する場合があります.この問題を解決する方法はsynchonizedをロックすることです.最初のロードでは速くありません.,マルチスレッドでは不要な同期を使用するとオーバーヘッドが大きい.
3.二重検査
class Test {
        private Test() {
        }
        public static Test instance = null;

        public static Test getInstance() {
                if (instance == null) {
                        synchronized (Test.class) {
                                if (instance == null) {
                                        instance = new Test();
                                }
                        }
                }
                return instance;
        }
}

メリット
    リソース使用率が高く、getInstance()を実行しないとインスタンスされず、このクラスの他の静的メソッドを実行できます.
欠点
    最初のロードで反応が悪く、javaメモリモデルのいくつかの理由でたまに失敗します.
4.静的内部クラス
class Test {
        private Test() {
        }

        private static class SingletonHelp {
                static Test instance = new Test();
        }

        public static Test getInstance() {
                return SingletonHelp.instance;
        }
}

メリット
    リソース使用率が高く、getInstance()を実行せずにインスタンスを実行せず、このクラスの他の静的メソッドを実行できます.
欠点
    1回目のロードで反応が速くない
まとめ:
    一般的に餓漢式を採用し、資源が非常に気になる場合は静的内部類を採用することができ、怠け者式と二重検査を採用することは提案されていない.
    転載は出典を明記してください.http://renyuan-1991.iteye.com/blogs/2246557
    プログラミングが好きな仲間がこのグループを加えて、お互いに助け合って、一緒に勉強することを望んでいます.グループ番号:141877583