如何设计部分属性方法通用的类 优化网络类强制类型转换代码
重构方案与适配设计模式
方案1:泛型交叉类型约束(改动最小,最适配当前场景)
你当前使用的CreateHostingNetworkCommand本身就是为托管网络场景设计的,传入的networkInfo天然需要包含availableIp字段,因此可以直接通过Kotlin的泛型交叉类型约束,在编译期就限定传入的networkInfo必须同时实现ICommonNetworkInfo和IHostAddress,完全消除运行时强转的风险:
// 修改CreateHostingNetworkCommand的定义,增加泛型约束 data class CreateHostingNetworkCommand<T>( val networkId: String, val ipv4Cidr: String, val networkInfo: T ) where T : ICommonNetworkInfo, T : IHostAddress
对应的HostingNetwork构造器可以直接取值,无需强转:
constructor(command: CreateHostingNetworkCommand<*>){ this.ipv4Cidr = command.ipv4Cidr availableIp = command.networkInfo.availableIp }
优点:编译期自动校验类型合法性,无运行时异常风险,代码改动量最小。
方案2:密封接口+智能类型转换(适合多网络类型扩展场景)
如果后续需要在同一份流程中处理多种不同的网络类型(比如host、peering等),可以将ICommonNetworkInfo定义为密封接口,利用Kotlin的智能转换能力替代手动强转:
sealed interface ICommonNetworkInfo { val name: String } // 带availableIp的网络类型继承该接口 interface IHostAddress : ICommonNetworkInfo { val availableIp: List<String> } // 其他不带availableIp的网络类型直接实现ICommonNetworkInfo即可 data class PeeringNetwork( override val name: String, val peerAsn: Int ) : ICommonNetworkInfo
使用时通过when分支做类型判断,编译器会自动完成智能转换:
constructor(command: CreateHostingNetworkCommand){ this.ipv4Cidr = command.ipv4Cidr availableIp = when(val info = command.networkInfo) { is IHostAddress -> info.availableIp else -> throw IllegalArgumentException("非法网络类型,缺少availableIp字段") } }
优点:后续新增网络类型时,编译器会自动检测when分支的覆盖度,避免遗漏处理逻辑,类型安全。
方案3:访问者模式(适合多类型复杂处理场景)
如果不同网络类型对应的业务处理逻辑非常多(比如IP计算、带宽核算、权限校验等),可以采用访问者模式将数据结构和业务逻辑分离,避免业务代码中散落大量类型判断分支。
选型建议
- 仅托管网络场景使用当前Command:优先选方案1
- 需要兼容多种网络类型的创建流程:优先选方案2
- 网络类型超过3种,且每种都有大量独立业务逻辑:选方案3
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

