美文网首页
单例模式

单例模式

作者: 周末的游戏之旅 | 来源:发表于2019-08-29 17:48 被阅读0次

什么是单例模式

单例模式就是说,这个类只有一个对象。比如游戏中的Player,一个玩家只能有一个Player。

简单实现

class Player
{
    public string name = "aaa";
    #region MyRegion
    //私有
    private Player()
    {

    }
    //2、在内部new一个单例,游戏一开始就会创建对象、
    public static Player player = new Player();
    #endregion
}

这是一个简单的实现。
可以通过Player.player来访问单例对象。但是这样不安全,因为任何一个使用Player.player的人都可以执行Player.player=null这一操作。所以,有一个升级版的方案如下。

只读单例

class Player
{
    public string name = "aaa";
    #region MyRegion
    //私有
    private Player()
    {

    }
    //2、在内部new一个单例,游戏一开始就会创建对象、
    public static readOnly Player player = new Player();
    #endregion
}

这样,Player.player就成只读的了,但是这样设计虽然安全性升级了,但是会在游戏一开始就创建对象。如果有大量的单例,这样游戏开始就会创建大量的对象。所以有一个优化的方案。

单例模式,惰性返回一个实例

Class Player
{   
    public string name ="aaa";
    //1、私有构造
    private Player(string name)
    {
        this.name=name;
    }
    //2、创建一个静态的单例
    private static Player instance;
    //3、创建一个静态方法,惰性实例化返回单例
    public static Player GetInstance(string name)
    {
        //惰性实例化;只有调用的时候才会实例化对象
        if (instance == null)
        {
            Console.WriteLine("被实例化了");
            instance = new Player(name);
        }
        Console.WriteLine("Get"+instance.name);
        return instance;
    }
}

这样只有调用Player类的时候才会创建单例对象。

思考

在学习惰性返回实例的单例时,有一个问题一开始没想通。

class Program
{
    static void Main(string[] args)
    {
        Player player = Player.GetInstance("bbb");
        Console.WriteLine("player"+player.name);
        player = null;
        Console.WriteLine("player是空"+(player==null));
        Player player1 = Player.GetInstance("ccc");
        Console.WriteLine("player1"+player1.name);
        //Console.WriteLine(player1.name);
    }
}

当我创建player1对象并打印其名字,然后再将其置为空。此时我再创建player1对象时,应该会创建一个新的对象。
但其实不是的,因为player对象里只是存的instance的地址,把player=null,也只是把player存的地址设为空而已,instance并不受影响。而且instance是存放在静态空间中的,不是存放在栈或堆中。

更简化的惰性实例化实现

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

内存分区

内存到底分几个区?

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。

2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由os回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

3、全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后有系统释放。

4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放。

5、程序代码区—存放函数体的二进制代码。


单例模板

如果一个项目中需要有很多单例,可以把单例抽象成一个父类作为模板。其他单例类直接继承这个模板即可。

public class SingleTon<T> where T : SingleTon<T>,new()
{
    private static T instance;

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

public class GameAssetsMgr :SingleTon<GameAssetsMgr> {

    /// <summary>
    /// 加载装备预设体
    /// </summary>
    public GameObject LoadEquipItemPrefab()
    {
        //加载预设体
        return Resources.Load<GameObject>("Prefabs/Equip");
    }

    /// <summary>
    /// 通过装备名称加载装备图片
    /// </summary>
    /// <returns>The equip sprite.</returns>
    /// <param name="equipName">Equip name.</param>
    public Sprite LoadEquipSprite(string equipName)
    {
        return Resources.Load<Sprite>("Textures/" + equipName);
    }

}

相关文章

  • 【设计模式】单例模式

    单例模式 常用单例模式: 懒汉单例模式: 静态内部类单例模式: Android Application 中使用单例模式:

  • Android设计模式总结

    单例模式:饿汉单例模式://饿汉单例模式 懒汉单例模式: Double CheckLock(DCL)实现单例 Bu...

  • 2018-04-08php实战设计模式

    一、单例模式 单例模式是最经典的设计模式之一,到底什么是单例?单例模式适用场景是什么?单例模式如何设计?php中单...

  • 设计模式之单例模式详解

    设计模式之单例模式详解 单例模式写法大全,也许有你不知道的写法 导航 引言 什么是单例? 单例模式作用 单例模式的...

  • Telegram开源项目之单例模式

    NotificationCenter的单例模式 NotificationCenter的单例模式分析 这种单例模式是...

  • 单例模式Java篇

    单例设计模式- 饿汉式 单例设计模式 - 懒汉式 单例设计模式 - 懒汉式 - 多线程并发 单例设计模式 - 懒汉...

  • IOS单例模式的底层原理

    单例介绍 本文源码下载地址 1.什么是单例 说到单例首先要提到单例模式,因为单例模式是单例存在的目的 单例模式是一...

  • 单例

    iOS单例模式iOS之单例模式初探iOS单例详解

  • 单例模式

    单例模式1 单例模式2

  • java的单例模式

    饿汉单例模式 懒汉单例模式

网友评论

      本文标题:单例模式

      本文链接:https://www.haomeiwen.com/subject/vmhwectx.html