跟着项目学设计模式(一):初识单例模式

版权声明:本文为博主原创文章,未经博主允许不得转载。博客地址: https://blog.csdn.net/m0_37057454/article/details/81984676

         跟着项目学设计模式(一):初识单例模式

跟着项目学设计模式(二):简单工厂

跟着项目学设计模式(三):工厂模式

跟着项目学设计模式(四):抽象工厂模式

跟着项目学设计模式(五):简单工厂+单例模式+静态类+延迟加载

TBD


           本文会以一个服务开发人员的视角,和您一起跟着项目学设计模式。

而在项目开始之前,我们的服务开发人员并不是对设计模式一无所知,他认为自己有一定基础,最起码对单例模式是很熟悉的。

单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例,即一个类只有一个对象实例。

单例模式是非常给力的设计模式,也是很多情况下不得不用的设计模式。

双花括号里的内容,需要新手观看,老手揭过:

{{

对web项目来说,单例模式的应用场景是很少见的,网上有些说数据库连接的,我也是醉了,您的网站大概是给一个人用的。还有说统计网站访问量的单例计数器,看了头疼,不知道为什么会有这种需求?正常的不都是每条访问记录都保存下来,然后求总数的么?您用计数器统计次数,大概是因为您的网站代码从不不更新,所以网站也用不重启。

 我在web项目里最长用到单例模式的地方,就是工厂模式的产品类可以用单例模式。这里netcore自带的IOC为例。

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IHistory, HistoryBll>();
}

此时可以保证系统中,HistoryBll(日志业务逻辑层)只有一个实例,所有对日志操作都是一个实例。 也很好的体现了单例模式的优点:只允许创建一个对象,因此节省内存,加快对象访问速度。

EF的DataContext使用using 定义对象的使用范围,即时释放对象,或者用数据槽存起来,这是针对每次请求创建实例的。这两者分别对应这netcore自带的IOC里的services.AddTransient和services.AddScoped。

}}

上面说了这么多,只是为了告诉新手应用场景的问题,防止他们真的把数据库连接做成单例模式,造成不必要的误解。单例模式是非常给力的设计模式,也是很多情况下不得不用的设计模式。

研究单例模式,还是要回过头来看网站计数器或者数据库连接的例子,我觉得这两个例子很恰当,就拿计数器来说:

    public interface ISingleton
    {
        int Count{get;set;} 
        void Add();
    }    

    public class Singleton:ISingleton
    {
         private static Singleton instance;//静态实例
         private static readonly object locker = new object();//锁
         
         private Singleton() {//私有构造函数
             
         }

         public static Singleton GetInstance()//方法,方法中去实例化类.
         {
             if (instance == null)
             {
                 lock(locker)
                 {
                     if (instance == null)
                     {
                         instance = new Singleton();
                     }
                 }
             }
             return instance;
         }
         
         public int Count{get;set;} 
 
         public void Add()
         {
             Count++;
         }
    }

如果不用单例模式,该怎么实现这个功能?

我想过用静态类完全可以用几行代码完成这个功能,而且也是线程安全的,完全符合单例模式的那些优点。

但最大的问题是静态类不能实现接口,这就是最致命的一点,静态类是面向过程的东西。

同样的静态字段无法实现接口成员,所以不光是Singleton这个类,Count属性和Add方法都不能是静态的。

又因为静态方法不能调用非静态的字段,因此只有生成的对象才能调用Add方法,所以单例模式成了必然的选择。

这些当初看似不合实际的例子,恰恰是区分单例模式和静态类的最好教程,而且对有一定基础的人才容易理解,学习的道路本身就是曲折的,进步的同时,关注点也随之改变了。

静态和单例的应用场景是一模一样的,区别是他们一个是面向过程,一个是面向对象。有静态没接口,有接口没静态,单例模式就是,既要实现接口又要用静态的特性,只有单例模式了。

这里是简单工厂中单例模式的应用,还是足够简单明了的:

设计模式——5、简单工厂+单例模式+静态类+延迟加载

附:一段Lazy<T>创建线程安全的单例模式     

 public class Singleton:ISingleton

    {

        public int Count { get; set; }

        private static readonly Lazy<SingletonForLazy> lazy = new Lazy<SingletonForLazy>(() => new SingletonForLazy(),true);

        public static SingletonForLazy GetInstance

        {

            get { return lazy.Value; }

        }

        public void Add()

        {

            Count++;

        }

    }

后面有文章会介绍项目中把单例和简单工厂结合起来使用。


         跟着项目学设计模式(一):初识单例模式

跟着项目学设计模式(二):简单工厂

跟着项目学设计模式(三):工厂模式

跟着项目学设计模式(四):抽象工厂模式

跟着项目学设计模式(五):简单工厂+单例模式+静态类+延迟加载

TBD

猜你喜欢

转载自blog.csdn.net/m0_37057454/article/details/81984676