跟着项目学设计模式(一):初识单例模式
跟着项目学设计模式(二):简单工厂
跟着项目学设计模式(三):工厂模式
跟着项目学设计模式(四):抽象工厂模式
跟着项目学设计模式(五):简单工厂+单例模式+静态类+延迟加载
TBD
本文会以一个服务开发人员的视角,和您一起跟着项目学设计模式。
而在项目开始之前,我们的服务开发人员并不是对设计模式一无所知,他认为自己有一定基础,最起码对单例模式是很熟悉的。
单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例,即一个类只有一个对象实例。
单例模式是非常给力的设计模式,也是很多情况下不得不用的设计模式。
双花括号里的内容,需要新手观看,老手揭过:
{{
对web项目来说,单例模式的应用场景是很少见的,网上有些说数据库连接的,我也是醉了,您的网站大概是给一个人用的。还有说统计网站访问量的单例计数器,看了头疼,不知道为什么会有这种需求?正常的不都是每条访问记录都保存下来,然后求总数的么?您用计数器统计次数,大概是因为您的网站代码从不不更新,所以网站也用不重启。
我在web项目里最长用到单例模式的地方,就是工厂模式的产品类可以用单例模式。这里netcore自带的IOC为例。
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton();
}
此时可以保证系统中,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
public class Singleton:ISingleton
{
public int Count { get; set; }
private static readonly Lazy lazy = new Lazy(() => new SingletonForLazy(),true);
public static SingletonForLazy GetInstance
{
get { return lazy.Value; }
}
public void Add()
{
Count++;
}
}
后面有文章会介绍项目中把单例和简单工厂结合起来使用。
跟着项目学设计模式(一):初识单例模式
跟着项目学设计模式(二):简单工厂
跟着项目学设计模式(三):工厂模式
跟着项目学设计模式(四):抽象工厂模式
跟着项目学设计模式(五):简单工厂+单例模式+静态类+延迟加载
TBD