Search code examples
kotlinoopsolid-principles

Kotlin: can I create an instance of a class in another class declaration (create object as class argument)?


Is it allowed to create an instance of a class in Kotlin inside another class, as an argument?

I'm new to Kotlin and I need to implenet the Single Responsibility Principle of SOLID Principles to this data class Order:

data class Order(
    val id: Long,
    val name: String,
    // ... other properties. 
)

Instead of creating a single class with notificationSender and invoiceGenerator methods, I have two other classes, OrderNotificationSender and OrderInvoiceGenerator, to declare differente responsibilities, according to the SOLID principle:

class OrderNotificationSender {

    fun sendNotification(order: Order) {
        // send order notifications
    }
}

class OrderInvoiceGenerator {

    fun generateInvoice(order: Order) {
        // generate invoice
    }
}

As I followed a tutorial to create this code, my doubt if it is allowed to declare OrderNotificationSender and OrderInvoiceGenerator as HandleOrder arguments, like this:

    class HandleOrder(
    private val orderNotificationSender: OrderNotificationSender,
    private val orderInvoiceGenerator: OrderInvoiceGenerator) 
    {

        fun sendNotification(order: Order) {
            orderNotificationSender.sendNotification(order)
        }

        fun generateInvoice(order: Order) {
            orderInvoiceGenerator.generateInvoice(order)
        }
    }

If this is allowed, what is this called in Kotlin? I don't remember seeing this approach in other programming languages.


Solution

  • You have defined your primary constructor's parameters to also be properties. This is Kotlin syntactic sugar for the dependency injection pattern. In languages that don't have this feature, you would have to initialize your properties with the constructor parameter values, like this:

    class HandleOrder(
        orderNotificationSender: OrderNotificationSender,
        orderInvoiceGenerator: OrderInvoiceGenerator
    ){
    
        private val orderNotificationSender: OrderNotificationSender = orderNotificationSender
        private val orderInvoiceGenerator: OrderInvoiceGenerator = orderInvoiceGenerator
    
        // ...
    }