Design-Patterns-In-Kotlin icon indicating copy to clipboard operation
Design-Patterns-In-Kotlin copied to clipboard

What about Null Object pattern?

Open johnnyfivedev opened this issue 7 years ago • 5 comments

Will you create a sample for Null Object pattern?

johnnyfivedev avatar Aug 13 '18 10:08 johnnyfivedev

Hi Such pattern isn't actually necessary with Kotlin. See https://kotlinlang.org/docs/reference/null-safety.html for details. Of course, it can be implemented anyway.

jolkdarr avatar Aug 13 '18 17:08 jolkdarr

Just because there's null safety doesn't mean the null object pattern is obsolete. I think one of the main ideas behind the null object pattern is to have a default object in the case that you are required to have an object, but really have nothing to pass to it. NullT has the same interface as T but returns blanks for properties or performs no-ops for all its behaviors, so feasibly you'd want to be able to pass NullT anywhere you could also pass T. Granted you could handle all those cases at the call site, but the benefit of using a null object is that you don't have to.

shekibobo avatar Aug 13 '18 19:08 shekibobo

I agree with @shekibobo, Null Safety and Null Object are orthogonal concepts.

Here is a good description of it https://sourcemaking.com/design_patterns/null_object

On the other hand it is much less used in Kotlin as we have better null handling with ?. and ?: operators.

I will think about example where it fits in Kotlin. I am also happy to accept PR.

dbacinski avatar Aug 13 '18 19:08 dbacinski

to have a default object in the case that you are required to have an object, but really have nothing to pass to it.

This is exactly how I ended up here asking this question :)

johnnyfivedev avatar Aug 14 '18 16:08 johnnyfivedev

Hi

Below, a small snippet (from the Sourcemaking Java example):

import java.io.OutputStream
import java.io.PrintStream

object NullOutputStream : OutputStream() {
    override fun write(b: Int) {
        // do nothing
    }
}

object NullPrintStream : PrintStream(NullOutputStream)

fun doSomething(debugOut: PrintStream) {
    var sum = 0
    for (i in 0..9) {
        sum += i
        debugOut.println("i = $i")
    }
    println("sum = $sum")
}

fun main(args: Array<String>) {
    doSomething(NullPrintStream)  // without debug output
    doSomething(System.out)       // with debug output
}

With elvis operator:

import java.io.PrintStream

fun doSomething2(debugOut: PrintStream? = null) {
    var sum = 0
    for (i in 0..9) {
        sum += i
        debugOut?.println("i = $i")
    }
    println("sum = $sum")
}

fun main(args: Array<String>) {
    doSomething2()             // without debug output
    doSomething2(System.out)   // with debug output
}

jolkdarr avatar Aug 21 '18 11:08 jolkdarr