Simplified Private Setters for Data Classes

Our company’s best practice is to create all domain classes with public getters, but private setters - using explicit functions to make modifications to the domain’s state. In kotlin, we have been able to achieve this purpose with code looking like the following:

class Vehicle(
    vehicleId: Int?,
    stateCode: String,
    licensePlate: String?,
    vin: String?,
    makeCode: String,
    colorCode: String,
    typeCode: String?,
    campusOwnerByuId: String?,
    campusTagCode: String?,
    primaryVehicleFlag: Boolean,
    allowNewOwner: Boolean,
    stateOwnerId: String?,
    stateTagCode: String?,
    campusUseCode: String?,
    nickname: String?,
    vehicleYear: String?,
    campusRelationToOwner: String?
) {
    var vehicleId = vehicleId
        private set
    var stateCode = stateCode
        private set
    var licensePlate = licensePlate
        private set
    var vin = vin
        private set
    var makeCode = makeCode
        private set
    var colorCode = colorCode
        private set
    var typeCode = typeCode
        private set
    var campusOwnerByuId = campusOwnerByuId
        private set
    var campusTagCode = campusTagCode
        private set
    var primaryVehicleFlag = primaryVehicleFlag
        private set
    var allowNewOwner = allowNewOwner
        private set
    var stateOwnerId = stateOwnerId
        private set
    var stateTagCode = stateTagCode
        private set
    var campusUseCode = campusUseCode
        private set
    var nickname = nickname
        private set
    var vehicleYear = vehicleYear
        private set
    var campusRelationToOwner = campusRelationToOwner
        private set
}

But I’m sure I don’t have to tell you how monotonous this can get for all of our objects… And we aren’t able to use data classes. It would be really nice to have something like:

data class Vehicle(
    private (set) vehicleId: Int?,
    private (set) stateCode: String,
    private (set) licensePlate: String?,
    private (set) vin: String?,
    private (set) makeCode: String,
    private (set) colorCode: String,
    private (set) typeCode: String?,
    private (set) campusOwnerByuId: String?,
    private (set) campusTagCode: String?,
    private (set) primaryVehicleFlag: Boolean,
    private (set) allowNewOwner: Boolean,
    private (set) stateOwnerId: String?,
    private (set) stateTagCode: String?,
    private (set) campusUseCode: String?,
    private (set) nickname: String?,
    private (set) vehicleYear: String?,
    private (set) campusRelationToOwner: String?
)

like is done in Swift to help out with creating data classes with private setters.

3 Likes

If you have a class where all the properties have private setters this implies that there are other methods that will mutate these values. At that point you don’t really have a plain data class, but you have a class with some (non-trivial) behaviour. That is not a data class anymore, and other assumptions behind data classes may also break (for example a very stable API). You are probably better of creating your own implementations for the various methods.

2 Likes

Thanks for the quick reply.

Two different ideas:

  1. Perhaps I’m misunderstanding the purposes of a data class, but I still believe our use case fits into the example, as the major purpose of these classes is to hold data. We would love to have the functionality of the equals, copy, and toString built into these classes. Also, the only reason for the private setters is to provide better code quality by have methods that mutate the variables instead of repeating the same mutations throughout our code base. Thoughts?

  2. Even if we can’t/shouldn’t use data classes, it would still be nice to have an easier way to set the member variables as having private setters inside the constructor definition, rather than having to have the boilerplate code as shown above.

1 Like