• C#面向对象设计模式纵横谈:Singleton


     

    模式分类:

    1. 目的分类

    创建型(creatinal)

    机构型(structural):类与对象间的组合,避免继承的耦合

    行为型(behavioral):类与对象交互中的职责分配,组件间的交互,隔离变化

    2. 范围分类

    类模式处理类与子类的静态关系

    对象模式处理对象间的动态关系

    单件模式:

    1.动机(tivation)

    在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。

    如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?

    这应该是类设计者的责任,而不是使用者的责任

       2.意图(Intent)保证一个类仅有一个实例,并提供一个该实例的全局访问点

        ——《设计模式》GOF

    3. 结构



    4. 单线程Singleton模式的几个要点

    Singleton模式中的实例构造器可以设置为protected以允许子类派生。

    Singleton模式一般不要支持ICloneable接口,因为这可能会导致多个对象实例,与Singleton模式的初衷违背。

    Singleton模式一般不要支持序列化,因为这也有可能导致多个对象实例,同样与Singleton模式的初衷违背。

    Singletom模式只考虑到了对象创建的管理,没有考虑对象销毁的管理。就支持垃圾回收的平台和对象的开销来讲,我们一般没有必要对其销毁进行特殊的管理。

    不能应对多线程环境:在多线程环境下,如直接使用传统Singleton模式仍然有可能得到Singleton类的多个实例对象
    单线程Code:

    class ServeChannel
        {
            private static ServeChannel FInstance;
            private ServeChannel() { }
            public static ServeChannel Instance//如果有参数时,则不能用属性而应改为函数
            {
                get {
                    if (FInstance == null) {//此实现导致无法多线程
                        FInstance = new ServeChannel();
                    }
                    return FInstance;
                }
            }
        }
    test{
      
    ServeChannel t = ServeChannel.Instance;
    }

    多线程Code:1。传统实现,C#下实现

    class ServeChannel
        {
            private static volatile ServeChannel FInstance; //不允许编译器对实现代码顺序微调
            private static object FLocker = new object();
            private ServeChannel() { }
            public static ServeChannel Instance
            {
                get {
                    if (FInstance == null) {
                        lock (FLocker)
                        {

                            if (FInstance == null)
                                FInstance = new ServeChannel();
                        }
                    }
                    return FInstance;
                }
            }
        }
    test{
      
    ServeChannel t = ServeChannel.Instance;
    }

    这是比较传统的方案而下面的是C#中很经典的的实现,它利用静态构成函数的特点将代码简化,缺点是不支持构造时传参数,但一般的应用中是可以满足的,有人建议在构造后加一个初始化的函数,我认为不会,这方式不是通用的习惯,新手加入是很容易漏掉。

    class ServeChannel
        {
            public static readonly ServeChannel Instance = new ServeChannel();
            private ServeChannel() { }
        }

    此实现相当于:

    class ServeChannel
        {
            public static readonly ServeChannel Instance;

            static ServeChannel()//保证了多线程安全

            {

               Instance = new ServeChannel();

            }       

            private ServeChannel() { }
        }

  • 相关阅读:
    bzoj 1853: [Scoi2010]幸运数字 容斥
    bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树
    bzoj 2331: [SCOI2011]地板 插头DP
    bzoj 3669: [Noi2014]魔法森林 动态树
    bzoj 2734: [HNOI2012]集合选数 状压DP
    bzoj 3751: [NOIP2014]解方程 同余系枚举
    bzoj 2594: [Wc2006]水管局长数据加强版 动态树
    bzoj 2049: [Sdoi2008]Cave 洞穴勘测 动态树
    bzoj 2209: [Jsoi2011]括号序列 splay
    bzoj 1223: [HNOI2002]Kathy函数 数位DP 高精度
  • 原文地址:https://www.cnblogs.com/xiachong/p/1070775.html
Copyright © 2020-2023  润新知