iohao / ioGame

无锁异步化、事件驱动架构设计的 java netty 网络编程框架; 轻量级,无需依赖任何第三方中间件或数据库就能支持集群、分布式; 适用于网络游戏服务器、物联网、内部系统及各种需要长连接的场景; 通过 ioGame 你可以很容易的搭建出一个集群无中心节点、集群自动化、分布式的网络服务器;FXGL、Unity、UE、Cocos Creator、Godot、Netty、Protobuf、webSocket、tcp、socket;java Netty 游戏服务器框架;

Home Page:http://game.iohao.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

业务框架配置 - 关于 action

KING754 opened this issue · comments

commented

你的问题 | 使用场景

public BarSkeletonBuilderParamConfig scanActionPackage(Class<?> actionControllerClass) {
    this.actionControllerClassList.add(actionControllerClass);
    return this;
}

public BarSkeletonBuilderParamConfig scanActionSendPackage(Class<?> actionSendClass) {
    this.actionSendClassList.add(actionSendClass);
    return this;
}

预期值

这两个方法是, 是不是传包名更合理一点.
而且最能支持多个.

实际值

https://www.yuque.com/iohao/game/zm6qg2#xZiyK
image

方法注释
image

内部会获取该类所在包和子包来进行处理。

此外,使用类作为参数有一个优势,即使包名整体改动也不需要关心这部分的配置,因为 idea 会自行处理。如果使用字符串包名的方式配置,则可能会忘记修改,从而需要花费时间排查。

private void scanClass(final List<Class<?>> actionList
, final Predicate<Class<?>> predicateFilter
, final Consumer<Class<?>> actionConsumer) {
for (Class<?> actionClazz : actionList) {
// 扫描
String packagePath = actionClazz.getPackageName();
ClassScanner classScanner = new ClassScanner(packagePath, predicateFilter);
List<Class<?>> classList = classScanner.listScan();
// 将扫描好的 class 添加到业务框架中
classList.forEach(actionConsumer);
}
}

commented

此外,使用类作为参数有一个优势,即使包名整体改动也不需要关心这部分的配置,因为 idea 会自行处理。如果使用字符串包名的方式配置,则可能会忘记修改,从而需要花费时间排查。

感觉各有利弊吧.
比如,我一开始搭建的时候,可能根本还一个action没有写.
只是定义好了一个包.

但是感觉传包,语义上正常一些.传class,框架做了工作(取包的路径,然后加载所有),但是用户层面,感觉有点怪

而且最好是要考虑多个不同包的情况.

比如这样的结构
com.action
|
|-----user
|-----item
|-----other

这种情况,可能com.ation下面是没有具体 action.

还有一种情况
com.gm.action
|
|---html
|---ws
|---gm
com.game.action
|
|---1
|---2

这种情况需要多个.
感觉其实可以参包名的可变数组.

这个不影响,可以定义一个空类放在外部,这样只需要配置一个。

也可以配置多个相关的类,如下

public class DemoLogicServer extends AbstractBrokerClientStartup {
    @Override
    public BarSkeleton createBarSkeleton() {
        // 业务框架构建器 配置
        var config = new BarSkeletonBuilderParamConfig()
                // 扫描 action 类所在包
                .scanActionPackage(UserAction.class)
                .scanActionPackage(ItemAction.class)
                .scanActionPackage(OtherAction.class)
          ;

        // 业务框架构建器
        var builder = config.createBuilder();

        return builder.build();
    }
}
commented

配置空类,感觉就不太科学了.

而且这个理由其实并不成立:
此外,使用类作为参数有一个优势,即使包名整体改动也不需要关心这部分的配置,因为 idea 会自行处理。如果使用字符串包名的方式配置,则可能会忘记修改,从而需要花费时间排查。

那么改包名,是没有问题.
但如果,类移动位置是不是就有问题了.

感觉各有利弊吧.
比如,我一开始搭建的时候,可能根本还一个action没有写.
只是定义好了一个包.

但是感觉传包,语义上正常一些.传class,框架做了工作(取包的路径,然后加载所有),但是用户层面,感觉有点怪


实际中传 class 的优势远大于手写字符串包名的。让我们先看一个项目的目录,结构如下

.
├── UserLogicServer.java
└── action
    └── UserAction.java

比如你现在举的一个例子是没写 action,只定义好了一个包,但又想做配置;那么可以扫描当前类 UserLogicServer,因为框架会扫描该类所在包和子包,那么自然的就解决的没有 action 就想配置的问题了。


如果是手写的包名,就有可能拼接出错;那么如果包名配置错了呢,将会导致扫描不到,这也是手写包名的劣势;如果包名整体改动了,但这部分又忘记改了呢,也将会导致扫描不到,这还是手写包名的劣势。


最重要的是,如果使用字符串包名的方式配置,则可能会忘记修改,从而需要花费时间排查。而使用 class 的方式就不会有这些问题。


如果还没写 action ,可以使用当前游戏逻辑服类当作扫描的参数。

public class UserLogicServer extends AbstractBrokerClientStartup {
    @Override
    public BarSkeleton createBarSkeleton() {
        // 业务框架构建器 配置
        var config = new BarSkeletonBuilderParamConfig()
                // 扫描 action 类所在包
                .scanActionPackage(UserLogicServer.class)
          ;

        // 业务框架构建器
        var builder = config.createBuilder();

        return builder.build();
    }
}

配置空类,感觉就不太科学了.

而且这个理由其实并不成立: 此外,使用类作为参数有一个优势,即使包名整体改动也不需要关心这部分的配置,因为 idea 会自行处理。如果使用字符串包名的方式配置,则可能会忘记修改,从而需要花费时间排查。

那么改包名,是没有问题. 但如果,类移动位置是不是就有问题了.

没啥不科学的,这个回答是基于你的描述的。你可以在 com 建立个空配置类,也可以在 com.gm ,也可以在 com.game 建立个空配置类。这样无论你怎么移动都不影响。

这里还有点搞不懂你的思路,你都改包名了,为什么不改下相关配置呢。

比如这样的结构
com.action
|
|-----user
|-----item
|-----other

这种情况,可能com.ation下面是没有具体 action.

还有一种情况
com.gm.action
|
|---html
|---ws
|---gm
com.game.action
|
|---1
|---2

commented

如果方法改成:setBaseActionClass(Class)/setRootAction,那这样传Class,我觉得比较正常.
哪果方法是scanActionPackage(Class),这样感觉就有点别扭.这样子,感觉就String[] packageNames比较舒服.

只是一个想法和建议.

如果方法改成:setBaseActionClass(Class)/setRootAction,那这样传Class,我觉得比较正常. 哪果方法是scanActionPackage(Class),这样感觉就有点别扭.这样子,感觉就String[] packageNames比较舒服.

只是一个想法和建议.

首先, setXXX 通常指的是设置一次值,这是普遍命名上的常识。而 scanActionPackage 是支持多次使用的,所以 setXXX 系列命名并不适用。

其次,使用 String[] 作为参数,只是放大了之前所讨论的;所以,关于 String 作为参数的缺点这里就不同义反复了。

再次,现有的 api 已经能满足该 issu 所提出的需求了。

最后,如果觉得现有 api 不合理的,建议自行做一次封装来屏蔽现有的 api;通过封装的方式来制定符合你预期的使用方式。