Hands-On Design Patterns with Kotlin - Alexey Soshin - E-Book

Hands-On Design Patterns with Kotlin E-Book

Alexey Soshin

0,0
34,79 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

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.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB
MOBI

Seitenzahl: 305

Veröffentlichungsjahr: 2018

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Hands-On Design Patterns with Kotlin
Build scalable applications using traditional, reactive, and concurrent design patterns in Kotlin
Alexey Soshin
BIRMINGHAM - MUMBAI

Hands-On Design Patterns with Kotlin

Copyright © 2018 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

Commissioning Editor: Richa TripathiAcquisition Editor: Shriram ShekharContent Development Editor: Zeeyan PinheiroTechnical Editor: Ketan KambleCopy Editor: Safis EditingProject Coordinator: Vaidehi SawantProofreader: Safis EditingIndexer: Rekha NairGraphics: Jason MonteiroProduction Coordinator: Aparna Bhagat

First published: June 2018

Production reference: 1130618

Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.

ISBN 978-1-78899-801-7

www.packtpub.com

To Lula Leus, my constant source of inspiration. To my mentor, Lior Bar On. Without you, I would have never started writing.
mapt.io

Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.

Why subscribe?

Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals

Improve your learning with Skill Plans built especially for you

Get a free eBook or video every month

Mapt is fully searchable

Copy and paste, print, and bookmark content

PacktPub.com

Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.

At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.

Contributors

About the author

Alexey Soshin is a software architect with 13 years of experience of making software, mostly for JVM. He started exploring Kotlin even before Kotlin 1.0 was released, and since then, he has been a big enthusiast of the language. He speaks about Kotlin and reactive frameworks at various conferences and meetups and maintains a technical blog. He's also a contributor to Vert.x, a toolkit for building reactive applications onthe Java Virtual Machine.

About the reviewers

Ranga Rao Karanam is a programmer, trainer, and architect. He is the founder of in28Minutes—helping 200,000 learners reskill on Cloud native applications, microservices, evolutionary design, high-quality code, DevOps, BDD, TDD, and refactoring. He loves consulting for startups on the development of scalable component-based cloud-native applications and following modern development practices, such as BDD, continuous delivery, and DevOps.

Ranga likes to play cricket and tennis, and he is a regular hiker. His dream is to spend a year hiking in the Himalayas.

Ganesh Samarthyam is a co-founder of CodeOps Technologies, a software technology, consultancy, and training company based in Bangalore. He has 16 years of experience in the IT industry, and his latest book, Refactoring for Software Design Smells by Morgan Kaufmann/Elsevier, has been translated into Korean and Chinese. Ganesh loves exploring anything and everything about technology in his free time.

Packt is searching for authors like you

If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.

Table of Contents

Title Page

Copyright and Credits

Hands-On Design Patterns with Kotlin

Dedication

Packt Upsell

Why subscribe?

PacktPub.com

Contributors

About the author

About the reviewers

Packt is searching for authors like you

Preface

Who this book is for

What this book covers

To get the most out of this book

Download the example code files

Conventions used

Get in touch

Reviews

Getting Started with Kotlin

Basic language syntax and features

Multi-paradigm

Code structure

No semicolons

Naming conventions

Packages

Types

Type inference

val versus var

Comparison

Null safety

Declaring functions

Control flow

Using the if expression

Using the when expression

String interpolation

Classes and inheritance

Classes

Inheritance

Constructors

Properties

Data classes

More control flow – loops

The for loop

For-each loop

While loop

Extension functions

Introduction to design patterns

What are design patterns?

Design patterns in real life

Design process

Why use design patterns in Kotlin?

Summary

Working with Creational Patterns

Singleton

Factory Method

Factory

Static Factory Method

Advantages of the Static Factory Method

Caching

Subclassing

Static Factory Method in Kotlin

Companion object

Abstract Factory

Abstract Factory in action

Introduction to generics in Kotlin

Back to our bases

Making improvements

Builder

Composing an email

Collection types in Kotlin

Creating an email – first attempt

Creating an email – second attempt

Creating an email – the Kotlin way

Creating an email – the Kotlin way – second attempt

Prototype

Building your own PC

Starting from a prototype

Summary

Understanding Structural Patterns

Decorator

Enhancing a class

Operator overloading

Dude, where's my map?

The great combinator

Caveats

Adapter

Different adapters

Adapters in the real world

Caveats of using adapters

Bridge

Bridging changes

Type aliases

You're in the army now

Constants

A lethal weapon

Composite

Get together

The Squad

Varargs and secondary constructors

Counting bullets

Facade

Keep it simple

Flyweight

Being conservative

Saving memory

Proxy

A short detour into the RMI world

A replacement

Lazy delegation

Summary

Getting Familiar with Behavioral Patterns

Strategy

Fruit arsenal

Citizen function

Switching sides

Iterator

One, two... many

Running through the values

State

Fifty shades of State

State of the Nation

Command

Undoing commands

Chain of responsibility

Interpreter

We need to go deeper

A language of your own

Taking a break

Call suffix

Mediator

Trouble in the Jungle

The middleman

Flavors

Caveats

Memento

Remembrance

Visitor

Writing a crawler

Template method

Observer

Animal Choir

Summary

Functional Programming

Why functional programming?

Immutability

Tuples

Value mutation

Immutable collections

Functions as values

Higher-order functions

Pure functions

Currying

Memoization

Expressions, not statements

Pattern matching

Recursion

Summary

Streaming Your Data

The it notation

The map() function

Filter family

Find family

Drop family

Sort family

ForEach

Join family

Fold/Reduce

Flat family

Slice

Chunked

Zip/Unzip

Streams are lazy, collections are not

Sequences

Summary

Staying Reactive

Reactive principles

Responsiveness

Resiliency

Elasticity

Message-driven

Reactive extension

Hot Observable

Multicast

Subject

ReplaySubject

BehaviorSubject

AsyncSubject

SerializedSubject

Flowables

Holding state

FlowableProcessor

Batching

Throttling

Summary

Threads and Coroutines

Threads

Thread safety

Threads are expensive

Coroutines

Starting coroutines

Jobs

Coroutine starvation

Coroutines under the hood

Fixing starvation

Waiting for a coroutine

Canceling a coroutine

Returning results

Setting timeouts

Parent jobs

Channels

Producers

Actors

Summary

Designed for Concurrency

Active Object

Testing

Deferred value

Barrier

CountDownLatch

Data class as Barrier

Scheduler

Understanding contexts

Pipelines

Establishing a pipeline

The fan-out design pattern

The fan-in design pattern

Managing workers

Buffered channels

Unbiased select

Mutexes

Selecting on close

Sidekick channel

Deferred channel

Summary

Idioms and Anti-Patterns

Let

Apply

Also

Run

With

Instance checks

Try-with-resources

Inline functions

Reified

Constants

Constructor overload

Dealing with nulls

Explicit async

Validation

Sealed, not enumerated

More companions

Scala functions

Summary

Reactive Microservices with Kotlin

Getting started with Vert.x

Routing

Handling requests

Verticles

Subrouting

Testing

Helper methods

Working with databases

Managing configuration

Managing the database

EventBus

Consumer

Producer

More testing

Summary

Other Books You May Enjoy

Leave a review - let other readers know what you think

Preface

Design patterns enable you as a developer to speed up the development process by providing tested, proven development paradigms. Reusing design patterns helps prevent complex issues that can cause major problems and improves your code base, promotes code reuse, and makes the 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. Furthermore, the book provides an in-depth explanation of the classic design patterns, such as Creational, Structural, and Behavioral, before heading into functional programming. It then takes you through Reactive and Concurrent patterns, teaching you about Streams, Threads, and Coroutines to write better code. Toward the end, you will learn about the latest trends in architecture, exploring the design patterns for microservices, and discuss the considerations when choosing between different architectures, such as microservices and MVC.

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 this book is for

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

What this book covers

Chapter 1,Getting Started with Kotlin, covers basic language concepts and syntax, such as types, functions, classes, and flow control structures.

Chapter 2,Working with Creational Patterns, explains what classical creational patterns are embedded into the language and how to implement those that aren't. It discusses Singleton and Factory, among others.

Chapter 3,Understanding Structural Patterns, focuses on how to extend the functionality of our objects and adapt to changes.

Chapter 4,Getting Familiar with Behavioral Patterns, explains how can we alter object behavior at runtime, iteration over complex data structures, and communication between objects using the Observable design pattern.

Chapter 5,Functional Programming, dives into the principles of functional programming and how they fit into Kotlin. Topics such as data immutability and functions as a first-class value will be discussed in depth.

Chapter 6,Streaming Your Data, shows how applying the principles of functional programming help us process potentially infinite streams of incoming data.

Chapter 7, Staying Reactive, explains what reactive principles are and gives extensive examples based on the Reactive Extensions framework, better known as simply Rx.

Chapter 8, Threads and Coroutines, shows how easy it to work with concurrent code in Kotlin, making use of its lightweight thread model.

Chapter 9, Designed for Concurrency, covers design patterns that help us process many tasks at the same time, using coroutines.

Chapter 10, Idioms and Anti-Patterns, provides guidelines on some best practices and pitfalls that you may encounter while developing in Kotlin.

Chapter 11, Reactive Microservices with Kotlin, goes over a detailed example of writing a microservice using Kotlin, Vert.x, and PostgreSQL.

To get the most out of this book

In this book, we assume that the reader has basic knowledge of Java programming language and what JVM is.

It is also assumed that the reader is comfortable working with the command line.

A few command-line examples we use in this book are based on OSX, but could be easily adapted for Windows or Linux.

Download the example code files

You can download the example code files for this book from your account at www.packtpub.com. If you purchased this book elsewhere, you can visit www.packtpub.com/support and register to have the files emailed directly to you.

You can download the code files by following these steps:

Log in or register at

www.packtpub.com

.

Select the

SUPPORT

tab.

Click on

Code Downloads & Errata

.

Enter the name of the book in the

Search

box and follow the onscreen instructions.

Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:

WinRAR/7-Zip for Windows

Zipeg/iZip/UnRarX for Mac

7-Zip/PeaZip for Linux

The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Hands-on-Design-Patterns-with-Kotlin. In case there's an update to the code, it will be updated on the existing GitHub repository.

We also have other code bundles from our rich catalog of books and videos available athttps://github.com/PacktPublishing/. Check them out!

Get in touch

Feedback from our readers is always welcome.

General feedback: Email [email protected] and mention the book title in the subject of your message. If you have questions about any aspect of this book, please email us at [email protected].

Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.

Piracy: If you come across any illegal copies of our works in any form on the Internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.

If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.

Reviews

Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!

For more information about Packt, please visit packtpub.com.

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.

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 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.

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.

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.

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).