Netty 游戏开发 -重构 -设计模式实战

先来看几段代码
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
从 解码-> 处理 -> 编码,你会发现我们使用了很多的if或者case,尤其是这个handler处理这一步代码量非常多,还是多功能的耦合在一起,非常不利于业务的拓展以及维护。
略懂设计模式的应该都懂,需要使用设计模式中的工厂模式来优化。

创建对应的工厂,使用hashmap集合来存储

编码器和解码器工厂(消息编码工厂)
在这里插入图片描述
在这里插入图片描述
Handler处理器工厂
在这里插入图片描述

需要获取的话直接使用 map.get来获取对应的value,看这个handlerMap,每个命令需要执行的具体业务就交给一个类来处理,而不是耦合在同一个handler中。
看现在优化完成后,handdler的类一下就简洁了。
在这里插入图片描述
本以为优化到这已经优化完成了,非常完美!!!
但是想要达到架构师的水平还远远不够的,你想想,每次添加新的任务,我都需要执行3步,decoderMap中添加 -> 添加处理器 -> encoderMap中添加,这给用户的体验不是很好哦,有没有什么可以我只要 一步到位 的方法呢?

当然有,只不过对技术水平要求比较高一些。我在初始化的时候 通过反射的方式将一些需要的东西自动添加到 deconderMap 和 encoderMap 当中。

private static void autoInit(Class clazz){
        Class<?>[] declaredClasses = clazz.getDeclaredClasses();
        for (Class<?> innerClazz :declaredClasses){
            if(!GeneratedMessageV3.class.isAssignableFrom(innerClazz)){
                continue;
            }
            String simpleName = innerClazz.getSimpleName();
            simpleName = simpleName.toLowerCase();
            System.out.println(simpleName);

            for (GameMsgProtocol.MsgCode msgCode : GameMsgProtocol.MsgCode.values()) {
                String name = msgCode.name();
                name = name.replaceAll("_", "").toLowerCase();
                if(!name.startsWith(simpleName)){
                    continue;
                }
                try {
                    Object defaultInstance = innerClazz.getDeclaredMethod("getDefaultInstance").invoke(innerClazz);

                    decoderMap.put(msgCode.getNumber(), (GeneratedMessageV3) defaultInstance);

                    //不要误写成 innerClazz.getClass()
                    encoderMap.put(innerClazz, msgCode.getNumber());

                    logger.info(innerClazz.getName() + " <===> " + msgCode.getNumber());
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }
    }

直接在 GameMsgProtocol 中获取 里面的内部类,通过遍历筛选,保存符合业务需求的数据到map中。
看现在只需要调用此函数就ok了,以后添加新的需求,就不需要在map.put如此之麻烦了。
在这里插入图片描述

遇到的问题:
实例.getClass() 获取实例的类型类
对象.class 获取类对象的类型类
Class<?> clazz 是类对象类型类
由于这两个概念的误解导致encoderMap自动注入的失败

总结:
这个思想非常的棒,如果我们想要添加某些业务的话,只需要在直接添加 new Handler,在handlerMapz中添加handler就可以了,方便简洁低耦合,以后哪个功能出问题了直接找对应的Handler类就OK了。
但是这个hadlerMap还是可以优化的哦!可以添加注解,这样就可以直接帮助我们注入到对应的handlerMap中,加油,一步一步来!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值