zoukankan      html  css  js  c++  java
  • 设计模式之Singleton

            Singleton是我项目中运用最多的设计模式了,虽然简单,却能大大降低模块耦合性。通过该模式,最多只能创建该类的一个实例。个人理解,Singleton就不再需要别的模块来聚合本模块,其表现形式最大特点就是构造函数的访问权限是private的,由第一个依赖本模块的其它模块进行实例化。笔者一直从事安全软件的研发,会在软件运行初期通过调用各个模块的Init()来实现单例的实现,而这个过程由于在初始化线程中串行执行,也有效避免了多线程下单例的互斥问题。不过下述文章仍会介绍下多线程开发单线程互斥问题。

    类的声明:

    View Code
    //Singleton.h
    namespace DP{
    #ifndef _SINGLETON__H_
    #define _SINGLETON__H_

    class CSingleton{
    private:
    CSingleton(){
    };
    ~CSingleton(){
    };

    static CSingleton* instance;
    public:
    static CSingleton* Singleton();/*Singleton()函数必须设置成公有属性*/
    void Print();/*本模块对外提供的操作方法实例*/
    };
    }

    #endif/*_SINGLETON__H_*/

    类的成员变量的实现:

    View Code
    //Singleton.cpp
    #include "Singleton.h"
    #include <stdio.h>
    using DP::CSingleton;

    CSingleton* CSingleton::instance = NULL;
    CSingleton* CSingleton::Singleton()
    {
    if (NULL ==instance)
    {
    instance = new CSingleton();
    }
    return instance;
    }
    void CSingleton::Print()
    {
    printf("this instance is call\n");
    }

    单例模式主要具备如下特征:

    1. 将构造函数声明为私有的,防止在类外生成对象;

    2. 提供静态方法Singleton()来返回自己的实例,别的模块在依赖该模块时,比如需要该模块提供的操作Print()时,只需要CSingleton::Singleton()->Print();

    3. CSingleton类中有一个静态变量instance,用于指向唯一自己模块实例的指针,在初始化的时候为NULL;

    4. 在Singleton()是单例模式的核心体现,会在第一次被调用时进行自我实例化。

    然而,Singleton()中的if(NULL==instance)判断,在多线程程序中会出现竞争冒险,这时候我们就采取多线程互斥的方法。

    采用DCLP(Double Check Locking Pattern)实现互斥。

    互斥锁的声明和实现(使用Windows平台API,以后可以考虑posix接口实现,可以针对跨平台操作):

    //Mutex.h
    #ifndef _MUTEX__H_
    #define _MUTEX__H_

    #include "Windows.h"
    class CMutex{
    public:
    CMutex();
    ~CMutex();
    void Lock();
    void UnLock();
    private:
    HANDLE m_mutex;
    };

    #endif/*_MUTEX__H_*/
    View Code
    //Mutex.cpp
    #include "Mutex.h"

    CMutex::CMutex()
    {
    m_mutex = CreateMutex(NULL, false, NULL);
    }

    CMutex::~CMutex()
    {
    CloseHandle(m_mutex);
    }

    void CMutex::Lock()
    {
    WaitForSingleObject(m_mutex, INFINITE);
    }

    void CMutex::UnLock()
    {
    ReleaseMutex(m_mutex);
    }

    Sinleton()模式声明和实现:

    //Singleton.h

    #ifndef _SINGLETON__H_
    #define _SINGLETON__H_
    #include "../Mutex/Mutex.h"
    namespace DP{
    class CSingleton{
    private:
    CSingleton(){
    };
    ~CSingleton(){
    };
    static CMutex mutex_visit;

    static CSingleton* instance;
    public:
    static CSingleton* Singleton();/*Singleton()函数必须设置成公有属性*/
    void Print();/*本模块对外提供的操作方法实例*/
    };
    }

    #endif/*_SINGLETON__H_*/
    View Code
    //Singleton.cpp
    #include "Singleton.h"
    #include <stdio.h>
    using DP::CSingleton;

    CMutex CSingleton::mutex_visit;
    CSingleton* CSingleton::instance = NULL;
    CSingleton* CSingleton::Singleton()
    {
    if (NULL ==instance)//第一层判断, 避免下面line12~line16频繁执行
    {
    mutex_visit.Lock();
    if(NULL==instance){//因为第一层判断没有加锁,因此只靠第一层判断无法做到避免竞争冒险
    instance = new CSingleton();
    }
    mutex_visit.UnLock();
    }
    return instance;
    }
    void CSingleton::Print()
    {
    printf("this instance is call\n");
    }


    示例代码:

    CSingleton::Singleton()->Print();






  • 相关阅读:
    雷林鹏分享:XML to HTML
    雷林鹏分享:XML DOM
    雷林鹏分享:XML 编码
    雷林鹏分享: XML CDATA
    雷林鹏分享:服务器上的 XML
    雷林鹏分享:XML 注意事项
    雷林鹏分享:现实生活中的 XML
    雷林鹏分享:XML 相关技术
    雷林鹏分享:XML
    Android 系统架构图
  • 原文地址:https://www.cnblogs.com/RealOnlyme/p/2396173.html
Copyright © 2011-2022 走看看