.NET c# 单体模式(Singleton)

单体模式(Singleton)是经常为了保证应用程序操作某一全局对象,让其保持一致而产生的对象,例如对文件的读写操作的锁定,数据库操作的时候的事务回滚,还有任务管理器操作,都是一单体模式读取的。
  创建一个单体模式类,必须符合三个条件:
  1:私有构造函数(防止其他对象创建实例);
  2:一个单体类型的私有变量;
  3:静态全局获取接口

下面我写一个类,为了看是不是单体,就加了一个计数器,如果是同一个类,那么这个类的计数每次调用以后就应该自动加一,而不是重新建对象归零:

.NET c# 单体模式

using System;
using System.Threading;
public class Singleton{ 
    private int ObjCount=0;
    private Singleton(){
        Console.WriteLine("创建对象");
    }
    private static Singleton objInstance = null;
    public static  Singleton getInstance() {
        if (objInstance==null) objInstance=new Singleton();

return objInstance;
    }
    public void ShowCount(){
        ObjCount++;
        Console.WriteLine("单个对象被调用了{0}次",ObjCount);
    }
};

然后我们来测试一下:
public class ConsoleTest{
    public static void Main(string[] args){
        Console.WriteLine("开始执行单体模式"); 
        for(int i=0;i<5;i++){
            Singleton.getInstance().ShowCount();
        }

Console.ReadLine();
    }
};

我在这个Main里面执行了5次,看看输出的结果:
开始执行单体模式
创建对象
单个对象被调用了1次
单个对象被调用了2次
单个对象被调用了3次
单个对象被调用了4次
单个对象被调用了5次
  在这里可以看出,每次都是使用的同一个对象,实现了单体。
  为了测试在多线程下面是否是单体,下面我写了一个多线程测试的:
class ApartmentTest
{
    public static void RunMoreThread()
    {
        Thread newThread =  new Thread(new ThreadStart(ThreadSingleMethod));
        newThread.SetApartmentState(ApartmentState.MTA);
        Console.WriteLine("ThreadState: {0}, ApartmentState: {1},ManagedThreadId:{2}", newThread.ThreadState, newThread.GetApartmentState(),newThread.ManagedThreadId );
        newThread.Start();
    }

public static void ThreadSingleMethod() {
        Singleton.getInstance().ShowCount();
    }
};

然后每次for循环执行ApartmentTest.RunMoreThread();
再看看输出的结果:开始执行单体模式
ThreadState: Unstarted, ApartmentState: MTA,ManagedThreadId:3
创建对象
单个对象被调用了1次
ThreadState: Unstarted, ApartmentState: MTA,ManagedThreadId:4
单个对象被调用了2次
ThreadState: Unstarted, ApartmentState: MTA,ManagedThreadId:5
单个对象被调用了3次
ThreadState: Unstarted, ApartmentState: MTA,ManagedThreadId:6
单个对象被调用了4次
ThreadState: Unstarted, ApartmentState: MTA,ManagedThreadId:7
单个对象被调用了5次

根据ManagedThreadId,可以看出不同的线路访问达到了单体,OK!

c#的单体模式介绍完毕;

下面是PHP 单体模式的代码:
<?php

header("Content-Type: text/html; charset=utf-8");

class Singleton{ 
    private $ObjCount=0;
    private function __construct(){
        echo("创建对象<hr/>");
    }

public static  function   getInstance() {
        static $objInstance = null;        
                  if ( $objInstance == null )
          $objInstance =  new Singleton();
        return $objInstance;

}
    public function ShowCount(){
        $this->ObjCount++;
        echo("单个对象被调用了".$this->ObjCount.'次数<hr/>');
    }

};

for($i=0;$i<5;$i++)
    Singleton::getInstance()->ShowCount();
?>

请注意以上PHP代码的私有静态变量范围,不要放在类主体。
执行结果:
创建对象
--------------------------------------------------------------------------------
单个对象被调用了1次数
--------------------------------------------------------------------------------
单个对象被调用了2次数
--------------------------------------------------------------------------------
单个对象被调用了3次数
--------------------------------------------------------------------------------
单个对象被调用了4次数
--------------------------------------------------------------------------------
单个对象被调用了5次数

下面我们再来看看Java版本的写法:

单体模式 Java
class Singleton{ 
    private int ObjCount=0;
    private Singleton(){
        System.out.println("创建对象");
    }
    private static Singleton objInstance = null;
    public static  Singleton getInstance() {
        if (objInstance==null) objInstance=new Singleton();

return objInstance;
    }
    public void ShowCount(){
        ObjCount++;
        System.out.println("单个对象被调用了"+ ObjCount +"次");
    }
};
class ConsoleTestSingleton{
    public static void main(String args[]){
        System.out.println("开始执行单体模式"); 
        for(int i=0;i<5;i++){
            Singleton.getInstance().ShowCount();
        }
    }
};
基本代码与c#一致,执行结果:
开始执行单体模式
创建对象
单个对象被调用了1次
单个对象被调用了2次
单个对象被调用了3次
单个对象被调用了4次
单个对象被调用了5次

可以看出,也是完全的单体,只要记住开头提到的三点,即可掌握该模式。
----------
1:今天L出差
2:昨天聚会,比较Happy
3:SL和Z都是手机Q网
4:无事之冬

(0)

相关推荐

  • C#中利用代理实现观察者设计模式详解

    界面开发中,经常使用观察者设计模式来实现文档/视图模式,当文档内容改变时,作为观察者的用户视图必须相应作出调整以向用户呈现文档的状态.由于语言机制的不同,观察者设计模式在不同的语言中实现方法也不尽相同. 在MFC的文档/视图模式中,每当文档内容改变都需要调用UpdateAllView函数来更新视图,该函数会遍历文档的每一个视图,调用每个视图的更新函数来更新视图,为此文档须登记每一个使用该文档的视图.C#中观察者设计模式的实现也可以采用这种方法,但C#提供的代理(delegate)机制为实现观察者

  • 深入c#工厂模式的详解

    什么是工厂模式?类比生活中的概念,当我们需要打电话的时候,我们需要一部手机,我们通常会选择直接去卖手机的实体店买.但在程序设计中,当我们需要调用一个类(PhoneA或PhoneB)的方法的时候,我们往往还要关心他是怎么new出来的(见代码段1).这就好比我们自己还要去工厂里面告诉他们你要怎么生产出一部我需要的手机.而我们只关心他能不能打电话,你怎么做的关我屁事.所以这就有了工厂模式.工厂模式其实就是抽象出一个工厂,我需要什么手机,去哪个工厂买就行了.我不必关心他的制作过程,你只要能生产我要的功能

  • C# 观察者模式实例介绍

    观察者模式 观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主体对象,这个主题对象在状态发生变化时,会通知所有观察者.当一个对象改变需要同时改变其他对象,而且他不知道具体有多少对象需要改变的时候,应该考虑使用观察者模式. 观察者结构图: 使用场景:老板回来通知员工需要进入工作状态. 定义观察者的抽象类: 复制代码 代码如下: abstract class Observer { protected string name; protected ISubject sub; pu

  • C#中委托和事件在观察者模式中的应用实例

    通常来说当一个被监视对象的方法执行会触发观察者Observer的方法的时候,我们就可以在被监视对象中声明委托和事件.本文就以实例形式展示了C#中实现委托和事件在观察者模式中的应用.具体如下: 示例如下: 有一个宠物追踪器挂宠物身上,只要宠物离开主人100米之外,主人手上的显示器显示警告信息并声音报警. class Program { static void Main(string[] args) { PetTracker tracker = new PetTracker(); tracker.I

  • C#设计模式之外观模式介绍

    1.在设计初期阶段,应该要有意识的将不同的两层分离,比如考虑数据访问层.业务逻辑层.表示层之间建立外观模式,这样可以为子系统提供简单一致的接口,使得耦合大大降低. 2.开发阶段,子系统内部由于不够重构变得非常复杂,增加外观模式可以屏蔽这个复杂性,并提供简单的接口. 3.维护一个遗留的大型系统,代码不好再维护时,使用外观模式也是不错的选择. 看看外观模式的结构图: Facade类定义:可以给高层系统提供简单的接口 复制代码 代码如下: class Facade { SubSystemOne one

  • c# 适配器模式

    结构图: 客户可以对接的接口类: 复制代码 代码如下: class Target { public virtual void Request() { Console.WriteLine("普通请求!"); } } 客户需要使用适配器才能使用的接口: 复制代码 代码如下: class Adaptee { public void SpecialRequest() { Console.WriteLine("特殊请求!"); } } 适配器的定义:继承与Target类 复制

  • c# 备忘录模式

    结构图: Memento类:保存状态的容器 复制代码 代码如下: class Memento    {        public string State { get; set; }        public Memento(string state)        {            this.State = state;        }    } Caretaker是保存Memento类: 复制代码 代码如下: class Caretaker    {        public

  • c# 代理模式

    代理模式的应用: 远程代理,为一个对象在不同的地址空间提供局部代表,可以隐藏一个对象存在于不同地质空间的事实. 虚拟代理,根据需要创建开销很大的对象,通过代理来存放实例化需要很长时间的真实对象. 安全代理,用来控制真实对象的访问权限. 智能代理,当调用代理时,可以代理处理一些额外的功能. 案例场景: 向一位自己心仪的女孩表达爱意,一般我们有两种选择:亲自出马(有自信的人)和 使用'媒婆'(比较害羞). 其中使用'媒婆'就是代理行为,我们实现如下: 调用代理模式的主函数: class Progra

  • 深入C#字符串和享元(Flyweight)模式的使用分析

    写这个文章,主要是因为网上对C#字符串和享元模式的误解比较多. Flyweight模式先说这名字,fly呢,就是苍蝇,没错这里面不是飞的意思,是苍蝇的意思,weight大家都知道,就是重量,苍蝇的重量,就是非常非常轻的意思.所以Flyweight模式就是处理非常非常轻量级对象的一个东西.Flyweight的目标是解决大量细粒度对象的内存消耗问题,当然,巧妇难为无米之炊,任何模式和手法都不能凭空造出内存来,所以享元模式针对的情况是这些细粒度对象的中数据有重复的情况.Flyweight的做法是,把对

  • c#标准idispose模式使用示例

    IDispose模式在C++中用的很多,用来清理资源,而在C#里,资源分为托管和非托管两种,托管资源是由C#的CLR帮助我们清理的,它是通过调用对象的析构函数完成的对象释放工作,而对于非托管系统来说,则需要我们自己来释放,例如数据库连接对象,这就需要我们手动去调用它的Dispose()方法来实现对象它的释放,事实上,Dispose()内容到底做了什么事,我们并不清楚,当然这就是面向对象,它不希望你关系实现的细节,呵! 对于我们开发人员来说,在了解它怎么用之后,总会对它如何实现的产生兴趣,下面,我

  • c# 组合模式

    结构图: 抽象对象: 复制代码 代码如下: abstract class Component    {        protected string name;        public Component(string name)        {            this.name = name;        }        public abstract void Add(Component c);        public abstract void Remove(Com

  • C#中的IDisposable模式用法详解

    本文实例讲述了C#中IDisposable模式的用法,针对垃圾资源的回收进行了较为详细的讲解.分享给大家供大家参考之用.具体方法如下: 首先,对于垃圾回收而言,在C#中,托管资源的垃圾回收是通过CLR的Garbage Collection来实现的,Garbage Collection会调用堆栈上对象的析构函数完成对象的释放工作:而对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Idisposable接口,以及如何使用呢? 先来参考一

  • C#策略模式(Strategy Pattern)实例教程

    本文以一个简单的实例来说明C#策略模式的实现方法,分享给大家供大家参考.具体实现方法如下: 一般来说,当一个动作有多种实现方法,在实际使用时,需要根据不同情况选择某个方法执行动作,就可以考虑使用策略模式. 把动作抽象成接口,比如把玩球抽象成接口.代码如下: public interface IBall { void Play(); } 有可能是玩足球.篮球.排球等,把这些球类抽象成实现接口的类.分别如下: public class Football : IBall { public void P

随机推荐