Book Image

Kotlin Design Patterns and Best Practices - Second Edition

By : Alexey Soshin
Book Image

Kotlin Design Patterns and Best Practices - Second Edition

By: Alexey Soshin

Overview of this book

This book shows you how easy it can be to implement traditional design patterns in the modern multi-paradigm Kotlin programming language, and takes you through the new patterns and paradigms that have emerged. This second edition is updated to cover the changes introduced from Kotlin 1.2 up to 1.5 and focuses more on the idiomatic usage of coroutines, which have become a stable language feature. You'll begin by learning about the practical aspects of smarter coding in Kotlin, as well as understanding basic Kotlin syntax and the impact of design patterns on your code. The book also provides an in-depth explanation of the classical design patterns, such as Creational, Structural, and Behavioral families, before moving on to functional programming. You'll go through reactive and concurrent patterns, and finally, get to grips with coroutines and structured concurrency to write performant, extensible, and maintainable code. By the end of this Kotlin book, you'll have explored the latest trends in architecture and design patterns for microservices. You’ll also understand the tradeoffs when choosing between different architectures and make informed decisions.
Table of Contents (17 chapters)
1
Section 1: Classical Patterns
6
Section 2: Reactive and Concurrent Patterns
11
Section 3: Practical Application of Design Patterns

Understanding Kotlin code structure

The first thing you'll need to do when you start programming in Kotlin is to create a new file. Kotlin's file extension is usually .kt.

Unlike Java, there's no strong relationship between the filename and class name. You can put as many public classes in your file as you want, as long as the classes are related to one another and your file doesn't grow too long to read.

Naming conventions

As a convention, if your file contains a single class, name your file the same as your class.

If your file contains more than one class, then the filename should describe the common purpose of those classes. Use Camel case when naming your files, as per the Kotlin coding conventions: https://kotlinlang.org/docs/coding-conventions.html.

The main file in your Kotlin project should usually be named Main.kt.

Packages

A package is a collection of files and classes that all share a similar purpose or domain. Packages are a convenient way to have all your classes and functions under the same namespace, and often in the same folder. That's the reason Kotlin, similar to many other languages, uses the notion of a package.

The package that the file belongs to is declared using a package keyword:

package me.soshin

Similar to placing classes in files, you can put any package in any directory or file, but if you're mixing Java and Kotlin, Kotlin files should follow Java package rules, as given at https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html.

In purely Kotlin projects, common package prefixes can be omitted from the folder structure. For example, if all your projects are under the me.soshin package, and part of your application deals with mortgages, you can place your files directly in the /mortgages folder and not in the /me/soshin/mortgages folder like Java requires.

There is no need to declare a package for your Main.kt file.

Comments

Going forward, we will be documenting parts of the code using Kotlin comments. Similar to many other programming languages, Kotlin uses // for a single-line comment and /* */ for multiline comments.

Comments are a useful way to provide more context both to other developers and to your future self. Now, let's write our first Kotlin program and discuss how Kotlin's guiding principles are applied to it.

Hello Kotlin

There's no book dedicated to a programming language that can avoid the ubiquitous Hello World example. We're certainly not going to challenge that honored tradition.

To begin learning how Kotlin works, let's put the following code in our Main.kt file and run it:

fun main() {
    println("Hello Kotlin")
}

When your run this example, for example by pressing the Run button in your IntelliJ IDEA, it simply outputs the following:

> Hello Kotlin

There are some interesting attributes in that piece of code in comparison to the following Java code that does exactly the same:

class Main {
    public static void main(String[] args) {
        System.out.println("Hello Java");
    }
}

Let's focus on those attributes in the next sections.

No wrapping class

In Java, C#, Scala, and many other languages, it's necessary to wrap every function in a class for it to become executable.

Kotlin, though, has the concept of package-level functions. If your function doesn't need to access properties of a class, you don't need to wrap it in a class. It's as simple as that.

We'll discuss package-level functions in more detail in the following chapters.

Important Note:

From here on, we'll use ellipsis notation (three dots) to indicate that some parts of the code were omitted to focus on the important bits. You can always find the full code examples at the GitHub link for this chapter.

No arguments

Arguments, supplied as an array of strings, are a way to configure your command-line application. In Java, you cannot have a runnable main() function that doesn't take this array of arguments:

public static void main(String[] args) { ... }

But in Kotlin, those are entirely optional.

No static modifier

Some languages use the static keyword to indicate that a function in a class can be executed without the need to instantiate the class. The main() function is one such example.

In Kotlin, there's no such limitation. If your function doesn't have any state, you can place it outside of a class, and there is no static keyword in Kotlin.

A less verbose print function

Instead of the verbose System.out.println method that outputs a string to the standard output, Kotlin provides us with an alias called println() that does exactly the same.

No semicolons

In Java, and many other languages, every statement or expression must be terminated with a semicolon, as shown in the following example:

System.out.println("Semicolon =>"); 

Kotlin is a pragmatic language. So, instead, it infers during compilation where it should put the semicolons:

println("No semicolons! =>")

Most of the time, you won't need to put semicolons in your code. They're considered optional.

This is an excellent example of how pragmatic and concise Kotlin is. It sheds lots of fluff and lets you focus on what's important.

Important Note:

You don't have to write your code in a file for simple snippets. You can also play with the language online: try https://play.kotlinlang.org/ or use a REPL and an interactive shell after installing Kotlin and running kotlinc.