Proper way to build a hierarchy of immutable classes

I’m not talking about data modifier, just about classes which hold data with minimal functionality (so called Data Transfer Objects).

Kotlin allows to use nice compact syntax to declare a read-only property along constructor field:

open class Parent (
    val prop1: String,
    val prop2: String,
    val prop3: String
)

But if I want to create a hierarchy (which is sometimes very natural), then it gets very repetitive:

class Child1 (
    prop1: String,
    prop2: String,
    prop3: String,
    val prop4: String
) : Parent (prop1, prop2, prop3)

class Child2 (
    prop1: String,
    prop2: String,
    prop3: String,
    prop4: String,
    val prop5: String
) : Child1 (prop1, prop2, prop3, prop4)

The only way to somewhat reduce this repetition that I’ve found is to use an interface for each class and delegation
instead of subclassing:

interface IParent {
  val prop1: String
  val prop2: String
  val prop3: String
}

open class Parent (
    override val prop1: String,
    override val prop2: String,
    override val prop3: String
) : IParent

interface IChild1 : IParent {
  val prop4: String
}

class Child1 (
    parent: IParent,
    override val prop4: String
) : IParent by parent, IChild1

interface IChild2 : IChild1 {
  val prop5: String
}

class Child2 (
    child1: IChild1,
    override val prop5: String
) : IChild1 by child1, IChild2

But it’s not reduced that much and construction of those objects now looks ugly:

val child2 = Child2(
    child1 = Child1(
        parent = Parent(
            prop1 = "p1",
            prop2 = "p2",
            prop3 = "p3"
        ),
        prop4 = "p4"
    ),
    prop5 = "p5"
)

Is there any better way?

1 Like