设计模式——10.单例模式

单例模式(Singleton)

单例模式(Singleton)简介:

单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点。使用单例模式能够让设计师快速获取提供某项服务或者功能的对象,可以省去层层传递对象的困扰。

单例模式在实现时,需要编程语言的支持,需要编程语言具有静态类属性静态类方法以及可重新定义构造函数的访问修饰符,具有这3项语句功能的编程语言就可以实现单例模式。

C++代码

单线程

Singleton单例类:

//file: Singleton.h
#pragma once

class Singleton
{
public:
    virtual ~Singleton();

    static Singleton * getInstance();

    void operation();

private:
    static Singleton * instance;

    Singleton();
};
//file: Singleton.cpp
#include "pch.h"
#include "Singleton.h"
#include <iostream>

Singleton * Singleton::instance = nullptr;

Singleton::Singleton() {}

Singleton::~Singleton()
{
    delete instance;
}

Singleton * Singleton::getInstance()
{
    if (instance == nullptr)
        instance = new Singleton();
    return instance;
}

void Singleton::operation()
{
    std::cout << "Singleton Operation ." << std::endl;
}

客户端代码:

//file: SingletonPattern.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include "pch.h"
#include "Singleton.h"
#include <iostream>
using namespace std;

int main()
{
    Singleton * singleton = Singleton::getInstance();
    singleton->operation();

    char c;
    cin >> c;
    return 0;
}

多线程

C#代码

C#单线程

Singleton单例类:

public class Singleton
{
    private Singleton() { }
    private static Singleton instance = null;

    public static Singleton Instance
    {
        get
        {
            if (instance == null)
                instance = new Singleton();
            return instance;
        }
    }

    public void Operation()
    {
        Console.WriteLine("The Singleton Operation .");
    }
}

其中静态类方法Instance用来获取_instance属性,上方代码使用了C#的getter存取运算符功能来实现Instance方法,使Singleton.Instance()的调用方式,写为Singleton.Instance的方式,减少的一对括号对于后续代码维护有着一定程度的帮助。

客户端测试代码:

class Program
{
    static void Main(string[] args)
    {
        Singleton singleton = Singleton.Instance;
        singleton.Operation();
        Console.ReadKey();
    }
}

或者使用方法方式获取单例:

public class Singleton
{
    private Singleton() { }
    private static Singleton instance = null;

    public static Singleton GetInstance()
    {
        if (instance == null)
        {
            instance = new Singleton();
        }
        return instance;
    }

    public void Operation()
    {
        Console.WriteLine("The Singleton Operation .");
    }
}

//使用时:
//Singleton singleton = Singleton.GetInstance();

C#多线程

    public class Singleton
    {
        private Singleton() { }
        private static Singleton instance = null;
        private static readonly object syncObj = new object();

        public static Singleton Instance
        {
            ////可以在多线程上工作但是效率不高
            //get {
            //    lock (syncObj) {
            //        if (instance == null)
            //            instance = new Singleton();
            //    }
            //    return instance;
            //}

            //加同步锁前后两次判断,仅当instance为空时,才进行加锁操作
            get {
                if (instance == null) {
                    lock (syncObj) {
                        if (instance == null)
                            instance = new Singleton();
                    }
                }
                return instance;
            }
        }
        public void Operation()
        {
            Console.WriteLine("The Singleton Operation .");
        }
    }

C#多线程单例的另一种写法,这样写虽然很简洁,但是其instance实例并不是在第一次使用的时候才创建,而是在运行时第一次发现Singleton类被用到时就创建了

    public class Singleton {
        private Singleton() { }
        private static Singleton instance = new Singleton();

        public static Singleton Instance {
            get {
                return instance;
            }
        }
        public void Operation()
        {
            Console.WriteLine("The Singleton Operation .");
        }
    }

单例模式优点及缺点

优点:
单例模式通过将类的构造方法私有化,让类对象只能够在类的成员方法中产生,配合类的静态成员属性在类中只会出现一个的限制,让系统可以有效的限制数量,因此,单例模式可以有效的限制类对象产生的地点和时间,同时也可以防止类对象被随意产生而造成系统错误。

缺点:

单例模式使用方便,但是在挑选适合以单例模式实现的类时,需要认真挑选,不能够滥用单例;其次,单例模式违反了“开闭原则”,因为通过Instance方法获取的对象是“实现类”不是“接口类”,该方法返回的对象是包含了实现细节的实体类,当后续设计变更后者需求改变时,程序员无法将它替代为其他类,只能改变实现类中原有的程序代码,无法满足“对修改关闭”的要求。

REF

书籍:

设计模式与游戏开发、大话设计模式

GitHub:

https://github.com/me115/design_patterns

posted @ 2018-12-09 18:41  SylvanYan  阅读(109)  评论(0编辑  收藏  举报
TOP