当前位置: 首页 > news >正文

游戏设计模式专栏(一):工厂方法模式

引言

大家好,我是亿元程序员,一位有着8年游戏行业经验的主程。

本系列是《和8年游戏主程一起学习设计模式》,让糟糕的代码在潜移默化中升华,欢迎大家关注分享收藏订阅。

在游戏开发中,代码的组织和结构对于项目的可维护性和可扩展性至关重要。一个常见的设计模式,工厂方法模式,可以帮助我们更好地管理游戏对象的创建。本文将介绍工厂方法模式,并通过一个示例来展示如何使用它来改善代码质量。
本文源码和源工程在文末获取,小伙伴们自行前往。

1.工厂方法模式的相关概念

  • 工厂方法模式:一种创建型设计模式,它提供了一种将对象的创建过程封装在子类中的方式,以便在不改变父类代码的情况下创建多个具体类型的对象。该模式将对象的实例化延迟到子类中,从而使得客户端代码不必关心要创建的具体对象类型,只需要通过调用工厂方法来获取对象即可。
  • 开闭原则:面向对象编程中的一个重要设计原则,它由著名的计算机科学家伯特兰·梅耶(Bertrand Meyer)提出,并被引入到软件工程的设计中。开闭原则的核心思想是:对扩展开放和对修改关闭。
  • 对扩展开放(Open for Extension):这意味着在不修改已有代码的情况下,应该能够扩展系统的功能。新功能应该通过添加新的代码来实现,而不是通过修改已有代码。
  • 对修改关闭(Closed for Modification):这表示一旦一个软件实体被创建并投入使用,就不应该再修改它的源代码。任何变化都应该通过扩展而不是修改现有代码来实现。

2.不使用工厂方法模式的糟糕代码

假设我们正在开发一个2D游戏,其中有多种不同类型的敌人需要创建。在没有工厂模式的情况下,我们可能会创建一个函数来手动实例化这些敌人,如下所示:

测试代码如下:

测试结果:

如果我们新增加一个外星人敌人,我们需要在构造函数里面添加对应的代码,以及初始化外星人敌人的相关操作:

新增测试代码:

测试结果如下:

这段代码存在一些问题:

  1. 代码臃肿:随着敌人类型的增多,构造函数会变得越来越复杂,难以维护。
  2. 违反开闭原则:每次添加新的敌人类型都需要修改构造函数,违反了开闭原则(对扩展开放,对修改关闭)。
  3. 可读性差:代码不易阅读和理解,因为创建不同类型的敌人的逻辑混在一起。

3.使用工厂方法模式改善代码

现在,让我们使用工厂方法模式来改善这段代码。工厂方法模式将对象的创建移到单独的工厂类中,每个具体的对象类型都有自己的工厂。以下是使用工厂方法模式的改进代码:

测试代码如下:

测试结果如下:

如果我们新增加一个外星人敌人,我们仅仅需要创建一个具体的外星人敌人类和具体的外星人敌人工厂:

新增测试代码:

测试结果如下:

通过使用工厂方法模式,我们改进了代码的质量:

  1. 代码更清晰:创建对象的逻辑被移到了工厂类中,使代码更加清晰和易于理解。
  2. 符合开闭原则:添加新的敌人类型只需要创建新的敌人类和相应的工厂方法,而不需要修改现有代码,符合开闭原则。
  3. 更易于扩展:可以轻松地添加新的敌人类型,而不会对现有代码产生影响。

结语

工厂方法模式是游戏开发中常用的设计模式之一,可以帮助我们更好地组织和管理对象的创建过程,提高代码的可维护性和可扩展性。通过遵循这种模式,开发者可以更轻松地适应游戏项目的需求变化,同时保持代码的整洁和可读性。

本系列是《和8年游戏主程一起学习设计模式》,让糟糕的代码在潜移默化中升华,欢迎大家关注分享收藏订阅。

我是"亿元程序员",一位有着8年游戏行业经验的主程。在游戏开发中,希望能给到您帮助, 也希望通过您能帮助到大家。

AD:笔者线上的小游戏《贪吃蛇掌机经典》《填色之旅》《重力迷宫球》大家可以自行点击搜索体验。

实不相瞒,想要个在看!请把该文章分享给你觉得有需要的其他小伙伴。谢谢!

GitHub地址:

https://github.com/lswgit/YiyuanGameProgrammingPatterns.git

相关文章:

游戏设计模式专栏(一):工厂方法模式

引言 大家好,我是亿元程序员,一位有着8年游戏行业经验的主程。 本系列是《和8年游戏主程一起学习设计模式》,让糟糕的代码在潜移默化中升华,欢迎大家关注分享收藏订阅。 在游戏开发中,代码的组织和结构对于项目的可…...

element中使用el-steps 进度条效果demo(整理)

<template><div class"margin-top20"><!-- align-center 不要居中就去掉 --><!-- process-status 这几个参数值&#xff1a;改变颜色 wait / process / finish / error / --><!-- active 到第几个是绿色 --><el-steps :space&qu…...

038:mapboxGL 旋转地图(rotateTo)

第038个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中旋转地图。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共68行)相关API参考:专栏目标示例效果 配置方式 1)查看基础设置:https://xiaozhuan…...

java遇到的问题

java遇到的问题 Tomcat与JDK版本问题 当使用Tomcat10的版本用于springmvc借用浏览器调试时&#xff0c;使用JDK8浏览器会报异常。 需要JDK17&#xff08;可以配置多个JDK环境&#xff0c;切换使用&#xff09;才可以使用&#xff0c;配置为JAVA_HOME路径&#xff0c;否则&a…...

LLM(二)| LIMA:在1k高质量数据上微调LLaMA1-65B,性能超越ChatGPT

本文将介绍在Lit-GPT上使用LoRA微调LLaMA模型&#xff0c;并介绍如何自定义数据集进行微调其他开源LLM 监督指令微调&#xff08;Supervised Instruction Finetuning&#xff09; 什么是监督指令微调&#xff1f;为什么关注它&#xff1f; 目前大部分LLM都是decoder-only&…...

Android AMS——创建Application(七)

与在 App 内部启动一个 Activity 的不同之处在于,点击桌面 Launcher 首次启动一个应用程序的时候,会先去创建一个该应用程序对应的进程,然后执行 ActivityThread 的 main() 方法去创建该应用对应的 Application,然后再去启动首页 Activity。前面已经分析了进程的创建和启动…...

html 边缘融合加载

html 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>边缘融合加载</title><style>* {margin: 0;padding: 0;box-sizing: border-box;}body {height: 100vh;padding-bottom: 80px;b…...

ElasticSearch - 在 微服务项目 中基于 RabbitMQ 实现 ES 和 MySQL 数据异步同步(考点)

目录 一、数据同步 1.1、什么是数据同步 1.2、解决数据同步面临的问题 1.3、解决办法 1.3.1、同步调用 1.3.2、异步通知&#xff08;推荐&#xff09; 1.3.3、监听 binlog 1.3、基于 RabbitMQ 实现数据同步 1.3.1、需求 1.3.2、在“酒店搜索服务”中 声明 exchange、…...

Springboot+vue的企业人事管理系统(有报告),Javaee项目,springboot vue前后端分离项目。

演示视频: Springbootvue的企业人事管理系统&#xff08;有报告&#xff09;&#xff0c;Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的企业人事管理系统&#xff0c;采用M&#xff08;model&am…...

初识Java 11-1 函数式编程

目录 旧方式与新方式 lambda表达式 方法引用 Runnable 未绑定方法引用 构造器方法引用 函数式接口 带有更多参数的函数式接口 解决缺乏基本类型函数式接口的问题 本笔记参考自&#xff1a; 《On Java 中文版》 函数式编程语言的一个特点就是其处理代码片段的简易性&am…...

【Ambari】银河麒麟V10 ARM64架构_安装Ambari2.7.6HDP3.3.1问题总结

&#x1f341; 博主 "开着拖拉机回家"带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——&#x1f390;开着拖拉机回家_大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341; 希望本文能够给您带来一定的帮助&#x1f338;文…...

李宏毅机器学习第一课(结尾附作业模型详细分析)

机器学习就是让机器找一个函数f&#xff0c;这个函数f是通过计算机找出来的 如果参数少的话&#xff0c;我们可以使用暴搜&#xff0c;但是如果参数特别多的话&#xff0c;我们就要使用Gradient Descent Regression (输出的是一个scalar数值) Classification &#xff08;在…...

对日项目工作总结

从18年8月到23年中秋节&#xff0c;目前已经入职主营对日车载项目的公司满5年了&#xff0c;一般来说&#xff0c;在一家公司工作工作超过3年&#xff0c;如果是在比较大型以及流程规范的公司&#xff0c;那么该公司的工作流程&#xff0c;工作思维会深深地烙印在该员工的脑海中…...

设计模式探索:从理论到实践的编码示例 (软件设计师笔记)

&#x1f600;前言 设计模式&#xff0c;作为软件工程领域的核心概念之一&#xff0c;向我们展示了开发过程中面对的典型问题的经典解决方案。这些模式不仅帮助开发者创建更加结构化、模块化和可维护的代码&#xff0c;而且也促进了代码的复用性。通过这篇文章&#xff0c;我们…...

【内网穿透】在Ubuntu搭建Web小游戏网站,并将其发布到公网访问

目录 前言 1. 本地环境服务搭建 2. 局域网测试访问 3. 内网穿透 3.1 ubuntu本地安装cpolar 3.2 创建隧道 3.3 测试公网访问 4. 配置固定二级子域名 4.1 保留一个二级子域名 4.2 配置二级子域名 4.3 测试访问公网固定二级子域名 前言 网&#xff1a;我们通常说的是互…...

在cesuim上展示二维模型

前提问题&#xff1a;在cesuim上展示二维模型 解决过程&#xff1a; 1.获取或定义所需变量 2.通过window.cesium.viewer.imageryLayers.addImageryProvider和new Cesium.UrlTemplateImageryProvider进行建模 3.传入url路径后拼接{z}/{x}/{y}.png 4.聚焦到此模型window.ces…...

c/c++中如何输入pi

标准的 C/C 语言中没有π这个符号及常量&#xff0c;一般在开发过程中是通过开发人员自己定义这个常量的&#xff0c;最常见的方式是使用宏定义&#xff1a; 方法1&#xff1a;#define pi 3.1415926 方法2&#xff1a;使用反三角函数const double pi acos(-1.0);...

python爬虫:JavaScript 混淆、逆向技术

Python爬虫在面对JavaScript混淆和逆向技术时可能会遇到一些挑战&#xff0c;因为JavaScript混淆技术和逆向技术可以有效地阻止爬虫对网站内容的正常抓取。以下是一些应对这些挑战的方法&#xff1a; 分析网页源代码&#xff1a;首先&#xff0c;尝试分析网页的源代码&#xf…...

Vue error:0308010C:digital envelope routines::unsupported

vue项目&#xff0c;npm run dev的时候出现&#xff1a;Error: error:0308010C:digital envelope routines::unsupported vue项目&#xff0c;npm run dev的时候出现&#xff1a;Error: error:0308010C:digital envelope routines::unsupported 这个是node的版本问题。我的nod…...

gitee 远程仓库操作基础(一)

git remote add <远程仓库名> <仓库远程地址> :给远程仓库取个别名,简化一大堆字符串操作 git remote add origin xxx.git :取个Origin名字 git remote -v :查看本地存在的远程仓库 git pull <远程仓库名><远程分支名>:<本地分支名> 相同可取消…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

WebRTC调研

WebRTC是什么&#xff0c;为什么&#xff0c;如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...