Kotlin Code Smell 32 - Repeated Code

Kotlin Code Smell 32 - Repeated Code

Breaking the Chains of Duplication for Elegant and Maintainable Code

Problem

Solution

  1. Find repeated patterns (not repeated code).

  2. Create an abstraction.

  3. Parametrize abstraction calls.

  4. Use composition and avoid inheritance.

  5. Unit test the new abstraction.

Sample Code

Wrong

class WordProcessor(var text: String = "") {
    fun replaceText(patternToFind: String, textToReplace: String) {
        text = "<<< ${text.replace(patternToFind, textToReplace} >>>"
    }
}

class Obfuscator(var text: String = "") {
    fun obfuscate(patternToFind: String, textToReplace: String) {
        text = text.lowercase().replace(patternToFind, textToReplace)
    }
}

Right

class TextReplacer {
    fun replace(
        patternToFind: String,
        textToReplace: String,
        subject: String,
        replaceFunction: (String, String, String) -> String,
        postProcessClosure: (String) -> String
    ): String =
        replaceFunction(patternToFind, textToReplace, subject)
            .let(postProcessClosure)
}

class WordProcessor(private var text: String = "") {
    fun replaceText(patternToFind: String, textToReplace: String) {
        text = TextReplacer()
            .replace(
                patternToFind,
                textToReplace,
                text,
                replaceFunction = { pattern, replace, subject ->
                    subject.replace(pattern, replace)
                },
                postProcessClosure = { "<<< $it >>>" }
            )
    }
}

class Obfuscator(private var text: String = "") {
    fun obfuscate(patternToFind: String, textToReplace: String) {
        text = TextReplacer()
            .replace(
                patternToFind,
                textToReplace,
                text,
                replaceFunction = { pattern, replace, subject ->
                    subject.replace(pattern, replace, ignoreCase = true)
                },
                postProcessClosure = { it.lowercase() }
            )
    }
}

Conclusion

Repeated code is always a smell. Copying and pasting code is always a shame. With our refactoring tools, we need to accept the challenge of removing duplication and trust our tests as a safety net.

Credits

Did you find this article valuable?

Support Yonatan Karp-Rudin by becoming a sponsor. Any amount is appreciated!