Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Hands-On Design Patterns with Kotlin
Hands-On Design Patterns with Kotlin

Hands-On Design Patterns with Kotlin: Build scalable applications using traditional, reactive, and concurrent design patterns in Kotlin

eBook
€20.98 €29.99
Paperback
€36.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

Hands-On Design Patterns with Kotlin

Getting Started with Kotlin

In this chapter, we'll cover basic Kotlin syntax, and discuss what design patterns are good for and why they should be used in Kotlin.

The goal of this chapter is not to cover the entire language vocabulary, but to get you familiar with some basic concepts and idioms. The following chapters will slowly expose you to more language features as they become relevant to the design patterns we'll discuss.

In this chapter, we will cover the following topics:

  • Basic language syntax and features
  • Introduction to design patterns

Basic language syntax and features

Whether you come from Java, C#, Scala or any other statically typed programming language, you'll find Kotlin syntax quite familiar. This is not by coincidence, but to make the transfer to this new language as smooth as possible for those with previous experience in other languages. Besides that familiarity, Kotlin brings a vast amount of features, such as better type safety. As we move ahead, you'll notice that all of them are attempting to solve real-world problems. That pragmatic approach is very consistent across the language. For example, one of the strongest sides of Kotlin is complete Java interoperability. You can have Java and Kotlin classes alongside each other, and freely use any library that is available in Java for a Kotlin project.

To summarize, the goals of language are as follows:

  • Pragmatism
  • Having clear syntax
  • Being type-safe
  • Interoperability

The first chapter will discuss how these goals are achieved.

Multi-paradigm

Some of the major paradigms in programming languages are procedural, object-oriented, and functional paradigms.

Being practical, Kotlin allows for any of these paradigms. It has classes and inheritance, coming from the object-oriented approach. It has higher-order functions from functional programming. But you don't have to wrap everything in classes if you don't want to. You can structure your entire code as just a set of procedures and structs. You will see how all these approaches come together, as different examples will use different paradigms to solve the problems discussed.

Code structure

The first thing you'll need to do when you start programming in Kotlin is create a new file. Kotlin's 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.

No semicolons

In Java, every line of code must be terminated with a semicolon:

System.out.println("Hello"); //<- This is a semicolon
System.out.println("World"); //<- I still see you, semicolon

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

println("Hello") //<- No semicolon here
println("World") //<- Not here

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

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 CamelCase when naming your files, as per the Kotlin Coding Conventions: https://kotlinlang.org/docs/reference/coding-conventions.html#naming-rules.

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

Packages

It wouldn't be convenient to have all your classes and functions in the same folder or under the same namespace. That's the reason Kotlin, similar to many other languages, uses the notion of a package.

Like Java, Kotlin uses packages:

package me.soshin.controllers

If you're mixing Java and Kotlin, Kotlin files should follow Java package rules.

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, place your controllers in the /controllers folder and not in the /me/soshin/controllers folder like Java does.

Types

We'll start with the Kotlin type system, and compare it to what Java provides.

The Java examples are for familiarity, and not to prove that Kotlin is superior to Java in any way.

Type inference

Let's define a simple string in Java:

String s = "Hello World";

We defined that s is of type String. But why? Isn't it obvious at this point?

Kotlin provides us with type inference:

val s = "Hello World"

Now, the compiler will decide what type of variable should be used. Unlike interpreted languages (such as JavaScript, Groovy, or Ruby), the type of variable is defined only once. This will not work:

var s = "I'm a string"
s = 1 // s is a String

You may wonder why we've used one var and one val to define the variables. We'll explain it shortly.

val versus var

In Java, variables can be declared final. Final variables can be assigned only once:

final String s = "Hi";
s = "Bye"; // Doesn't work

Kotlin urges you to use immutable data as much as possible. Final variables in Kotlin are simply val:

val s = "Hi"
s = "Bye" // Doesn't work

If you do have a case in which you would like to reassign a variable, use var instead:

var s = "Hi"
s = "Bye" // Works now

Comparison

We were taught very early in Java that comparing objects using == won't produce the expected results, since it tests for reference equality, and we need to use equals() for that.

JVM does string interning to prevent that in some basic cases, so for the sake of the example we'll use new String() to avoid that:

String s1 = "ABC";
String s2 = new String(s1);

System.out.println(s1 == s2); // false

Kotlin translates == to equals():

val s1 = "ABC"
val s2 = String(s1.toCharArray())

println(s1 == s2) // true

If you do want to check for reference equality, use ===:

println(s1 === s2) // false

Null safety

Probably the most notorious exception in the Java world is NullPointerException.

The reason behind this exception is that every object in Java can be null. The code here shows us why:

String s = "Hello";
...
s = null;
System.out.println(s.length); // Causes NullPointerException

In this case, marking s as final would prevent the exception.

But what about this one:

public class Printer {    
public static void printLength(final String s) {
System.out.println(s.length);
}
}

From anywhere in the code it's still possible to pass null:

Printer.printLength(null); // Again, NullPointerException

Since Java 8, there's been an optional construct:

if (optional.isPresent()) {
System.out.println(optional.get());
}

In a more functional style:

optional.ifPresent(System.out::println);

But... it doesn't solve our problem. We can still pass null instead of the proper Optional.empty() and crash the program.

Kotlin checks it even earlier—during compile time:

val s : String = null // Won't compile

Let's go back to our printLength() function:

fun printLength(s: String) {
println(s.length)
}

Calling this function with null won't compile any more:

printLength(null) // Null can not be a value of a non-null type String

If you specifically want your type to be able to receive nulls, you'll need to mark it as nullable using the question mark:

val notSoSafe : String? = null

Declaring functions

Everything is an object in Java. If you have a method that doesn't rely on any state, it still must be wrapped by a class. You're probably familiar with a lot of Util classes in Java that only have static methods, and their only purpose is to satisfy the language requirements and bundle those methods together.

In Kotlin, a function can be declared outside of a class instead of the following code:

public class MyFirstClass {

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

It's enough to have:

fun main(args: Array<String>) {
println("Hello, world!")
}

Functions declared outside of any class are already static.

Many examples in this book assume that the code we provide is wrapped in the main function. If you don't see a signature of the function, it probably should be:
fun main(args: Array<String>).

The keyword to declare a function is fun. The argument type comes after the argument name, and not before. And if the function doesn't return anything, the return type can be omitted completely.

What if you do want to declare the return type? Again, it will come after the function declaration:

fun getGreeting(): String {
return "Hello, world!"
}

fun main(args: Array<String>) {
println(getGreeting())
}

There are lots of other topics regarding function declarations, such as default and named arguments, default parameters, and variable numbers of arguments. We'll introduce them in the following chapters, with relevant examples.

Control flow

One could say that control flow is the bread and butter of writing programs. We'll start with two conditional expressions: if and when.

Using the if expression

Previously it was noted that Kotin likes variables to be assigned only once. And it also doesn't like nulls so much. You probably wondered how that would ever work out in the real world. In Java, constructs such as this are quite common:

public String getUnixSocketPolling(boolean isBsd) {
String value = null;
if (isBsd) {
value = "kqueue";
}
else {
value = "epoll";
}

return value;
}

Of course, this is an oversimplified situation, but still, you have a variable that at some point absolutely must be null, right?

In Java, if is just a statement and doesn't return anything. On the contrary, in Kotlin, if is an expression, meaning it returns a value:

fun getUnixSocketPolling(isBsd : Boolean) : String {
val value = if (isBsd) {
"kqueue"
} else {
"epoll"
}
return value
}

If you are familiar with Java, you can easily read this code. This function receives a Boolean (which cannot be null), and returns a string (and never a null). But since it is an expression, it can return a result. And the result is assigned to our variable only once.

We can simplify it even further:

  1. The return type could be inferred
  2. The return as the last line can be omitted
  3. A simple if expression can be written in one line

So, our final result in Kotlin will look like this:

fun getUnixSocketPolling(isBsd : Boolean) = if (isBsd) "kqueue" else "epoll"

Single line functions in Kotlin are very cool and pragmatic. But you should make sure that somebody else other than you can understand what they do. Use with care.

Using the when expression

What if (no pun intended) we want to have more conditions in our if statement?

In Java, we use the switch statement. In Kotlin, there's a when expression, which is a lot more powerful, since it can embed some other Kotlin features.

Let's create a method that's based on the amount of money that will give cause to suggest a nice birthday gift:

fun suggestGift(amount : Int) : String {
return when (amount) {
in (0..10) -> "a book"
in (10..100) -> "a guitar"
else -> if (amount < 0) "no gift" else "anything!"
}
}

As you can see, when also supports a range of values. The default case is covered by the else block. In the following examples, we will elaborate on even more powerful ways to use this expression.

As a general rule, use when if you have more than two conditions. Use if for simple checks.

String interpolation

What if we would like to actually print those results?

First, as you may have already noticed, in one of the examples above, Kotlin provides a nifty println() standard function that wraps the bulkier System.out.println() from Java.

But, more importantly, as in many other modern languages, Kotlin supports string interpolation using the ${} syntax. Following on from the example before:

println("I would suggest: ${suggestGift(10)} ")

The preceding code would print:

I would suggest: a book

If you're interpolating a variable, and not a function, curly braces could be omitted:

val gift = suggestGift(100)
println("I would suggest: $gift ")

This would print the following output:

I would suggest: a guitar

Classes and inheritance

Although Kotlin is multi-paradigm, it has a strong affinity to the Java programming language, which is based on classes. Keeping Java and JVM interoperability in mind, it's no wonder that Kotlin also has the notion of classes and classical inheritance.

Classes

To declare a class, we use a class keyword, exactly like in Java:

class Player {
}

There's no new keyword in Kotlin. The instantiation of a class simply looks like this:

// Kotlin figured out you want to create a new player
val p = Player()

If the class has no body, as in this simple example, we can omit the curly brackets:

class Player // Totally fine

Inheritance

Exactly like in Java, abstract classes are marked by abstract and interfaces by the interface keyword:

abstract class AbstractDungeonMaster {
abstract val gameName: String

fun startGame() {
println("Game $gameName has started!")
}
}

interface Dragon

As in Java 8, interfaces in Kotlin can have a default implementation of functions, as long as they don't rely on any state:

interface Greeter {
fun sayHello() {
println("Hello")
}
}

There are no inherits and implements keywords in Kotlin. Instead, both the name of an abstract class and all the names of the interfaces that class implements are put after a colon:

class DungeonMaster: Greeter, AbstractDungeonMaster() {
override val gameName: String
get() = "Dungeon of the Beholder"
}

We can still distinguish the abstract class by the parenthesis that comes after its name, and there can still be only one abstract class, as there are no multiple inheritances in Kotlin.

Our DungeonMaster has access to both functions from Greeter and AbstractDungeonMaster:

val p = DungeonMaster()
p.sayHello() // From Greeter interface
p.startGame() // From AbstractDungeonMaster abstract class

Calling the preceding code, it will print the following output:

Hello
Game Dungeon of the Beholder has started!

Constructors

Our DungeonMaster looks a bit awkward now, since it can proclaim the start of only one game. Let's add a non-empty constructor to our abstract class to fix that:

abstract class AbstractDungeonMaster(private val gameName : String) {
fun startGame() {
println("Game $gameName has started!")
}
}

Now, our DungeonMaster must receive the name of the game and pass it to the abstract class:

open class DungeonMaster(gameName: String):
Greeter, AbstractDungeonMaster(gameName)

What if we wanted to extend DungeonMaster by having an EvilDungeonMaster?

In Java, all classes can be extended, unless they're marked final. In Kotlin, no class can be extended, unless it's marked open. The same goes for functions in abstract classes. That's the reason why we declared DungeonMaster as open in the first place.

We'll change AbstractDungeonMaster a bit again to give more power to the evil ruler:

open fun startGame() {
// Everything else stays the same
}

Now, we add the following to our EvilDungeonMaster implementation:

class EvilDungeonMaster(private val awfulGame: String) : DungeonMaster(awfulGame) {
override fun sayHello() {
println("Prepare to die! Muwahaha!!!")
}

override fun startGame() {
println("$awfulGame will be your last!")
}
}

Whereas in Java, @Override is an optional annotation, in Kotlin it is a mandatory keyword.

You cannot hide supertype methods, and code that doesn't use override explicitly won't compile.

Properties

In Java, we are used to the concept of getters and setters. A typical class may look something like this:

public class Person {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

// More methods come here
}

If we want to get a person's name, we call getName(). If we want to change it, we call setName(). That's quite simple.

If we want to set the name only once, during object instantiation, we can specify the non-default constructor and remove the setter as follows:

public class ImmutablePerson {
private String name;

public ImmutablePerson(String name) {
this.name = name;
}

public String getName() {
return name;
}
}

All this dates back to the beginning of Java, somewhere around '95.

But if you've worked with C#, for example, you're probably familiar with the idea of properties. To understand them, let's go to the first example and change it a bit:

public class PublicPerson {
public String name;
}

Reading a person's name is not much shorter: p.name.

Also, changing the name is much more intuitive: p.name = "Alex";.

But by doing so, we lost a lot of control over our object. We cannot make PublicPerson immutable. If we want everybody to be able to read the person's name, they'll also be able to change it at any point in time. And what if later we decide that all names must be uppercase? With setter, we could do that. But not with the public field.

Properties provide a solution for all those problems:

class Person() {
var name : String = ""
}

This may look the same as the Java example, with all its problems. But actually, behind the scenes, it's compiled to a getter and setter pair, just like the first example.

And since properties in Kotlin are translated into getters and setters, we can also control their behavior:

class Person {
var name : String = ""
set(value) {
field = value.toUpperCase()
}
}

Note that we don't need to check that value is null. The String type simply cannot receive nulls.

Coming from Java, it may seem intuitive to use the following assignment: this.name = value.toUpperCase(). But, in Kotlin, this will create a circular dependency. Instead, there's a field identifier that we're using, which is provided automatically.

Data classes

Remember how Kotlin is all about productiveness? One of the most common tasks for Java developers is to create another Plain Old Java Object (POJO). If you're not familiar with POJO, it is basically an object that only has getters, setters, and an implementation of equals or hashCode methods.

This task is so common that Kotlin has it built into the language:

data class User (val username : String, val password : String)

This will generate a class with two getters and no setters (note the val part), which will also implement equals, hashCode, and clone functions in the correct way.

The introduction of data classes is one of the biggest improvements in reducing the amount of boilerplate in the language.

More control flow – loops

Now let's discuss another common control structure—a loop. Loops are a very natural construct for most developers. Without loops, it would be very hard to repeat the same block of code more than once (although we will discuss how to do that without loops in later chapters).

The for loop

The for loop in Java, which prints each character of a string on a new line, may look something like this:

final String word = "Word";
for (int i = 0; i < word.length; i++) {

}

The same loop in Kotlin is:

val word = "Word";
for (i in 0..(word.length-1)) {
println(word[i])
}

Note that while the usual for loop in Java is exclusive (it excludes the last index by definition, unless specified otherwise), the for loop over ranges in Kotlin is inclusive. That's the reason we have to subtract one from the length to prevent overflow (string index out of range): (word.length-1).

If you want to avoid that, you can use the until function:

val word = "Word";
for (i in 0 until word.length) {
println(word[i])
}

Unlike some other languages, reversing the range indexes won't work:

val word = "Word";
for (i in (word.length-1)..0) {
println(word[i])
} // Doesn't print anything

If your intention is to print the word in reverse order, for example, use the downTo function:

val word = "Word";
for (i in (word.length-1) downTo 0) {
println(word[i])
}

It will print the following output:

d
r
o
W

It may seem confusing that until and downTo are called functions, although they look more like operators. This is another interesting Kotlin feature called infix call, which will be discussed later on.

For-each loop

Of course, if you're a bit familiar with Java, you may argue that the previous code could be improved by using a for-each construct instead:

final String word = "Word";

for (Character c : word.toCharArray()) {
System.out.println(c);
}

The same in Kotlin would be:

val word = "Word"

for (c in word) {
println(c)
}

While loop

There are no changes to the while loop functionality, so we'll cover them very briefly:

var x = 0
while (x < 10) {
x++
println(x)
}

This will print numbers from 1 to 10. Note that we are forced to define x as var. In the following chapters, we'll discuss much more idiomatic ways to do this.

The lesser used do while loop is also present in the language:

var x = 5
do {
println(x)
x--
} while (x > 0)

Extension functions

You may have noticed from the previous examples that String in Kotlin has some methods that its Java counterpart is lacking, such as reversed(). How is that achieved, if it's the same String type as in Java and, as we know, String in Java cannot be extended by any other class, since it's declared final?

If you look at the source code, you'll find the following:

public inline fun String.reversed(): String {
return (this as CharSequence).reversed().toString()
}

This feature is called an extension function, and it also exists in some other languages, such as C# or Groovy.

To extend a class without inheriting from it, we prefix the function name, reversed in our example, with a class name we want to extend.

Do note that the extension function cannot override the member function. The inline keyword will be discussed in later chapters.

Introduction to design patterns

Now that we are a bit familiar with basic Kotlin syntax, we can move on to discuss what design patterns are all about.

What are design patterns?

There are different misconceptions surrounding design patterns. In general, they are as follows:

  • Missing language features
  • Not necessary in dynamic language
  • Relevant only to object-oriented languages
  • Relevant only to enterprises

But actually, design patterns are just a proven way to solve a common problem. As a concept, they are not limited to a specific programming language (Java), nor to a family of languages (C-family, for example), nor are they limited to programming in general. You may have even heard of design patterns in software architecture, which discuss how different systems can efficiently communicate with each other. There are service-oriented architectural patterns, which you may know as Service-Oriented Architecture (SOA), and microservice design patterns that evolved from SOA and emerged over the past few years. The future will, for sure, bring us even more design pattern families.

Even in the physical world, outside software development, we're surrounded by design patterns and commonly accepted solutions to a certain problem. Let's look at an example.

Design patterns in real life

Did you ride an elevator lately? Was there a mirror on the wall of the elevator? Why is that?

How did you feel when you last rode an elevator that had no mirror and no glass walls?

The main reason we commonly have mirrors in our elevators is to solve a common problem. Riding in an elevator is boring. We could put in a picture. But a picture would also get boring after a while, if you rode the same elevator at least twice a day. Cheap, but not much of an improvement.

We could put in a TV screen, as some do. But it makes the elevator more expensive. And it also requires a lot of maintenance. We need to put some content on the screen, to make it not too repetitive. So either there's a person whose responsibility is to renew the content once in a while, or a third-party company that does it for us. We'll also have to handle different problems that may occur with screen hardware and the software behind it. Seeing the "Blue Screen of Death" is amusing, of course, but only mildly.

Some architects even go for putting elevator shafts on the building exterior, and making part of the walls transparent. This may provide some exciting views. But this solution also requires maintenance (dirty windows don't make for the best view), and a lot of architectural planning.

So, we put in a mirror. You get to watch an attractive person even if you ride alone. Some studies indicate that we find ourselves more attractive than we are, anyway. Maybe you get a chance to review your appearances one last time before that important meeting. Mirrors visually expand the visual space and make the entire trip less claustrophobic, or less awkward, if it's the start of a day and the elevator is really crowded.

Design process

Let's try and understand what we did just now.

We didn't invent mirrors in elevators. We've seen them thousands of times. But we formalized the problem (riding in an elevator is boring) and discussed alternative solutions (TV screens, glass walls) and the benefits of the commonly used solution (solves the problem, easy to implement). That's what design patterns are all about.

The basic steps of the design process are:

  1. Define exactly what the current problem is.
  2. Consider different alternatives, based on the pros and cons.
  3. Choose the solution that solves the problem, while best fitting your specific constraints.

Why use design patterns in Kotlin?

Kotlin comes to solve the real-world problems of today. In the following chapters, we will discuss both Design Patterns first introduced by the Gang of Four back in '94, as well as design patterns that emerged from the functional programming paradigm.

You'll find that some of the design patterns are so common or useful that they're already built into the language as reserved keywords or standard functions. Some of them will need to combine a set of language features. And some are not so useful any more, since the world has moved forward, and they're being replaced by some other patterns.

But in any case, familiarity with design patterns and best practices expands your "developer toolbox" and creates shared vocabulary between you and your colleagues.

Summary

So, in this chapter, we covered the main goals of the Kotlin programming language.

We went through the variables that are defined, such as val, var, null safety, and type inference. We observed how program flow is controlled by commands such as if, when, for, and while, and we also took a look at the different keywords used to define classes and interfaces: class, interface, data, and abstract class. We learned how to construct new classes and how we inherit from interfaces and implement classes. And finally, we learned what design patterns are good for, and why we need them in Kotlin.

In the next chapter, we'll start discussing the first of the three design pattern families: creation patterns.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Understand traditional GOF design patterns to apply generic solutions
  • Shift from OOP to FP; covering reactive and concurrent patterns in a step-by-step manner
  • Choose the best microservices architecture and MVC for your development environment

Description

Design patterns enable you as a developer to speed up the development process by providing you with proven development paradigms. Reusing design patterns helps prevent complex issues that can cause major problems, improves your code base, promotes code reuse, and makes an architecture more robust. The mission of this book is to ease the adoption of design patterns in Kotlin and provide good practices for programmers. The book begins by showing you the practical aspects of smarter coding in Kotlin, explaining the basic Kotlin syntax and the impact of design patterns. From there, the book provides an in-depth explanation of the classical design patterns of creational, structural, and behavioral families, before heading into functional programming. It then takes you through reactive and concurrent patterns, teaching you about using streams, threads, and coroutines to write better code along the way By the end of the book, you will be able to efficiently address common problems faced while developing applications and be comfortable working on scalable and maintainable projects of any size.

Who is this book for?

This book is for developers who would like to master design patterns with Kotlin to build efficient and scalable applications. Basic Java or Kotlin programming knowledge is assumed

What you will learn

  • • Get to grips with Kotlin principles, including its strengths and weaknesses
  • • Understand classical design patterns in Kotlin
  • • Explore functional programming using built-in features of Kotlin
  • • Solve real-world problems using reactive and concurrent design patterns
  • • Use threads and coroutines to simplify concurrent code flow
  • • Understand antipatterns to write clean Kotlin code, avoiding common pitfalls
  • • Learn about the design considerations necessary while choosing between architectures
Estimated delivery fee Deliver to Greece

Premium delivery 7 - 10 business days

€17.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Jun 15, 2018
Length: 310 pages
Edition : 1st
Language : English
ISBN-13 : 9781788998017
Vendor :
JetBrains
Category :
Languages :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Estimated delivery fee Deliver to Greece

Premium delivery 7 - 10 business days

€17.95
(Includes tracking information)

Product Details

Publication date : Jun 15, 2018
Length: 310 pages
Edition : 1st
Language : English
ISBN-13 : 9781788998017
Vendor :
JetBrains
Category :
Languages :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 110.97
Mastering High Performance with Kotlin
€36.99
Learning Concurrency in Kotlin
€36.99
Hands-On Design Patterns with Kotlin
€36.99
Total 110.97 Stars icon

Table of Contents

12 Chapters
Getting Started with Kotlin Chevron down icon Chevron up icon
Working with Creational Patterns Chevron down icon Chevron up icon
Understanding Structural Patterns Chevron down icon Chevron up icon
Getting Familiar with Behavioral Patterns Chevron down icon Chevron up icon
Functional Programming Chevron down icon Chevron up icon
Streaming Your Data Chevron down icon Chevron up icon
Staying Reactive Chevron down icon Chevron up icon
Threads and Coroutines Chevron down icon Chevron up icon
Designed for Concurrency Chevron down icon Chevron up icon
Idioms and Anti-Patterns Chevron down icon Chevron up icon
Reactive Microservices with Kotlin Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Most Recent
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.1
(9 Ratings)
5 star 33.3%
4 star 44.4%
3 star 22.2%
2 star 0%
1 star 0%
Filter icon Filter
Most Recent

Filter reviews by




Hudson Aug 19, 2020
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
some example are not practical.
Amazon Verified review Amazon
psopen Aug 14, 2020
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
gut erklaert, recht unterhaltsam, wenige Fehler, wenige grafische Darstellungen, Übersicht der Eigenschaften der Patterns sollte verbessert werden
Amazon Verified review Amazon
Jerome Lanteri Apr 05, 2020
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3
Bonne explications, mais encore une fois et de plus en plus je le constate par ailleurs aussi: des erreurs dans les codes. Factory design pattern, à la fin sur les instances appelées... Dommage qu'il soit si fréquent de voir une baisse de qualité sur la rédaction, bâclée, des codes, qui plus est dans un livre qui prétend instruire.Good explications, but again, same as other many books nowadays, some source code examples errors. Look at Factory design pattern, at the end there is errors codes on instances call. Very boring to see a lower job quality to redact poor un checked codes and in the same time, pretend to teach how to write good code.Please, people paid for your job, be more serious and win money honorably.
Amazon Verified review Amazon
Trust Mubaiwa Jan 05, 2020
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
So far I like the book. As a seasoned developer, this is a good book to re affirm the reasons behind some of the design patterns we have been using for years
Amazon Verified review Amazon
Lasse Lindgård Nov 08, 2019
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
I enjoyed the book. It was a quick read and that is a good thing. I have a good understanding of patterns from programming java about 20 years, but it was nice with a to refresh them.It could have been a five star review if the book wasn't so badly edited. Also I found some of the examples were a little thin around the edges. I liked the original GoF book that stuck to examples with building a text editor.I already knew the GoF book, but maybe some of the stuff in the book assumes that you know them a little too well? Maybe sticking a little more to the "templated" approach of the original book would have worked better. Don't show how it is done in java - just show it in kotlin plain and simple.I think a second edition of the book would be worthwhile and could really be the kotlin book to recommend.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela