boxmoe_header_banner_img

Hello! 欢迎来到我的博客!

加载中

文章导读

设计模式之单例模式


avatar
xiaoifei 2024年4月1日 416

设计模式概览

  • 创建型模式
    • 抽象工厂模式(Abstract Factory)
    • 建造者模式(Builder)
    • 工厂方法模式(Factory Method)
    • 原型模式(Prototype)
    • 单例模式(Singleton)
  • 结构型模式
    • 适配器模式(Adapter)
    • 桥接模式(Bridge)
    • 组合模式(Composite)
    • 装饰模式(Decorator)
    • 外观模式(Facade)
    • 享元模式(Flyweight)
    • 代理模式(Proxy)
  • 行为型模式
    • 职责链模式(Chain of Responsibility)
    • 命令模式(Command)
    • 解释器模式(Interpreter)
    • 迭代器模式(Iterator)
    • 中介者模式(Mediator)
    • 备忘录模式(Memento)
    • 观察者模式(Observer)
    • 状态模式(State)
    • 策略模式(Strategy)
    • 模板方法模式(Template Method)
    • 访问者模式(Visitor)

单例模式

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象

注意:

  1. 单例类只能有一个实例
  2. 单例类必须自己创建自己的唯一实例
  3. 单例类必须给所有其他对象提供这一实例

示例代码

class Test
{
	private static Test t = new Test();//因为是static所以不会出现循环实例化问题
	public int testInt = 10;
	public static Test T
	{
		get
		{
			return t;
		}
	}
	private Test() { }
}

class Program
{
	static void Main(string[] args)
	{
		Console.WriteLine(Test.T.testInt);
	}
}

 

游戏开发中的单例模式(Unity+IMGUI案例)

在我们制作UI面板的时候,比如开始面板(BeginPanel),设置面板(SettingPanel),提示面板(TipsPanel)等等,通常需要将其设计为单例模式,设计成单例模式有下面的好处:

  1. 不能在外部随便实例化对象创建面板,保证只有一个对象
  2. 随时随地都可以使用,要使用时直接类名.Instance.方法名即可

BeginPanel.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class BeginPanel
{
    //私有的静态成员变量(声明)
    private static BeginPanel instance;
    //公共的静态成员属性或方法(获取)
    public static BeginPanel Instance => instance;
    //声明公共的成员变量 来关联各个控件
    public CustomGUIButton btnBegin;
    public CustomGUIButton btnSettings;
    public CustomGUIButton btnQuit;

    private void Awake() 
    {
        instance = this;//Unity会根据反射自动创建实例化对象,引用到静态私有变量即可
    }
    // Start is called before the first frame update
    void Start()
    {
        btnBegin.clickEvent += () =>
        {
            SceneManager.LoadScene("GameScene");
        };

        btnSettings.clickEvent += () =>
        {
            HideMe();
            SettingPanel.Instance.ShowMe();
        };

        btnQuit.clickEvent += () =>
        {
            Application.Quit();
        };
    }
    public void ShowMe()
    {
        this.gameObject.SetActive(true);
    }

    public void HideMe() 
    {
        this.gameObject.SetActive(false);
    }
}

单例模式结合泛型

由于这些面板中都有相同的特征,那就是关闭(Hide)和显示(Show),为了节约代码减少重复性工作,就需要把他们的特点提取到一个共同的基类(BasePanel)中
但是我们要知道,每一个面板类都是不同的,我们需要再其内部创建一个与自己同名的静态变量,但是提取到BasePanel类后如何用自己的类创建呢,这就需要用到泛型

BasePanel.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BasePanel : MonoBehaviour where T : class
{
    //两个关键的静态成员
    //私有的静态成员变量(声明)、
    private static T instance;
    //公共的静态成员属性或方法(获取)
    public static T Instance => instance;

    private void Awake() 
    {
        instance = this as T;//需要约束
    }

    public virtual void ShowMe()
    {
        this.gameObject.SetActive(true);
    }

    public virtual void HideMe() 
    {
        this.gameObject.SetActive(false);
    }
}

BeginPanel.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class BeginPanel : BasePanel
{
    //声明公共的成员变量 来关联各个控件
    public CustomGUIButton btnBegin;
    public CustomGUIButton btnSettings;
    public CustomGUIButton btnQuit;

    // Start is called before the first frame update
    void Start()
    {
        btnBegin.clickEvent += () =>
        {
            SceneManager.LoadScene("GameScene");
        };

        btnSettings.clickEvent += () =>
        {
            HideMe();
            SettingPanel.Instance.ShowMe();
        };

        btnQuit.clickEvent += () =>
        {
            Application.Quit();
        };
    }
}

要注意Unity中继承了MonoBehaviour的脚本会由Unity来管理自动执行和实例化对象,不需要构造方法,至于成员的初始化可以放在Awake或者Start方法中



评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字
插入代码