单例模式(Singleton Pattern)——游戏开发常用设计模式(一)

news/2025/1/13 21:53:16/文章来源:https://www.cnblogs.com/CloverJoyi/p/18669500

前言

单例模式应该是在unity游戏开发中最简单最常用的设计模式之一,无论是管理全局游戏状态、处理资源加载,还是控制音频播放,单例模式都能为我们提供一个简洁的解决方案——确保一个类只有一个实例,并允许在游戏的任何地方轻松访问它。

然而,这种便利性也伴随着潜在的风险,比如代码耦合度增加、测试难度提升,甚至可能引发难以调试的多线程问题。

本文记录了我在学习单例模式中总结的重点和实用方法
本文脚本均为基于unity的C#脚本

一、简介

1.概念

单例模式是一种设计模式,它通过限制类的实例化过程,确保在整个应用程序生命周期中只有一个实例存在,并提供一个全局访问点以便在代码的任何地方都能方便地使用这个唯一实例。应用在Unity里面,可以用来作为数据类、工具类、实现类,方便脚本调用。

2.优缺点

优点:

  1. 它确保一个类只有一个实例,避免了重复创建对象的开销,从而节省了系统资源;
  2. 单例模式提供了一个全局访问点,使得在程序的任何地方都能方便地访问这个实例。
  3. 单例模式能简化代码结构,减少因多实例管理带来的复杂性。
    缺点:
  4. 单例模式可能导致代码的耦合度增加,因为全局访问的特性使得其他类直接依赖于单例,降低了代码的可测试性和可维护性;
  5. 单例模式在多线程环境下可能引发线程安全问题,需要额外的同步机制来保证实例的唯一性;
  6. 单例的生命周期通常与应用程序一致,如果设计不当,可能会导致资源无法及时释放,从而引发内存泄漏等问题。

3.分类

单例模式分为饿汉式和懒汉式两种:

  1. 饿汉式单例模式:在程序一开始的时候就创建了单例对象。但这样一来,这些对象就会在程序一开始时就存在于内存之中,占据着一定的内存。
  2. 懒汉式单例模式:在用到单例对象的时候才会创建单例对象。

在使用unity进行游戏开发时,单例模式的实现方式又分为继承MonoBehaviour不继承MonoBehaviour

二、代码实现

1.继承MonoBehaviour的单例模式

写法一

可将此脚本挂载在任意对象上

public class UnitySingleton : MonoBehaviour{static UnitySingleton instance;public static UnitySingleton Instance {get{if(instance == null){instance = GameObject.FindObjectOfType(typeof(UnitySingleton)) as UnitySingleton ;}return instance;}}
}

写法二

这是一种更容易理解的写法,需要将此脚本挂载在单例对象上

public class UnityManager : MonoBehaviour{public static UnityManager Instance;void Awake(){if(instance == null){intstance = this;}else{Destory(gameObject);}}
}

写法三

切换场景不销毁单例对象

public class TestUI : MonoBehaviour 
{//定义私有的构造方法,防止外部实例化对象private Test(){}private static Test instance;public static Test Instance { get { //保证对象的唯一性if (instance == null){instance = FindObjectOfType<Test>();if(instance == null){GameObject go = new GameObject("Test");//创建游戏对象instance = go.AddComponent<Test>();//挂载脚本到游戏对象}DontDestroyOnLoad(instance);//创建不销毁的对象}return instance; } }
}

2.不继承MonoBehaviour的单例模式

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

还有一种泛型单例基类的写法,可以提高代码复用率,因为我暂时用不到,现在这里留个坑,等以后用到了再回来补上。泛型基类的写法在这篇文章里有详细教程:【unity框架开发1】最详细的单例模式的设计和应用,继承和不继承MonoBehaviour的单例模式,及泛型单例基类的编写_unity继承monobehaviour单例模式-CSDN博客

3.使用方法

以上写法均可使用 [ 类名.Instance.---- ] 进行访问

三、总结

单例虽然方便,但如果我们在一个项目中 过度使用单例模式,就会造成该项目的 耦合性非常高,一个单例中的某个变量,可能同时被十几个对象引用,导致牵一发而动全身,使得项目难以维护。

在使用unity进行游戏开发的过程中,使用单例时需要注意:

如果其它脚本与单例有依赖关系,且单例中有初始化代码在Awake或者Start方法中执行,最好手动控制单例的初始化顺序。因为在unity中多个脚本间的Start方法和Awake方法是以随机顺序进行的,手动控制单例的初始化顺序以防止空引用异常。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/868724.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

黑狂野大数据2

--拉链表 --增量导入是没有overwrite 且加载的是最新分区的数据

others_shellcode 1

其实这题直接nc连一下就可以了。其实考的是系统调用来着 32位程序系统调用号用 eax 储存, 第一 、 二 、 三参数分别在 ebx 、ecx 、edx中储存。 可以用 int 80 汇编指令调用。 64位程序系统调用号用 rax 储存, 第一 、 二 、 三参数分别在 rdi 、rsi 、rdx中储存。 可以用 sys…

一篇解决编译原理大作业,基于Flex、Bison设计编译器(含语法分析树和符号表)

1.工具简单介绍 Flex 和 Bison 是编译器开发中常用的两个工具,分别用于生成词法分析器和语法分析器。它们通常一起使用,共同完成源代码的词法分析和语法分析工作。 Flex: Flex通过读取一个规则文件(通常是.l文件),这个文件中定义了一系列的模式和对应的动作。模式用于匹配…

python 删除txt的前三行并保存原文件

数据 #!usr/bin/env python # -*- coding:utf-8 _*- """@author:Suyue @file:raindrop.py @time:2025/01/$ {DAY} @desc: """ def remove_first_three_lines(file_path):# 读取原始文件的所有行with open(file_path, r, encoding=utf-8) as file…

P3586 [POI2015] Logistyka

P3586 [POI2015] Logistyka 题目描述 维护一个长度为 \(n\) 的序列,一开始都是 \(0\),支持以下两种操作:U k a 将序列中第 \(k\) 个数修改为 \(a\)。 Z c s 在这个序列上,每次选出 \(c\) 个正数,并将它们都减去 \(1\),询问能否进行 \(s\) 次操作。每次询问独立,即每次询…

Java编程规范-命名规范

命名风格 抽象类/异常类/测试类 抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类命名以它要测试的类的名称开始,以 Test 结尾。 数组 中括号是数组类型的一部分,数组定义如下:String[] args。 反例: 使用 String args[] 的方式来定义。 POJO…

go序列化库--msgpack

简介 msgpack是一个基于二进制高效的对象序列化类库,可用于跨语言通信。 它可以像JSON那样,在许多种语言之间交换结构对象。 但是它比JSON更快速也更轻巧。 支持Python、Ruby、Java、C/C++、Go等众多语言。 宣称比Google Protocol Buffers还要快4倍。官方的说法它像 JSON, 但…

图灵完备游戏介绍

怎么从软件到硬件 这个问题对于我来说很难理解。即使我本身是程序员,即使看了很多科普视频,但仍然不知道。硬件是不可变的,软件是多变的,怎么用不变实现变化? 我偶然间看了系统推荐的游戏视频,发现了这个游戏。于是就趁着无聊玩了下。这个游戏展现了怎么从硬件到软件。逻…

推荐4款基于.NET开源、功能强大的CMS建站系统

前言 CMS系统作为一种强大的内容管理工具,在数字化时代发挥着越来越重要的作用。无论是个人博客还是大型企业官网,选择一个合适的CMS都能极大地提高效率和用户体验。今天大姚给大家推荐4款基于.NET开源、免费、功能强大的CMS建站系统,希望可以帮助到有需要的同学。 SSCMS SS…

DVWA靶场CSP Bypass (漏洞绕过) 漏洞通关及源码审计

CSP Bypass CSP Bypass(Content Security Policy Bypass)漏洞涉及的是绕过网站部署的内容安全策略(Content Security Policy,CSP)限制,从而执行潜在的恶意操作。CSP 是一种安全机制,用于防止跨站脚本(XSS)、数据注入攻击等。其通过限制网页能够加载和执行的内容来源…

为你的Blazor程序加入本地化多语言功能

本地化 本地化是为给定语言和地区定制应用程序的过程. BootstrapBlazor 组件允许您将其 UI 元素转换为所需的语言。这包括按钮、过滤器操作符属性等文本。组件内部默认使用当前请求 UI 文化语言,本文将向您展示如何在应用程序中使用此功能: BootstrapBlazor 组件库 简介 Boot…