游戏设计模式

单列模式

概念

单例模式是一种创建型设计模式,可以保证一个类只有一个实例,并提供一个访问该实例的全局节点。

优点

  • 可以派生:在单例类的实例构造函数中可以设置以允许子类派生。
  • 受控访问:因为单例类封装他的唯一实例,所以它可以严格的控制其他程序怎样以及何时访问它。
  • 可以获得一个指向该实例的全局访问节点。
  • 仅在首次请求单例对象时对其进行初始化。

缺点

  • 违反了单一职责原则。
  • 单例模式一般不要支持序列化,因为这也有可能导致多个对象实例。
  • 多线程环境下需要进行特殊处理, 避免多个线程多次创建单例对象。

组成

1.单例(Singleton)类声明了一个名为get­Instance的静态方法来返回其所属类的一个相同实例。

2.单例的构造函数必须私有化,即对客户端(Client)隐藏。调用get­Instance方法必须是获取单例对象的唯一方式。

案例

方式1

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

方式2:多线程单例

class SingletonThread
{private SingletonThread() { } //私有化构造private static volatile SingletonThread instance;private static object lockHelper = new Object { };public static SingletonThread GetInstance{get{// 双重校验,为避免额外的性能消耗。if (instance == null){// 当第一个线程运行到这里时,此时会对lock加锁。// 当第二个线程运行该方法时,首先检测到lock加锁状态,该线程就会挂起等待第一个线程解锁。lock (lockHelper){if (instance == null){instance = new SingletonThread();}}}return instance;}}
}

方式3

class SingletonRead
{private SingletonRead() { }//只要访问就会被执行静态构造器,不使用不会进行实例化public static readonly SingletonRead Instance = new SingletonRead();//等价于//public static readonly SingletonRead Instance;//static SingletonRead ()//{//    Instance = new SingletonRead ();//}
}

MVC模式

概念

MVC设计模式一般指MVC框架,M(Model)指数据模型层,V(View)指视图层,C(Controller)指控制层。其设计目的是将M和V的实现代码分离,使同一个程序可以有不同的表现形式。

优点

  • 多视图共享一个模型,大大提高了代码的重用性。
  • MVC三个模块相互独立,松耦合架构。
  • 控制器提高了应用程序的灵活性和可配置性。
  • 有利于软件工程化管理。

 总之,我们通过MVC设计模式最终可以打造出一个松耦合+高可重用性+高可适用性的完美架构。

缺点

  • 原理复杂。
  • 增加了系统结构和实现的复杂性。
  • 视图对模型数据的低效率访问。

MVC并不适合小型甚至中型规模的项目,花费大量时间将MVC应用到规模并不是很大的应用程序,通常得不偿失,所以对于MVC设计模式的使用要根据具体的应用场景来决定。

组成

  • 视图层(View):负责格式化数据并把它们呈现给用户,包括数据展示、用户交互、数据验证、界面设计等功能。
  • 控制层(Controller):负责接收并转发请求,对请求进行处理后,指定视图并将响应结果发送给客户端。
  • 数据模型层(Model):模型对象拥有最多的处理任务,是应用程序的主体部分,它负责数据逻辑(业务规则)的处理和实现数据操作(即在数据库中存取数据)。

案例

新建StudentView.cs、StudentModel.cs和StudentController.cs,分别作为视图层、数据模型层和控制层。

StudentView.cs

using UnityEngine;public class StudentView
{public void PrintStudentDetails(string studentName, string studentRollNo){Debug.Log("Student: ");Debug.Log("Name: " + studentName);Debug.Log("Roll No: " + studentRollNo);}
}

StudentModel.cs

public class StudentModel
{private string name;private string rollNo;public string Name { get => name; set => name = value; }public string RollNo { get => rollNo; set => rollNo = value; }
}

 StudentController.cs

public class StudentController
{private StudentModel model;private StudentView view;public StudentController(StudentModel model, StudentView view){this.model = model;this.view = view;}public void SetStudentName(string name){model.Name = name;}public string GetStudentName(){return model.Name;}public void SetStudentRollNo(string rollNo){model.RollNo = rollNo;}public string GetStudentRollNo(){return model.RollNo;}public void UpdateView(){view.PrintStudentDetails(model.Name, model.RollNo);}
}

新建MVCPatternDemo.cs,实现代码如下:

using UnityEngine;public class MVCPatternDemo : MonoBehaviour
{private void Awake(){StudentModel model = RetrieveStudentFromDatabase();StudentView view = new StudentView();//创建一个视图:把学生详细信息输出到控制台StudentController controller = new StudentController(model, view);controller.UpdateView();controller.SetStudentName("John");//更新模型数据controller.UpdateView();}private static StudentModel RetrieveStudentFromDatabase(){StudentModel student = new StudentModel();student.Name = "Robert";student.RollNo = "10";return student;}
}

输出如下:

观察者模式

概念

观察者模式(发布-订阅模式)属于行为型模式。在程序设计中,观察者模式通常由两个对象组成:观察者和被观察者。当被观察者状态发生改变时,它会通知所有的观察者对象,使他们能够及时做出响应。

优点

解除耦合,让耦合的双方都依赖于抽象,从而使得各自的变化都不会影响另一边的变化。

缺点

在应用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现。

组成

  • 抽象被观察者(Subject):定义了一个接口,包含了注册观察者、删除观察者、通知观察者等方法。
  • 具体被观察者(ConcreteSubject):实现了抽象被观察者接口,维护了一个观察者列表,并在状态发生改变时通知所有注册的观察者。
  • 抽象观察者(Observer):定义了一个接口,包含了更新状态的方法。
  • 具体观察者(ConcreteObserver):实现了抽象观察者接口,存储了需要观察的被观察者对象,并在被观察者状态发生改变时进行相应的处理。

过程

1.观察者(Observer):

观察者将自己注册到被观察者中,被观察者将观察者存放在一个容器里。

2.被观察(Subject):

被观察者发生变化时,从容器中得到所有注册过的观察者,将变化通知观察者。

3.撤销观察

观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。

观察者将自己注册到被观察者的容器中时,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的优点是:假定程序中还有别的观察者,那么只要这个观察者也是相同的接口实现即可。一个被观察者可以对应多个观察者,当被观察者发生变化的时候,他可以将消息一一通知给所有的观察者。基于接口,而不是具体的实现,这一点为程序提供了更大的灵活性。

案例

新建ISubject.cs和IObserver.cs,分别作为抽象被观察者和抽象观察者。

新建ConcreteSubject.cs和ConcreteObserver.cs,分别作为具体被观察者和具体观察者。

脚本内容如下:

ISubject.cs

/// <summary>
/// 抽象被观察者
/// </summary>
public interface ISubject
{/// <summary>/// 添加观察者/// </summary>/// <param name="observer"></param>void AddObserver(IObserver observer);/// <summary>/// 删除观察者/// </summary>/// <param name="observer"></param>void RemoveObserver(IObserver observer);/// <summary>/// 通知观察者/// </summary>/// <param name="message"></param>void NoticeObserver(string message);
}

 IObserver.cs

/// <summary>
/// 抽象观察者
/// </summary>
public interface IObserver
{/// <summary>/// 更新消息/// </summary>/// <param name="message"></param>void UpdateMessage(string message);
}

 ConcreteSubject.cs

using System.Collections.Generic;/// <summary>
/// 具体被观察者
/// </summary>
public class ConcreteSubject : ISubject
{private List<IObserver> observers = new List<IObserver>();//存储观察者的容器public void AddObserver(IObserver observer){observers.Add(observer);}public void RemoveObserver(IObserver observer){observers.Remove(observer);}public void NoticeObserver(string message){for (int i = 0; i < observers.Count; i++){observers[i].UpdateMessage(message);}}
}

ConcreteObserver.cs

using UnityEngine;/// <summary>
/// 具体观察者
/// </summary>
public class ConcreteObserver : IObserver
{private string name;//观察者的名字public ConcreteObserver(string name){this.name = name;}public void UpdateMessage(string message){Debug.Log(name + "---接到消息: " + message);}
}

新建一个MyObserver.cs,内容如下:

using UnityEngine;public class MyObserver : MonoBehaviour
{private void Awake(){ConcreteSubject concreteSubject = new ConcreteSubject();//定义一个主题ConcreteObserver concreteObserver01 = new ConcreteObserver("李先生");//实例化一个观察者ConcreteObserver concreteObserver02 = new ConcreteObserver("王女士");//实例化一个观察者//李先生和王女士订阅该主题concreteSubject.AddObserver(concreteObserver01);concreteSubject.AddObserver(concreteObserver02);concreteSubject.NoticeObserver("俄罗斯和乌克兰打起来了");//通知所有观察者(订阅者)//王女士取消订阅该主题concreteSubject.RemoveObserver(concreteObserver02);concreteSubject.NoticeObserver("国际形势逐步紧张起来");//通知所有观察者(订阅者)}
}

最终输出如下:

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

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

相关文章

小土堆pytorch学习笔记004

目录 1、神经网络的基本骨架-nn.Module的使用 2、卷积操作实例 3、神经网络-卷积层 4、神经网络-最大池化的使用 &#xff08;1&#xff09;最大池化画图理解&#xff1a; &#xff08;2&#xff09;代码实现&#xff1a; 5、神经网络-非线性激活 &#xff08;1&#xf…

预训练语言模型transformer

预训练语言模型的学习方法有三类&#xff1a;自编码&#xff08;auto-encode, AE)、自回归&#xff08;auto regressive, AR&#xff09;&#xff0c;Encoder-Decoder结构。 决定PTM模型表现的真正原因主要有以下几点&#xff1a; 更高质量、更多数量的预训练数据增加模型容量…

NAS系统折腾记 – 申请域名和数字签名

群晖NAS硬件和DSM安装完毕&#xff0c;现在已经可以在家里局域网的环境下正常服务了。下一个问题自然是考虑出门在外的时候&#xff0c;怎样能通过外网远程访问NAS的服务了。为此&#xff0c;我需要给我的NAS服务器申请一个便于记忆的域名&#xff0c;然后配合DDNS服务实现域名…

uniapp微信小程序-input默认字的样式

需要的是这样的 问题 正常是在input框上面写样式就行&#xff0c;但是uniapp不起作用 解决 直接在input上写placeholder-style"color就解决了 <input class"findInput" type"text" placeholder"关键词查询"placeholder-style"co…

【PyTorch】n卡驱动、CUDA Toolkit、cuDNN全解安装教程

文章目录 GPU、NVIDIA Graphics Drivers、CUDA、CUDA Toolkit和cuDNN的关系使用情形判断仅仅使用PyTorch使用torch的第三方子模块 安装NVIDIA Graphics Drivers&#xff08;可跳过&#xff09;前言Linux法一&#xff1a;图形化界面安装&#xff08;推荐&#xff09;法二&#x…

逻辑推理,形式逻辑:且关系,或关系,前加非后不变,箭头和或的转化

国考省考行测&#xff1a;逻辑推理&#xff0c;形式逻辑&#xff1a;且关系考点 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要的还是申论和行测&#xff0c;所以大家认真准备吧&#xf…

2024年Java毕业设计选题大全,500道SpringBoot热门选题大全(持续更新)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

【论文笔记】UniVision: A Unified Framework for Vision-Centric 3D Perception

原文链接&#xff1a;https://arxiv.org/pdf/2401.06994.pdf 1. 引言 目前&#xff0c;同时处理基于图像的3D检测任务和占用预测任务还未得到充分探索。3D占用预测需要细粒度信息&#xff0c;多使用体素表达&#xff1b;而3D检测多使用BEV表达&#xff0c;因其更加高效。 本…

探索机器学习的奥秘

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;网络奇遇记、数据结构 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 机器学习的定义二. 机器学习的发展历程三. 机器学习的原理四. 机器学习的分类…

C#使用Sleep(Int32)方法动态时间

目录 一、涉及到的知识点 1.Sleep(Int32)方法 2.Parallel.Invoke方法 二、 实例&#xff1a;用Sleep方法动态时间 一、涉及到的知识点 在使用线程时&#xff0c;经常会用到Sleep方法&#xff0c;Sleep方法用于将线程挂起指定的时间&#xff0c;时间的单位为毫秒。本实例中将…

VGGNet的结构和复现

1 结构以及模型退化问题 上述为VGGNet的结构图&#xff0c;左边是VGG16D的步骤 16代表16层&#xff0c;有参数的层&#xff0c;其他结构也是如此 对于这6个机构来说&#xff0c;D中的VGG16是最优的&#xff0c;而VGG19相比较而言&#xff0c;没有VGG16优&#xff0c;VGG16有16…

关于获取CISP-PTE一些避坑经历

有幸在今年8月份成功通过CISP-PTE认证,以下是我遇到的一些常见问题,以及一些考点内容以及总结 考试题型 20道选择题 &#xff08;20分&#xff09; 5道基础题 &#xff08;50分&#xff09; 一题一个Key 1道综合大题 (30分) 三个key 线下考试 这次考试是在中国上海,现场大概…

节点的度(Degree of a node)、“入度”(In-degree)、“出度”(Out-degree)

在图论和网络分析中&#xff0c;“节点的度”&#xff08;Degree of a node&#xff09;是指与该节点直接相连的边的数量。在一个无向图中&#xff0c;每条边连接两个节点&#xff0c;对于每个节点来说&#xff0c;它的度就是与它相连的边的总数。在一个有向图中&#xff0c;节…

uniapp scroll-view用法[下拉刷新,触底事件等等...](4)

前言:可滚动视图区域。用于区域滚动 话不多说 直接上官网属性 官网示例 讲一下常用的几个 scroll 滚动时触发 scrolltoupper 滚动到顶部或左边&#xff0c;会触发 scrolltoupper 事件 scrolltolower 滚动到底部或右边&#xff0c;会触发 scrolltolower 事件 1.纵向滚动…

【HTML教程】跟着菜鸟学语言—HTML5个人笔记经验(四)

HTML学习第三天&#xff01; PS&#xff1a;牛牛只是每天花了1.5-2小时左右来学习HTML。 书接上回 HTML<div>和<span> HTML 可以通过<div> 和 <span>将元素组合起来。 HTML 区块元素 大多数 HTML 元素被定义为块级元素或内联元素。 块级元素在浏…

【Git配置代理】Failed to connect to github.com port 443 问题解决方法

前言&#xff1a; 在学习代码审计时&#xff0c;有时会需要使用git去拉取代码&#xff0c;然后就出现了如下错误 看过网上很多解决方法&#xff0c;觉得问题的关键还是因为命令行在拉取/推送代码时并没有使用VPN进行代理。 解决办法 &#xff1a; 配置http代理&#xff1a;…

【Linux】第三十七站:信号保存

文章目录 一、信号发送二、信号保存1.为什么要进行信号保存&#xff1f; 三、阻塞信号1.信号的一些相关概念2.在内核中的表示3.sigset_t4.信号集操作函数5.sigprocmask6.sigpending7. 总结 一、信号发送 如下所示&#xff0c;对于普通信号&#xff0c;它的编号是从1~31。这个是…

指针的深入了解2

1.const修饰指针 在这之前我们还学过static修饰变量&#xff0c;那我们用const来修饰一下变量会有什么样的效果呢&#xff1f; 我们来看看&#xff1a; 我们可以看到编译器报错告诉我们a变成了一个不可修改的值&#xff0c;我们在变量前加上了const进行限制&#xff0c;但是我…

使用py-spy对python程序进行性能诊断学习

py-spy简介 py-spy是一个用Rust编写的轻量级Python分析工具&#xff0c;它能够监视正在运行的Python程序&#xff0c;而不需要修改代码或者重新启动程序。Py-spy可以在不影响程序运行的情况下&#xff0c;采集程序运行时的信息&#xff0c;生成火焰图&#xff08;flame graph&…

linux 基于科大讯飞的文字转语音使用

官方文档地址&#xff1a;离线语音合成 Linux SDK 文档 | 讯飞开放平台文档中心 一、SDK下载 1、点击上面官方文档地址的链接&#xff0c;可以跳转到以下界面。 2、点击“普通版”&#xff0c;跳转到以下界面。 3、点击“下载”跳转到以下界面 4、最后&#xff0c;点击“SDK下…