说明:本篇阐述的问题,是基于前面的游戏服务器架构设计的。

问题

众所周知,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框架怎么构建游戏玩法服务的更多相关文章

  1. 基于Spring框架应用的权限控制系统的研究和实现

    摘 要: Spring框架是一个优秀的多层J2EE系统框架,Spring本身没有提供对系统的安全性支持.Acegi是基于Spring IOC 和 AOP机制实现的一个安全框架.本文探讨了Acegi安全 ...

  2. 简单Elixir游戏服设计- 游戏玩法介绍

    抄以前的,做了点修改. 到目前为止,我们完成了玩家的数据和进程建模,现在介绍游戏玩法. 为什么我们还不做客户端接入.协议指定呢?为什么还没有网关和数据存储呢.在我接手的游戏, 这些通常已经定下来了,我 ...

  3. 基于Spring框架的简单多数据源切换解决办法

    基于Spring框架的简单多数据源切换解决办法 Spring框架JDBC包提供了一个抽象类AbstractRoutingDataSource提供了动态切换数据库的基础方法.我们仅仅需要实现一个简单的数 ...

  4. 第一次玩博客,今天被安利了一个很方便JDBC的基于Spring框架的一个叫SimpleInsert的类,现在就来简单介绍一下

    首先先对这段代码的简单介绍,我之前在需要操作JDBC的时候总是会因为经常要重新写SQL语句感到很麻烦.所以就能拿则拿不能拿的就简单地封装了一下. 首先是Insert.Spring框架的JDBC包里面的 ...

  5. 基于Spring Boot+Cloud构建微云架构

    前言 首先,最想说的是,当你要学习一套最新的技术时,官网的英文文档是学习的最佳渠道.因为网上流传的多数资料是官网翻译而来,很多描述的重点也都偏向于作者自身碰到的问题,这样就很容易让你理解和操作出现偏差 ...

  6. 轻量级高性能ORM框架:Dapper高级玩法

    Dapper高级玩法1: 数据库中带下划线的表字段自动匹配无下划线的Model字段. Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true; 备 ...

  7. 使用 Spring Cloud Stream 构建消息驱动微服务

    相关源码: spring cloud demo 微服务的目的: 松耦合 事件驱动的优势:高度解耦 Spring Cloud Stream 的几个概念 Spring Cloud Stream is a ...

  8. 基于spring框架的apache shiro简单集成

    关于项目的安全保护,我一直想找一个简单配置就能达到目的的方法,自从接触了shiro,这个目标总算达成了,以下结合我使用shiro的经验,谈谈比较轻便地集成该功能. 首先我们先了解一下shiro是什么. ...

  9. 使用NetBeans搭建基于Spring框架的Web应用

    NetBeans下载链接:https://netbeans.org/. 第一步:选择“文件”菜单下的“新建项目”: 第二步:类别选择“Java Web”,项目选择“Web应用程序”,单击“下一步”: ...

随机推荐

  1. element-ui table 默认全选

    来自: https://juejin.im/post/5cf24f1ee51d4577583ddc77 侵删 this.deviceTableData = res.body || []; // con ...

  2. wampserver的使用配置

    1.正常安装就不说了,只需要把安装位置改成需要的位置就可以了.其它的默认就可以了. 2.安装完成之后打开wampserver. 3.现在该修改密码了: (1)点击进入mysql控制台. (2)Wamp ...

  3. 学习到目前,自己封装的db类和pdo类

    DB封装类 <?php class DBDA { public $host = "localhost"; public $uid = "root"; pu ...

  4. axiso 的使用

    Vue官方推荐的ajax请求框架叫做:axios axios的Get请求语法: axios.get("/item/category/list?pid=0") // 请求路径和请求参 ...

  5. ABAP Netweaver体内的那些寄生式编程语言

    今天这篇文章的主题是:寄生. Jerry最近看到朋友圈里一位朋友分享的一张寄居蟹的照片,对于Jerry这种在内地长大的又很宅的人来说,没有机会看到寄居蟹,所以觉得很新鲜: 寄居蟹主要以螺壳为寄体,寄居 ...

  6. python3 excel基本操作及格式设置

    #encoding=utf-8 ''' excel基本操作整理 ''' #openpyxl 版本2.5.4 from openpyxl import * import datetime as dt f ...

  7. JDK源码那些事儿之并发ConcurrentHashMap下篇

    上一篇文章已经就ConcurrentHashMap进行了部分说明,介绍了其中涉及的常量和变量的含义,有些部分需要结合方法源码来理解,今天这篇文章就继续讲解并发ConcurrentHashMap 前言 ...

  8. 高性能集群(HPC

    串行计算与并行计算1.串行计算串行计算是指在单个计算机(拥有单个中央独立单元) 上执行软件写操作.CPU 逐个使用一系列指令解决问题.为了加快处理速度,在原有的串行计算的基础上演变出并行计算2.并行计 ...

  9. glog的安装使用

    参考 :https://blog.csdn.net/Pig_Pig_Bang/article/details/81632962 https://blog.csdn.net/cywtd/article/ ...

  10. jaxa技术2

    XStream 1. 什么作用  * 可以把JavaBean转换为(序列化为)xml 2. XStream的jar包  * 核心JAR包:xstream-1.4.7.jar:  * 必须依赖包:xpp ...