我应该如何设计一个类,有一些常见的道具/方法,但有些不是



我正在研究一个网络类(聚合),它有多种类型的网络实例(主机,对等等)。所以我有一个问题与availableIp字段因为有些网络类型有,但有些没有。例如,托管网络类型将需要这个字段,所以我必须在构造函数上初始化它,但由于ICommonNetworkInfo没有它,我将不得不将它转换为包含此字段的具体类。因此,我通过创建另一个包含此字段的接口并在需要此字段的具体类上实现,从而制定了自己的解决方案。

interface ICommonNetworkInfo {
val name: String
// I dont want to put availableIp here
// because some network type doesn't have this field
}
interface IHostAddress {
val availableIp: List<String>
}
enum class CloudProvider {
GOOGLE,
AWS,
AZURE
}
data class CloudHostingNetwork(
val cloudProvider: CloudProvider,
override val name: String,
// I only want this common field
// but some other fields will be used later on the service layer
override val availableIp: List<String>
): ICommonNetworkInfo, IHostAddress {
}
data class InternalHostingNetwork(
val employeeId: String,
override val name: String,
// I only want this common field
// but some other fields will be used later on the service layer
override val availableIp: List<String>
): ICommonNetworkInfo, IHostAddress {
}
data class CreateHostingNetworkCommand(
val networkId: String,
val ipv4Cidr: String,
// it can be either internal hosting or cloud hosting or else
val networkInfo: ICommonNetworkInfo
)
abstract class AbstractNetwork() {
lateinit var ipv4Cidr: String
}
class HostingNetwork: AbstractNetwork {
// this field only belong to hosting network
// other network type doesn't have this field
var availableIp: List<String>
constructor(command: CreateHostingNetworkCommand){
// todo ...
this.ipv4Cidr = command.ipv4Cidr
// dirty solution that i made
val temp = command.networkInfo as IHostAddress
// I only want 
availableIp = temp.availableIp
}
}

但是对我来说又脏又复杂。我能做些什么来重构这段代码。有什么设计模式可以完美地解决这个问题吗?

要支持不同类型的网络,以及受限制的层次结构,每种都有不同的参数集,也许您可以在Kotlin中使用sealed class

以你的代码为例:

sealed class Network {
abstract val ipv4Cidr : String
abstract class Hosting : Network() {
abstract val name : String
abstract val availableIp : List<String>
class Cloud(
val cloudProvider : CloudProvider,
override val name : String,
override val availableIp : List<String>,
override val ipv4Cidr : String
): Hosting()
class Internal(
val employeeId : String,
override val name : String,
override val availableIp : List<String>,
override val ipv4Cidr : String
): Hosting()
}
}

从这里开始,我想你可以使用Builder模式作为创建设计模式来创建不同类型的网络实例。