【问题标题】:How should I design a class that has some common props/method, but some are not我应该如何设计一个有一些常见道具/方法的类,但有些不是
【发布时间】:2021-10-25 19:41:53
【问题描述】:

我正在研究具有多种网络类型的网络类(聚合)。 (主机、对等互连等)。所以我对 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 oop design-patterns solid-principles


    【解决方案1】:

    由于要支持不同类型的网络,以及受限制的层次结构,每个层次结构都有不同的参数集,也许您可​​以在 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 Pattern 作为 Creational Design Pattern 来创建不同类型的网络实例。

    【讨论】:

      猜你喜欢
      • 2016-09-22
      • 1970-01-01
      • 1970-01-01
      • 2016-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-03
      • 1970-01-01
      相关资源
      最近更新 更多