基于Spring框架怎么构建游戏玩法服务
说明:本篇阐述的问题,是基于前面的游戏服务器架构设计的。
问题
众所周知,Spring最擅长的领域是无状态服务的构建,而游戏(尤其是玩法部分)是有状态的。以棋牌游戏为例,玩法服务里面大概涉及以下两类对象:
1、无状态的服务,比如数据读写、通信等;
2、与游戏桌子绑定的有状态类,比如桌子本身,状态机,玩家的游戏状态等。
后者肯定是要访问前者提供的方法的,那么后者怎么拿到前者的引用呢。
我们一开始的做法是,无状态的服务做成Spring Bean,然后在启动的时候,把这些service的引用放到一个静态了类的字段里面,类似这样:
public class ServiceContainer {
public static ServiceBean1 bean1;
public static ServiceBean2 bean2;
...
public static init(ApplicationContext context)
{
bean1 = context.getBean(ServiceBean1.class);
bean2 = context.getBean(ServiceBean2.class);
...
}
}
然后有状态的对象就可以简单地通过ServiceContainer.bean1来访问无状态的服务了。
不过代码多了以后,发现这种方式实在有点糟糕。 由于对ServiceContainer的访问实在太简单了,导致大家随意地在里面添加新的字段,最后对象之间的耦合依赖非常混乱,完全没有享受到使用Spring的好处。
解决办法
为了解决问题,首先确立一个原则,不允许通过静态方法、静态字段来暴露服务;单例模式当然也不允许(本质还是静态方法),既然用了Spring,就要按Spring的架构哲学来搞。
第一个办法是这样的,在创建一个有状态的对象的时候,如果这个对象需要依赖某些Service,那么在初始化的过程中手动注入进去,以游戏桌table为例,代码类似这样:
public class GameTable {
public ServiceBean1 bean1;
public ServiceBean2 bean2;
...
public init(ApplicationContext context)
{
bean1 = context.getBean(ServiceBean1.class);
bean2 = context.getBean(ServiceBean2.class);
...
}
}
这个方法,虽然看起来和ServiceContainer半斤八两,但实际上要好很多,至少某个玩法的table依赖哪些服务一目了然。不过产品功能复杂性增加以后,table依赖的服务越来越多,还是会让人很不爽。
继续优化方案
table里面注入了太多的service,本质上说明游戏玩法逻辑的拆分不够细。
在前边的文章里面,我们的核心玩法逻辑拆分成table(桌子),state(状态机),messageProcessor(消息处理器),现在重新捋一下这些角色的职责:
1、table以及相关的类是游戏玩法的领域模型,专注于游戏的数据状态和基本规则算法;
2、state状态机用来简化流程控制,专注于消息的过滤,和状态的切换;
3、messageProcessor,专注于消息的处理,服务于玩法的所有桌子,也就是说它是无状态的;
4、其他业务逻辑,比如数据的存取,游戏日志处理,外围功能(比如任务)。
其中table和state都是内存对象,而messageProcessor和其他逻辑都是标准的Service Bean,state将消息过滤后,委托给messageProcessor来处理,依据处理结果来迁移状态。
一个典型的messageProcessor接口可能类似这样的:
public boolean processPlayerJoin(Table table, Player player, Message message)
{
if (玩家是否满足入桌条件)
{
table.addPlayer(player);
return true;
}
return false
}
基于Spring框架怎么构建游戏玩法服务的更多相关文章
- 基于Spring框架应用的权限控制系统的研究和实现
摘 要: Spring框架是一个优秀的多层J2EE系统框架,Spring本身没有提供对系统的安全性支持.Acegi是基于Spring IOC 和 AOP机制实现的一个安全框架.本文探讨了Acegi安全 ...
- 简单Elixir游戏服设计- 游戏玩法介绍
抄以前的,做了点修改. 到目前为止,我们完成了玩家的数据和进程建模,现在介绍游戏玩法. 为什么我们还不做客户端接入.协议指定呢?为什么还没有网关和数据存储呢.在我接手的游戏, 这些通常已经定下来了,我 ...
- 基于Spring框架的简单多数据源切换解决办法
基于Spring框架的简单多数据源切换解决办法 Spring框架JDBC包提供了一个抽象类AbstractRoutingDataSource提供了动态切换数据库的基础方法.我们仅仅需要实现一个简单的数 ...
- 第一次玩博客,今天被安利了一个很方便JDBC的基于Spring框架的一个叫SimpleInsert的类,现在就来简单介绍一下
首先先对这段代码的简单介绍,我之前在需要操作JDBC的时候总是会因为经常要重新写SQL语句感到很麻烦.所以就能拿则拿不能拿的就简单地封装了一下. 首先是Insert.Spring框架的JDBC包里面的 ...
- 基于Spring Boot+Cloud构建微云架构
前言 首先,最想说的是,当你要学习一套最新的技术时,官网的英文文档是学习的最佳渠道.因为网上流传的多数资料是官网翻译而来,很多描述的重点也都偏向于作者自身碰到的问题,这样就很容易让你理解和操作出现偏差 ...
- 轻量级高性能ORM框架:Dapper高级玩法
Dapper高级玩法1: 数据库中带下划线的表字段自动匹配无下划线的Model字段. Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true; 备 ...
- 使用 Spring Cloud Stream 构建消息驱动微服务
相关源码: spring cloud demo 微服务的目的: 松耦合 事件驱动的优势:高度解耦 Spring Cloud Stream 的几个概念 Spring Cloud Stream is a ...
- 基于spring框架的apache shiro简单集成
关于项目的安全保护,我一直想找一个简单配置就能达到目的的方法,自从接触了shiro,这个目标总算达成了,以下结合我使用shiro的经验,谈谈比较轻便地集成该功能. 首先我们先了解一下shiro是什么. ...
- 使用NetBeans搭建基于Spring框架的Web应用
NetBeans下载链接:https://netbeans.org/. 第一步:选择“文件”菜单下的“新建项目”: 第二步:类别选择“Java Web”,项目选择“Web应用程序”,单击“下一步”: ...
随机推荐
- 【SpringMVC】统一异常处理
一.需求 二.统一异常处理解决方案 2.1 定义异常 2.2 异常处理 2.3 配置统一异常处理器 2.4 异常处理逻辑 一.需求 一般项目中都需要作异常处理,基于系统架构的设计考虑,使用统一的异常处 ...
- 如何在github上提交pr
如何在github上提交pr 1.fork开源的代码到自己的远程仓库 2.clone自己的仓库到本地电脑 3.与源代码的github仓库建立新的连接 git remote add upstream h ...
- 直接插入排序算法(java)
直接插入排序是将未排序的数据插入至已排好序序列的合适位置. 具体流程如下: 1.首先比较数组的前两个数据,并排序: 2.比较第三个元素与前两个排好序的数据,并将第三个元素放入适当的位置: 3.比较第四 ...
- Oracle GoldenGate(ogg)安装经验大汇总,采坑总结,绝对干货!
一下是安装ogg过程中遇到的问题和解决办法,绝对良心干货,抽空会写更详细的安装教程.更多精彩内容请点击 OGG-00685 begin time prior to oldest log in log ...
- linux文件权限命令chmod学习
Linux系统中的每个文件和目录都有访问许可权限,用它来确定谁可以通过何种方式对文件和目录进行访问和操作. 文件或目录的访问权限分为只读,只写和可执行三种.以文件为例,只读权限表示只允许读其内容,而禁 ...
- [Abp vNext微服务实践] - 框架分析
一.简介 abp vNext新框架的热度一直都很高,于是最近上手将vNext的微服务Demo做了一番研究.我的体验是,vNext的微服务架构确实比较成熟,但是十分难以上手,对于没有微服务开发经验的.n ...
- jupyter notebook在启动时kernel一直在busy , 无法print
转: https://blog.csdn.net/loovelj/article/details/82184223 一. 问题: 内核一直显示忙碌,连简单的print都不能执行了.然后看后台,最后说” ...
- python中IO多路复用、协程
一.IO多路复用 IO多路复用:检测多个socket是否已经发生变化(是否已经连接成功/是否已经获取数据)(可读/可写) import socket def get_data(key): client ...
- SpringBoot项目的异常
1.问题描述 创建springcloud 项目时候,main报错: Spring Boot Application in default package less… (Ctrl+F1)Inspecti ...
- Robot Framework--接口测试环境搭建
1.安装requests库 (robotframework-requests依赖这个request http client) 执行pip install requests 2. 安装requestLi ...