• as3+java+mysql(mybatis) 数据自动工具(五)


    现在介绍常量的配置,主要用于客户端(as3)与服务端(java)之间的常量同步,比如错误码、请求标识等

    配置格式:

    <macros name="Macros" groupStart="16" groupEnd="128" bitOffset="20" author="idoublewei" note="宏定义">
        <macro name="SEX_MALE" type="integer" value="0" note="性别:男"/>
        <macro name="SEX_FEMALE" type="integer" value="1" note="性别:女"/>
        <group name="WEEK" type="string" value="week" note="星期">
            <macro name="WEEK_MON" type="string" value="monday" note="星期一"/>
            <macro name="WEEK_TUE" type="string" value="tuesday" note="星期二"/>
        </group>
    </macros>

    常量定义只能有一个根节点 macros,子节点 macro 表示一个常量,子节点 group 同样表示一个常量,但它与其下子节点 macro 有一层特殊的关系,下面在说明 groupStart 和 groupEnd 的时候再详细说明。

    macros : 

    ---name 常量类名 - 必须指定

    ---groupStart 起始分组编号 - 非必须,默认1。解释:有的常量是不关心值的,但必须相互唯一,这时就可以让程序自动计算常量的值,这种常量类型为 integer,该值的意义可见 bitOffset 解释

    ---groupEnd 结束分组编号 - 非必须,默认 Integer.MAX_VALUE,解释同 groupStart

    ---bitOffset 自动计算的常量的有效低位。解释:假设该值取 24,自动计算的常量值为 0x24565842,则该常量的高 8(0x24) 位为分组编号(位于 groupStart 与 groupEnd 之间),后 24(0x565842) 位为常量的有效编号

    ---author 常量类创建者 - 非必须

    ---note 常量类注释 - 非必须

    macro, group : 

    ---name 常量名 - 必须指定

    ---type 常量类型(区分大小写) - 非必须

    ------object 基类

    ------string 字符串

    ------integer 整数

    ------unsigned 非负整数

    ------decimal 小数

    ------bool 布尔值

    ------array 数组,后可接符号 "|" + 元素类型(默认为 object),例如 - array|Integer

    ------date 日期

    ---value 常量值(区分大小写) - 非必须,null 表示空

    ------如果 type 为 bool,则取值:true, false

    ------如果 type 为 array,则取值: new - 新建对象

    ------如果 type 为 date,则取值:new - 新建对象。 ms - 日期毫秒数,后接符号 "|" + 数字,例如 - ms|428, format - 日期字符串,后接符号 "|" + 日期格式字符,例如 - format|14-04-16 20:15:36 637

    ---note 常量注释 - 非必须

    需要注意的是

    ---如果未同时指定 type 和 value,则默认类型为 integer,value 由 groupStart 和 groupEnd 计算

    ---如果未指定 type,但指定了 value,默认类型为 string

    ---如果指定的类型为自定义类,则会原样输出,所以指定为自定义类时,最好将自定义类包路径写上,如 com.vo.MyClass

    这儿这个 groupStart 和 groupEnd 可能会让人有点不好理解。举个例子,每个应用或游戏都会分很多模块,每个模块的相关请求命令都会写到相关的模块类中,比如

    ---用户模块 : 注册请求,登录请求

    ---好友模块 :加好友请求,查询好友请求

    如果这样定义请求常量

    <macros name="ReqMacros" groupStart="1" groupEnd="100" bitOffset="24" author="idoublewei" note="请求命令常量">
    
      <group name="USER_MODULE" note="用户相关请求命令模块">
        <macro name="USER_REGISTER" note="注册用户,参数 : userName, password"/>
        <macro name="USER_LOGIN" note="登录用户,参数 : userName, password"/>
      </group>
    
      <group name="FRIEND_MODULE" note="好友相关请求命令模块">
        <macro name="FRIEND_ADD" note="添加好友"/>
        <macro name="FRIEND_SEARCH" note="查询好友"/>
      </group>
    
    </macros>

    例子中所有的常量都没指定类型 type 和值 value,则会自动计算常量值。自动计算的规则:

    常量值的计算公式 : index + (group << bitOffset)

    ---index 当前分组的第 index 个常量

    ---group 当前分组号,macros 下的直接常量 macro 的分组号从 groupStart 开始,第1个 group 节点的分组号从 groupStart + 1 开始。如果 macros 总的分组大于了 groupEnd - groupStart + 1,则会忽略超出的配置分组

    ---bitOffset (32 - bitOffset)表示常量值的高几位代表该常量的分组号

    根据该配置,可以得到 as3 常量类

    package
    {
        /**
         * 请求命令常量
         * @author idoublewei 2014-05-24 10:03:30
         */
        public class ReqMacros
        {
    
            /** 用户相关请求命令模块 */
            static public const USER_MODULE:int = 33554432;
            /** 注册用户,参数 : userName, password */
            static public const USER_REGISTER:int = 33554433;
            /** 登录用户,参数 : userName, password */
            static public const USER_LOGIN:int = 33554434;
            /** 好友相关请求命令模块 */
            static public const FRIEND_MODULE:int = 50331648;
            /** 添加好友 */
            static public const FRIEND_ADD:int = 50331649;
            /** 查询好友 */
            static public const FRIEND_SEARCH:int = 50331650;
    
        }
    }

    java 常量类

    /**
     * 请求命令常量
     * @author idoublewei 2014-05-24 10:03:30
     */
    public class ReqMacros {
        
        /** 用户相关请求命令模块 */
        static public final int USER_MODULE = 33554432;
        /** 注册用户,参数 : userName, password */
        static public final int USER_REGISTER = 33554433;
        /** 登录用户,参数 : userName, password */
        static public final int USER_LOGIN = 33554434;
        /** 好友相关请求命令模块 */
        static public final int FRIEND_MODULE = 50331648;
        /** 添加好友 */
        static public final int FRIEND_ADD = 50331649;
        /** 查询好友 */
        static public final int FRIEND_SEARCH = 50331650;
        
    }

    我们可以看到

    ---USER_MODULE 常量的值写成16进制为 0x02000000,USER_REGISTER 为 0x02000001,USER_LOGIN 为 0x02000002

    ---FRIEND_MODULE  常量的值写成16进制为 0x03000000,FRIEND_ADD 为 0x03000001,FRIEND_SEARCH 为 0x03000002

    可以看出来,常量值的低 bitOffset 位可作为实际请求命令,剩余的高 (32 - bitOffset) 位可以解释成该请求命令属于哪个模块。这样的常量值定义有什么好处呢?来试着写一下服务端的请求处理吧。

    ---用户请求的处理可以写成 UserFacade,专门处理高 (32 - bitOffset) 位为 2 的请求命令

    ---好友请求的处理可以写成 FriendFacade,专门处理高 (32 - bitOffset) 位为 3 的请求命令

    然后写一个接口 IFacade 定义为请求处理接口,如下

    /**
     * 请求处理接口
     * @author idoublewei
     */
    public interface IFacade {
        
        /**
         * 处理请求
         * @param command 请求命令
         * @param param请求参数
         * @return 请求返回的数据
         */
        Object request(int command, Object param);
        
    }

    那么可以让前面的 UserFacade implements IFacade,FriendFacade implements IFacade,这样所有请求处理都归结到 IFacade 了。然后再定义一个 FacadeMgr 类,专门管理请求的分发,如下

    import java.util.HashMap;
    import java.util.Map;
    
    public class FacadeMgr {
        
        //这个就是配置中的 bitOffset
        private int bitOffset = 24;
        private Map<Integer, IFacade> commandModuleFacadeMap = new HashMap<Integer, IFacade>();
    
        /** 注册模块接口 */
        public void registerFacade(int commandModule, IFacade facade) {
            commandModuleFacadeMap.put(Integer.valueOf(commandModule) >>> bitOffset, facade);
        }
        /** 处理请求 */
        public Object request(int command, Object param) {
            if (commandModuleFacadeMap.containsKey(Integer.valueOf(command >>> bitOffset))) {
                return commandModuleFacadeMap.get(Integer.valueOf(command >>> bitOffset)).request(command, param);
            }
            return null;
        }
        
    }

    可以在服务启动初始化时注册相关请求处理接口

    FacadeMgr facadeMgr = new FacadeMgr();
    facadeMgr.registerFacade(ReqMacros.USER_MODULE, new UserFacade());
    facadeMgr.registerFacade(ReqMacros.FRIEND_MODULE, new FriendFacade());

    当前请求到达时,可以直接请用

    facadeMgr.request(reqCommand, reqParam);
  • 相关阅读:
    redis持久化RDB和AOF
    线程同步的几种方法
    JRE和JDK的区别
    Spring-两种配置容器
    为什么String类是不可变的?
    Oracle 每五千条执行一次的sql语句
    Executor , ExecutorService 和 Executors
    常见框架单例、多例与线程安全性总结
    mysql 的S 锁和X锁的区别
    linux下使用shell脚本自动化部署项目
  • 原文地址:https://www.cnblogs.com/idoublewei/p/3748736.html
Copyright © 2020-2023  润新知