c# 单例模式[Singleton]之深夜闲聊

都有点记不起认识单例模式(也有叫单件模式的)是在什么时候了,有时候东西认多了不常用的话也经常抛之脑后甚至逐渐从大脑里被移除。不闲扯了,直接入正题吧。

什么是单例模式?

保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点.

单例模式的作用?

被指定的类在整个应用程序只会被创建一次.



接着我们用代码来加深对单例模式的理解。在这之前我们都知道如果一个类在没有使用单例模式的情况下是可以被实例化多次对象的,比如下面代码:

这里我先创建一个类:

1  public class Person
2 {
3         public string Name { get; set; }
4         public string Email { get; set; }
5         public int Age { get; set; }
6 }

在应用程序中,我可以根据自己的需要无限的去实例化这个对象

 static void Main(string[] args)
 {
     for (int i = 0; i < 100; i++)
     {
         Person p = new Person();
     }
}

这个时候我们开始把单例模式的思想带进来,首先我们思考第一个问题怎么实现这个类只会能被实例化一次对象。之所以我们现在可以无限去new这个对象是因为这个类当前有一个默认的public的构造函数,谁都能去拿

它来进行新的实例化。因此,这样也给我们带来一个解决问题的思路。看下面的代码,我在类中把默认的public构造函数给覆盖掉,自己写一个构造函数然后把尝试把访问修饰符改为private

public class Person
    {
        private Person()
        {
        }
        public string Name { get; set; }
        public string Email { get; set; }
        public int Age { get; set; }
    }

这个时候在外部去创建这个对象时就会出问题了。"....不可访问,因为...受保户级别限制"

这个时候虽然无法在外界创建这个对象,但是我们依然可以通过类的内部去创建对象。(在类中可以定义一个方法,这个方法就是用来创建这个对象)这样我们从外界就可以直接通过这个类的方法来创建对象了

这里需要注意的是我们在类中定义创建对象的方法必须为静态方法,这样外界只能通过这个类来实例对象,而不需要再new一个对象再调用这个内部方法。代码如下:

class Program
{
     static void Main(string[] args)
      {
           Person p1 = Person.GetInstance();
       }
}
public class Person
    {
        private Person()
        {

        }
        public static Person GetInstance()
        {
            return new Person();
        }
        public string Name { get; set; }
        public string Email { get; set; }
        public int Age { get; set; }
    }

这个时候依旧存在一个问题,我们依旧可以创建N此对象。这样就跟单例模式的思想不沾边了。接下来我们可以继续在这个类去加一个对象的判断,请看下面的代码

 1 public class Person
 2     {
 3         private Person()
 4         {
 5
 6         }
 7         private static Person _instance =null;
 8
 9         public static Person GetInstance()
10         {
11             if (_instance == null)
12             {
13                 return new Person();
14             }
15             return _instance;
16
17         }
18         public string Name { get; set; }
19         public string Email { get; set; }
20         public int Age { get; set; }
21     }

这个时候我们在这个类中加入静态成员,而静态成员在应用程序中只共享一个类,当第一次调用GetInstance()方法的时它为null,然后满足条件后返回一个新的对象给用户。当第二次进来时,就不会null了,直接

把第一次的的对象返回给用户。解下来我们来测试下这个单例模式的雏形吧,测试结果:

这样就完成了一个基本的单例模式了,但这样还是完全不够完美的。毕竟这种实现无法满足多线程的场景。先撇开这个问题,先来总结下单例模式的实现思路:

把构造函数变成私有的外界就无法随便调用,然后在类中自己创建一个方法,在这个方法中new出一个对象,因为这个方法是要new对象的,所以说这个方法不能为实例方法,只能是静态方法。

静态方法每次被调用它就会new一次对象,这样就不是单例模式,所以还需要在这个类中加入一个静态的字段,这个字段就是这个类本身的类型。然后在这个类中判断这个静态字段为null就实例

化一个对象,然后返回。下次再调用的时候就不会为null了

好了,到这边已经解决了我们最开始的问题了。时间过的好快,(快十二点半了!!抓紧!人真是有点贱,玩游戏看电视不在乎多晚,想正儿八经写个文章就关注时间了)接下来看如何去处理多线程的单例模式。

 1 public class Singleton
 2     {
 3
 4         public Singleton()
 5         {
 6             Console.WriteLine(".");
 7         }
 8         private static Singleton _instancce;
 9         private static readonly object syn = new object();
10         public static Singleton GetInstance()
11         {
12
13             if (_instancce == null) //当对象为null时就锁定
14             {
15                 lock (syn) //锁定
16                 {
17                     if (_instancce == null)  //防止多个线程同时访问
18                     {
19                         _instancce = new Singleton();
20                         return _instancce;
21                     }
22
23                 }
24             }
25             return _instancce;
26
27         }
28     }

这是通过加锁的方式来处理多线程访问问题,代码不难。这边简单解释下为什么要有两个对象的判断,先从第一个对象来说,因为一旦一开始加锁,代码就会被锁定同时只会有一段代码在执行,这样会影响代码执行性能。所以在锁定之前先去判断对象是否为 null ;第二个判断为 null 的原因是第一个判断不在这个线程中,表示只要满足条件都可以进入,之后的原因参考以上代码注释即可。

临睡之前突然想到还有个办法也能实现单例模式,可以利用 c# 静态字段,在第一次使用类的时候只初始化一次的特性。代码如下:

 1 public class Singleton2
 2     {
 3
 4         private Singleton2()
 5         {
 6             Console.WriteLine(".");
 7         }
 8
 9         public static readonly Singleton2 _instance = new Singleton2();
10         public static Singleton2 GetInstance()
11         {
12             return _instance;
13         }
14     }

好了,就写到这儿了~good 9

时间: 2024-12-14 10:14:16

c# 单例模式[Singleton]之深夜闲聊的相关文章

.Net 单例模式(Singleton)

每台计算机可以有若干个打印机,但只能有一个Printer Spooler, 以避免两个打印作业同时输出到打印机中.每台计算机可以有若干传真卡,但是只应该有一个软件负责管理传真卡,以避免出现两份传真作业同时传到传真卡中的情况.每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用. 问题描述: 单例模式 Singleton Pattern 问题解决: (1)单例模式简介: Singleton模式要求一个类有且仅有一个实例,并且提供了一个全局的访问点.这

单例模式——Singleton

模式分类: 从目的来看: 1.创建型(Creational)模式:负责对象创建. 2.结构型(Structural)模式:处理类于对象间的组合. 3.行为型(Behavioral)模式:类与对象交互中的职责分配. 从范围看: 1.类模式处理类于子类的静态关系. 2.对象模式处理对象间的动态关系. 动机 在软件系统中,经常有一些这样特殊的类,必须保证他们在系统中只存在一个实例,才能确保他们的逻辑正确性.以及良好的效率. 绕过常规的构造器,提供一种机制保证一个类只有一个实例. 意图 保证一个类仅有一

【白话设计模式四】单例模式(Singleton)

转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factory) [白话设计模式二]外观模式(Facade) [白话设计模式三]适配器模式(Adapter) [白话设计模式四]单例模式(Singleton) [白话设计模式五]工厂方法模式(Factory Method) [白话设计模式六]抽象工厂模式(Abstract Factory) [白话设计模式七]策

php设计模式——单例模式(Singleton)

二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 谷歌的Android设备 华为的Android设备 IOS只属于苹果公司 IOS只属于苹果公司 1 <?php 2 3 /* 4 * php

设计模式之——单例模式(Singleton)的常见应用场景(转):

单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此有些设计大师并把把其称为设计模式之一. 这里又不具体讲如何实现单例模式和介绍其原理(因为这方便的已经有太多的好文章介绍了),如果对单例模式不了解的可以先看下:http://terrylee.cnblogs.com/archive/2005/12/09/293509.html . 好多没怎么使用过的人

Android - 单例模式(singleton)的使用

单例模式(singleton)的使用 本文地址:http://blog.csdn.net/caroline_wendy 单例(singleton)是特殊的Java类,在创建实例时,一个类仅允许创建一个实例. 应用能够在内存里存多久,单例就能存在多久,因此将对象列表保存在单例里可保持crime数据的一直存在, 不管activity.fragment及它们的生命周期发生什么变化. 要创建单例,需创建一个带有私有构造方法及get()方法类,其中get()方法返回实例. 如实例已存在,get()方法则直

二十四种设计模式:单例模式(Singleton Pattern)

单例模式(Singleton Pattern) 介绍保证一个类仅有一个实例,并提供一个访问它的全局访问点. 示例保证一个类仅有一个实例. Singleton using System; using System.Collections.Generic; using System.Text; namespace Pattern.Singleton { /// <summary> /// 泛型实现单例模式 /// </summary> /// <typeparam name=&q

Java 设计模式 单例模式(Singleton) [ 转载 ]

Java 设计模式 单例模式(Singleton) [ 转载 ] 转载请注明出处:http://cantellow.iteye.com/blog/838473 前言 懒汉:调用时才创建对象 饿汉:类初始化时就创建对象 第一种(懒汉,线程不安全): 1 public class Singleton { 2 private static Singleton instance; 3 private Singleton (){} 4 5 public static Singleton getInstan

Android设计模式——单例模式(Singleton)

二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 1 package com.example.main; 2 3 import android.app.Activity; 4 import