lundi 25 octobre 2021

How should I design a class that has some common props/method, but some are not

I'm working on a network class (aggregate) that has multiple types of network ex. (host, peering etc..). So I have a problem with the availableIp field because some network type does have, but some doesn't. For example hosting network type will need this field so I have to initialize it on the constructor, but since the ICommonNetworkInfo doesn't have it I will have to cast it to concrete class that contain this field. So I make my own solution by creating another interface that contains this field and implement on a concrete class that need this field.

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
  }
}

but it seems dirty and complex for me. what can I do to refactor this code. Are there any design patterns that fit perfectly for this problem.

Aucun commentaire:

Enregistrer un commentaire