Tech Showcases,
Developer Resources &
Partners
droidcon News
Refactoring Legacy Code With Kotlin
Speaker: Ash Davies
Sources droidcon online 2020
Advanced Kotlin Series Part 1 of 3
Transcript
English
00:00
so hey everybody my name is Ashe Davis
00:03
I'm here to talk to you about
00:05
refactoring legacy code with Colin the
00:09
sort of fundamental basis for this talk
00:10
has come from my experience of using
00:14
Kotlin afresh in a very large Java
00:17
project and observing how people then
00:20
get very excited about one thing he's
00:23
gotten in Java with Java and then in
00:26
replacement with Java so that further
00:30
ado let's get started with the slides so
00:32
this is a refracting legacy code with
00:33
Collin but what what is legacy code how
00:36
do we define that so the definition is
00:39
denoting or relating to software or
00:41
hardware that has been superseded but
00:43
it's difficult to replace because of its
00:45
wide use you might have something
00:47
familiar in your codebase if you have
00:50
been working for it long enough that
00:53
legacy code is no this is a bit of a
00:56
trouble problem that we always have to
00:58
solve at some point however I choose to
01:01
go with a slightly different definition
01:02
and that's the one from the book on
01:05
working effectively with legacy code
01:06
from Michael feathers now in this book I
01:09
mean this goes on to sort of describe
01:11
tests so describe legacy code as being
01:14
anything that is not tested which is
01:17
quite interesting actually and
01:19
furthermore this is justified by the
01:21
position that's if you don't have any
01:24
regression test if you don't have any
01:25
unit tests on your code in place then
01:29
you don't have that confidence available
01:31
in your in your code you don't have the
01:33
confidence to be able to make changes or
01:36
to refactor or to work effectively whose
01:40
legacy code because you can't be sure
01:42
that your changes I'm not going to cause
01:43
a crash or a regression test so I like
01:49
to kind of combine these definitions as
01:51
anything untestable and anything Java
01:53
so let's extra buck onto Java so we all
01:57
know that Android is built upon Java and
01:59
we all probably have quite familiar that
02:01
Java is just quite out of our reach we
02:05
don't get to enjoy all the features
02:07
available in the latest revisions of
02:10
Java I think the stable releases were
02:12
twelve thirteen
02:13
but we're still using we're still
02:16
getting excited about having Java 8 and
02:18
this is because well the JVM is not the
02:20
same as the Android runtime so Google
02:25
has to I've had to optimize the Java
02:28
Runtime to be able to work with low spec
02:30
devices even though by setting more
02:32
powerful these days but you know we have
02:36
different things I'd give an instruction
02:37
sets and more optimized environment so
02:40
it's simply shared an API and it would
02:43
actually have a different runtime
02:44
underneath and it's because of this API
02:46
that's some trigger-happy company likes
02:49
to sue people and I draw your attention
02:51
to this lovely tweet that always makes
02:54
me smile
02:56
you may be able to see who is ranking
02:58
number one so what are these features in
03:02
Java 8 that we kind of quite like to use
03:05
or we sort of enjoy so Java 8 was
03:07
released in 2014 which is what already
03:09
six years ago but we enjoy using lambda
03:12
expressions method references default
03:15
interfaces try with resources and most
03:19
importantly I guess streams because
03:22
streams allow us to them
03:23
fully adopt functional reactive
03:26
programming so with cotton being
03:30
introduced in 2018 as a first-class
03:33
citizen or Android development
03:36
this meant that this sort of changed
03:38
everything this everything changed a
03:39
little bit for Java and : and later as
03:42
well when Colin was announced as a
03:44
preferred language in 2019 this then
03:47
made everyone very very happy
03:50
why is cotton so friggin awesome because
03:53
you have consistently familiar code it's
03:55
much much easier and familiar to read
03:58
and write
03:60
you have idiomatic behavior which means
04:04
that code is going to execute
04:06
automatically to the platform to the
04:08
language I'll go into a bit more detail
04:10
and what any matter code means in a
04:12
minute the code looks person concise
04:15
it's much easier to get a larger
04:18
plantation from much less code if you
04:20
are moving from Java to cotton of you
04:22
have already done this before
04:23
y'all know already how much less code
04:27
you need to write to actually achieve
04:29
the same effect one of the nice things
04:31
as well is that it's under aggressive
04:32
development you'll notice that the
04:34
chephren's team are constantly revising
04:36
or constantly bug fixing and constantly
04:38
updating these features so that whacking
04:41
consistent rollout of new new and very
04:44
exciting features which isn't really
04:46
happening with Java because we have to
04:48
wait for the runtime to be updated
04:50
boertie 40 sugaring to be
04:55
so what's one of the nice things about
04:57
cotton and I jumped ahead I jumped the
04:59
gun with a slide but what's the nice
05:01
things we prefer about : is its use of
05:04
malleability mil ability is often called
05:06
the billion dollar mistake why is that
05:08
and that's because of the author certain
05:12
Eva who believes that the amount of no
05:17
I'm out of pain and damage that null is
05:20
caused over the years is probably
05:21
cemented to that of billions of dollars
05:23
I don't want to argue with all that so
05:28
what are the military look like it's
05:30
pretty much like this you might have
05:31
seen this quite a lot if you work on any
05:34
Java projects or if you've seen any Java
05:36
projects recently you'll know that's
05:38
this is a guarded null check but this is
05:41
also can be considered defensive code so
05:46
what this defensive code offensive code
05:48
is code that's and behave defensively in
05:52
order to preserve the crafter able to
05:56
read the user from experiencing a crash
05:58
now that it doesn't mean that the user
06:00
is going to get a better experience it
06:01
just means that the app is not going to
06:03
crash you're still going to have
06:04
situations where you have a buggy code
06:07
or unexpected behaviors or polymorphic
06:10
behaviors that's just isn't what you
06:12
expect it and the result of this is it's
06:14
really hard to debug so when you compare
06:18
this to we can call the opposite of
06:20
offensive code offensive code
06:25
just like they'll if it compares to
06:27
offensive code which does not it has a
06:30
zero-tolerance policy for errors so our
06:32
low tolerance at least if you've ever
06:34
had to find an error in our X Java stack
06:38
trace you'll be familiar with what I'm
06:39
referring to here because it's really
06:41
hard to find out where the error
06:42
actually happened where the exception
06:44
was originally thrown because it's gone
06:47
down through some chat level chaining
06:49
and level of abstraction so it's really
06:51
hard to find out where actually occurred
06:53
whereas if you have offensive code that
06:56
throws first point of failure
06:58
it's much much easier to find detects
07:01
these things and furthermore I quite
07:04
enjoyed myself because it lends a sense
07:06
of urgency to this feature so if if you
07:09
for example have an unexpected states
07:11
which is causing a crash then you're
07:13
gonna have to deal with it quickly now
07:15
I'm the most scenarios you might think
07:18
that is a negative thing but actually if
07:20
you are able to react so very quickly
07:23
and perhaps these things properly then
07:27
you'll actually find that all the hidden
07:29
bugs that have gone unnoticed for so
07:31
long a time start kind of getting fixed
07:34
getting fixed properly not only with the
07:38
offensive code approach but if you would
07:40
take testing serious as well with it
07:42
you'll find that you're actually less
07:43
likely to get aggression issues so
07:47
practically Kotlin and it's idiom I see
07:49
or a team added features basically
07:52
allowing better readability for a less
07:54
cognitive load what does idiomatic me
07:57
means using containing or donating
07:60
expressions that are natural to a native
08:01
speaker here so don't don't confuse this
08:06
with native speaking as in Rajesh Parker
08:08
or mother tongue
08:10
this isn't referring to a language that
08:13
you and I might speak English German
08:14
French whatever it's referring to : Java
08:17
so it means that you're using
08:20
expressions using features you're using
08:23
language paradigms that are native to
08:25
cotton and that as such means that when
08:28
you as a reviewer coming back to it it's
08:31
much more familiar it's much more
08:32
consistent with the rest of the code
08:37
you can check out documentation on the
08:39
idiomatic use of language features on
08:40
the common man website really recommend
08:43
checked out its resource it's quite long
08:45
it's more of a reference document but
08:47
it's worth having in your bookmarks
08:52
it's what might be these in the middie
08:53
much encode features so we have things
08:55
benefits that consistent being easy to
08:57
read less cognitive load this means it
08:60
takes less less brainpower to actually
09:04
understand what's going on the screen
09:05
and the things you're reading less the
09:07
vacuity it's much clearer what's going
09:09
on you can you don't have to make any
09:10
assumptions or make or do some further
09:14
investigations it's a bit clearer
09:16
function over style if you've had any -
09:21
bike sharing discussions about whether
09:23
to have a parenthesis here or whether to
09:26
use explicit type declarations you'll
09:28
know how painful or how time-consuming
09:30
they can be suited why it's quite
09:33
refreshing to be able to review function
09:35
of the style so that you're actually
09:37
reviewing the behavior of your code
09:40
rather than did I forget indent this
09:43
line here there's also cotton style bag
09:46
here as well where you can check out the
09:49
documentation this is the one from
09:50
Android from Google sorry on the
09:52
recommendation on Android very minor as
09:56
well again like the cotton you might
09:58
take references it's more of a bookmark
10:01
than a thrilling read but nonetheless
10:04
I'd recommend keeping it you can also
10:06
use Katie Linds which is a pinion ated
10:09
linter and they call themselves an
10:11
antique bike sharing mentor but we still
10:13
have conversations on our side and you
10:15
can also use Casey at that katie fmt
10:17
which is a formatting library from
10:18
facebook which will automatically apply
10:20
your formatting rules
10:23
so that's the title of the talk
10:25
refactoring legacy code how can I start
10:28
converting my Java code Kotlin if I
10:30
haven't already or how can I get to that
10:33
elusive 100% cotton State
10:36
well obviously the answer is easy and
10:39
knowing this we can all go home thank
10:42
you all that joke never gets a laugh but
10:46
yeah so we all must probably have used
10:49
the shortcut at some point in our life
10:50
this is the option command shift and K
10:54
this is the shortcut in IntelliJ to
10:57
automatically convert to Colin now this
11:00
on its own can be a useful tool but I'm
11:03
actually going to tell you why you
11:05
probably don't want to use it as the
11:06
only tool in your tool chain because it
11:11
sort of makes a lot of assumptions about
11:12
null ability and and that's the problem
11:14
with automatic conversion is that's not
11:18
everything can be automatic it has to
11:19
make some assumptions by the behavior of
11:21
code because if it changes things from
11:23
being nullable to nominal or for
11:25
immutables being mutable or even change
11:27
the implementation then you might
11:29
actually have regression test introduced
11:30
by a automatic effector which is not
11:34
cool
11:39
so what might that look like
11:41
here's a very popular example from a
11:45
very well-known dependency injection
11:46
framework it's very clear what it's
11:48
doing of course but this is the Java
11:51
code so we apply automatic conversion to
11:53
this and we get something like this now
11:57
notice that our values are malleable and
12:00
they are mutable as well so this is
12:06
because you know it Kotlin can't make
12:08
any change or the idea come in any
12:10
changes to your code because if you are
12:11
setting it null that is permissible in
12:13
Java but we don't know if we're actually
12:14
doing this in Collin so it can't assert
12:17
that about the rest of the state of the
12:18
application furthermore if you continue
12:21
to use this then you have to then use a
12:22
double bang operator to unwrap it or you
12:26
need to require model do some of these
12:30
gymnastics to try and make sure that
12:32
this stays in the correct way you can
12:34
also notice here that we're not using
12:35
internal and that's because Java doesn't
12:37
know about the terminal Howard job
12:38
represent this it can't so Colin sort of
12:42
requires you to do it so crafting
12:45
manually we can make some changes and
12:46
make some improvements here we can make
12:48
use of internal I'm late in it these are
12:50
ready might have features in common so
12:52
we can use them safely then if you want
12:56
to then use it you know if it's not been
12:58
injected or if we have it in failure for
13:00
injection then it's gonna throw an
13:01
uninitialized property exception now you
13:04
might be able to change this and go
13:06
something else like throw a door bang
13:08
throw a nullpointerexception if you
13:10
using it all by an operator or you might
13:13
want to you know act a bit differently
13:15
you could use file is initialized but
13:19
it's important to remember that this is
13:20
again in defensive code it's basically
13:23
the same as a null check so you're not
13:26
actually getting the best benefit you
13:29
can from colin here so actually it's
13:32
probably better to just stick with the
13:33
original and go with offensive code
13:35
because this is going to throw an
13:36
exception as soon as this is no as soon
13:39
as it detects that you can't actually
13:40
execute this method on this member
13:42
because does exist
13:44
but we can do better than this we can
13:46
provide more contextual information so
13:48
we say require not null heater this is a
13:50
function available in common checks and
13:52
asserts the state of the provided value
13:55
and then you can also provide a message
13:57
that will then give the consumer more
13:59
information about why this was not and
14:01
this is really useful because it allows
14:03
you to obviously provide some context
14:04
and information if you're familiar with
14:06
the methods being made available on
14:10
Android X fragment and activity
14:13
libraries you'll know that there are now
14:15
things like require context require
14:18
activity or require B by ID what happens
14:22
in these functions is that they check
14:23
for null ability and then it throws in
14:24
it usually in the legal argument
14:26
exception legal state exception sorry
14:28
with an explanation saying viewers not
14:31
attached view is not a child that this
14:32
parent or such this actually gives you
14:35
some more useful information rather than
14:36
just a null pointer see you connection
14:39
and go and debug it with a bit more
14:40
efficacy
14:43
you can go one step further and actually
14:45
use the Elvis operator as well and then
14:48
you can actually build your own custom
14:50
exception which is really nice actually
14:52
because you can then provide additional
14:53
data you can modify the stack trace you
14:56
can add reporting data if necessary and
14:59
you can really have like a lot of
14:60
control over what's doing this and I
15:02
started using this approach myself in a
15:04
code but when I started doing this it
15:05
reminded me of a xkcd comic which I'd
15:08
like to share with you and that is that
15:10
of an unreachable state so I'll give you
15:13
a second to read it but teal teal they
15:15
are never right error messages tired
15:28
cool so another idiomatic feature we can
15:32
make use of in Colin applies to beans
15:35
and these are Java beans not coffee
15:37
beans so you might be familiar with a
15:41
basic user class or a basic class with
15:44
some like a basic POJO class have
15:46
getters and setters implementation for
15:49
equals and hashcode and some
15:51
constructors and private values so we
15:54
run the automatic conversion over this
15:56
and we get something like this
15:58
notice that our values are actually
16:01
still mutable and they're still novel
16:04
but what has not gotten rid of us for us
16:06
even though we could lean on the
16:10
compiler here is that we still have this
16:12
equals and hashcode function now the
16:14
reason that for this is because what
16:16
could be an IDE does not know if you're
16:21
implantation of equals or hash code is
16:23
going to differ from that generated
16:25
compiler so if you're making use of
16:27
these in a way that might not be typical
16:31
then that I can actually turn into you
16:33
some aggression issues so it's not safe
16:36
for them I didn't need to actually make
16:37
that assumption which is why you're then
16:39
gonna have to go in yourself and then
16:40
modify these and update it so first off
16:43
let's let's make it data class so that
16:46
we have these implementations directed
16:48
for us and it's get rid of the
16:50
mutability let's make them values and
16:52
let's remove null abilities so that we
16:54
can then use
16:56
values there's lots more about dates of
16:59
classes that i can get into but that's
17:02
more I guess basic cotton so but there's
17:07
a reason why you have to sort of hand
17:08
code this rather than relying on this
17:10
what's nice conversion so further if you
17:13
make features as you probably aware of
17:16
our extensions no extensions are really
17:18
fun to use some but I think we're
17:20
probably already using them quite
17:22
widespread there's an example a really
17:24
great example in the Android X KTX
17:27
library or core KTX library for shared
17:29
preferences so you might be familiar
17:32
with this shared preferences mechanism
17:34
already so you you call edits to
17:36
retrieve an editor and you put the
17:38
appropriate values that you want to set
17:40
and then you apply your commits
17:41
depending on what your requirements are
17:44
but the Analects library provides this
17:46
function you can see that it's in line
17:49
so this is actually going to get in
17:50
lines to your call sites so there's very
17:53
little overhead of actually calling this
17:55
function and then in doing so you can
17:58
sort of start building this domain
18:00
language that looks a bit more idiomatic
18:03
to Colin so you have this lambda
18:06
function that actually has your
18:07
behaviour inside of it now looking at
18:09
this it's much clearer in a it ematic
18:12
Colin fashion that it was looking at
18:14
this which is that's more Java style so
18:21
moving on
18:22
you can catch a full list of the cotton
18:25
idioms at the cotton land old web sites
18:27
I'll go over a few quick leave now but
18:29
we have things like default values where
18:31
you can specify the diva value in a
18:33
overloaded method so this might be the
18:38
Chivas in Java by declaring the the
18:40
method multiple times with different
18:43
sets of parameters here you can actually
18:44
just use default parameters and collapse
18:46
it all into a single signature you have
18:48
singleton objects single objects are
18:52
often sort of an anti-pattern in some
18:54
ways but they are often actually quite
18:57
useful in some other ways so you can
18:60
consider them as objects as more
19:02
consistent with cotton style strain
19:05
interpolation is one of the most
19:09
favorite features I've heard of promo
19:12
from Java developers and that's been
19:13
able to convince plates variables and
19:16
expressions into a string concatenation
19:19
which then goes on to use a string
19:22
builder on the hood which is really
19:24
useful and it's much more easier to read
19:27
these structuring is so beautiful as
19:30
well if you have a class like a pair or
19:33
day to class where it has sequential
19:35
components then you could then sort of
19:37
explode into individual variables this
19:39
exists in many other languages as well
19:41
have scoped functions as well now
19:44
arguably you could say that scoped
19:46
functions are from misused or they're
19:48
abused in some ways but I think if you
19:51
use them appropriately they can be quite
19:53
powerful and useful to your Collin idiom
19:57
vocabulary
19:59
some of the questions have actually
20:01
received a lot of it as well about
20:02
kalla-nohra factoring and moving into
20:04
college nits maintaining the get history
20:05
so if you have a lot of good history in
20:08
your upholstery about you know how this
20:09
kind of class came to be or what reasons
20:12
were given for a back ring and all this
20:14
rich history then you have would get
20:16
that you do not want to lose so if you
20:19
then migrate a file or convert a file
20:21
automatically and you might actually
20:23
then lose that history because you're
20:25
rewriting the whole file now this is
20:28
possible to achieve you could then you
20:31
can use get to rename the Java file to a
20:34
color file and one commits to commit
20:36
that and then do the column conversion
20:38
and then commit that if you're using get
20:41
squashing then remember that the entire
20:45
pull request will appear as a single
20:46
commits in your master history for this
20:49
to work you have to have them as
20:51
separate commits in the master history
20:52
not in your PR history so they have to
20:55
be separate PRS if you are using git
20:58
squashing but I would actually argue
21:01
against this I think this is often a
21:05
lazy way of converting to Kotlin what I
21:08
would actually much much much more
21:10
recommend is refracting you know losing
21:14
the title of the talk refactoring Alexa
21:17
code through conversion this has a
21:20
really beneficial aspect really kind of
21:25
useful
21:25
a side effect as well is that it gives
21:28
you a much better perception a much
21:31
better understanding of the code around
21:33
migrating instead of blindly moving it
21:36
over to covered so let's cover quickly
21:38
what principles you might want to
21:40
consider when doing when performing
21:42
abstractions and factoring
21:45
[Music]
21:47
so you may or may not have heard of
21:48
solid design principles before for those
21:51
that are that have heard of it it's
21:53
actually quite a tired table talking
21:56
points so I'll try and be brief when I'm
21:58
covering it here so solid design
22:00
principles obviously make up five
22:02
different principles they have similar
22:04
responsibilities open/closed
22:06
this cough substitution and interface
22:08
segregation and find dependency
22:10
inversion and what we can what we can
22:13
see from these principles is that
22:16
whoever named them really wanted to have
22:18
that acronym so but basically the only
22:25
one you really need to be concerned
22:26
about is single responsibility principle
22:28
make sure your classes are not doing too
22:30
much they have more than one
22:31
responsibility to think about how you
22:32
can abstract it and break it up into
22:35
different classes and always remember
22:36
that Uncle Bob is watching you because
22:40
you should be practicing these things
22:41
anyway so what does this lend us it
22:46
gives us a better perspective on the
22:49
code that we're factoring we have to
22:50
then actually understand what's going on
22:51
we we see it from a fresh light this is
22:53
the same reason that we perform all
22:55
these katha exercises or these cones or
22:57
these dojos or whatever you want to call
23:00
Molly's kind of repetitive coding
23:02
challenges to kind of hone our skills
23:04
because the more you repeat yourself
23:06
over a single task the different
23:09
solutions you're going to find to the
23:10
different ways you can find to approach
23:13
this problem and then you might actually
23:15
find that when you're then we addressing
23:17
this problem or refactoring that's well
23:19
the original solution was may be
23:22
inefficient but could be improved
23:26
so having a different perspective on
23:27
your code is actually really really
23:28
beneficial you can have a better
23:30
understanding of like why this code
23:32
exists and this might be due to business
23:35
concerns and product owner thought it
23:39
was useful whatever but you have to
23:42
actually understand that the business
23:43
value of this of this code and in some
23:46
cases you can actually remove code which
23:47
is even nicer that you can just remove
23:49
Java code that happens my khatma code
23:51
let's see that's the best case scenario
23:55
another thing I quite liked about this
23:57
is that static isn't so much of a thing
23:59
in Collin it's it's less it's sort of
24:01
passively discouraged which is really
24:05
quite nice because static is really
24:08
difficult to test it's really difficult
24:10
to substitute any dependencies in a
24:12
static method or even mock that method I
24:14
mean I know it's possible but you have
24:17
to jump through all these hoops to
24:18
achieve it and it's just difficult to
24:21
work with so if you are passively
24:23
discouraged from using static then you
24:25
actually passively encourage into using
24:27
better paradigms which are more testable
24:29
easy-to-use and give you more stability
24:33
so asynchronicity I'm gonna go into this
24:37
in the next slide but as we probably all
24:40
are familiar with coding a
24:43
synchronization is hard or concurrency
24:46
is hard sorry iso concurrency what is
24:50
concurrency concurrency is management of
24:52
threads and making sure that you have
24:54
the expected states and not to be
24:58
confused with parallelism parallelism is
24:60
where you can have a look at this
25:03
definition right the parallelism is
25:04
where you can have a tasks that can
25:05
operate on individual environments think
25:08
are things like CPUs which have
25:10
different cause they have transforming
25:12
and parallel
25:13
whereas concurrency is tasks that can
25:15
start the same time but finish it in
25:18
different times and then overlap
25:19
sometimes as well if you have the
25:22
resources of course in in this
25:25
environment might end up with race
25:27
conditions you have a shared mutable
25:28
state you might have threading issues
25:30
you might have blocking issues you might
25:34
even add a double with a deadlock
25:38
so how do we start a single a
25:40
traditional thread in Java well it's
25:43
actually quite straightforward but this
25:45
isn't very efficient it scales poorly
25:47
it's not encapsulated and there's no
25:49
cancellation behavior going on if you're
25:52
more familiar with the Java world you
25:53
might be aware of completel future and
25:56
this is a nice chaining mechanism that
25:59
you can then sort of apply a synchronous
26:01
behavior as a selector chain of
26:03
operations this is good the
26:04
unidirectional data flow and in the
26:08
Android worlds are equivalent is our X
26:11
Java where we have chain operations but
26:15
unfortunately sometimes that might get a
26:17
bit out of hand and you might end up
26:19
with our X cover observable chains that
26:22
do a lot of things you're not quite sure
26:24
what they are or why they were there in
26:27
the first place he is he an example of
26:31
how our Xterra to go quickly out of hand
26:34
mapping to different types I think it's
26:37
actually only does about two operations
26:38
it's it's quite ridiculous so yeah this
26:41
is escalated quickly
26:43
compare this to curtains so carotenes
26:46
the next big thing if not already the
26:48
current big thing if you're not already
26:50
using carotenes what's wrong with you
26:54
so what our curtains coatings are
26:57
basically cooperative routines for non
26:60
pre-emptive multitasking they execute
27:03
sequentially or sort of sequentially
27:05
with a seemingly imperative syntax and
27:08
it looks a lot like code you might be
27:09
familiar with in he colony esque well
27:15
so given this example I'm using
27:17
straightforward global scope we have a
27:20
print line printing hello sleeping for
27:23
two seconds and then we have the launch
27:25
which delays by one second and prints
27:27
world so because we're printing hello
27:29
immediately and we're printing world up
27:31
for one second this then prints hello
27:32
world after two seconds so cool I feel
27:38
like I should talk about stability
27:39
factor it even snows there are a lot of
27:41
parts of currencies which are stable and
27:43
there's a lot of annotations that
27:45
provide you the idea of what's going on
27:48
these things like experimental obsolete
27:50
internal flow preview
27:53
I think there's now what they've
27:55
actually been in there to be opted in
27:58
which means you can actually design your
28:01
own annotations and design your own API
28:03
documentation through use of this which
28:06
is really great and I recommend this
28:08
talk from your sleep mode where he talks
28:11
about building SDKs using these
28:12
annotations to your advantage and how
28:14
you can utilize this to give your API
28:19
much more meaning
28:23
so moving back to repairing let's code
28:25
with cotton curtains so the nicest thing
28:30
nice things here are that we're using a
28:32
native library so carotenes isn't like a
28:35
second-class citizen too common like our
28:38
ex Java is to Java or any of the guava
28:42
things like it's something developed
28:43
after the fact I color her routines is
28:45
part of the language even if you have to
28:48
you you import library it's still
28:50
language supported it's incredibly
28:53
efficient
28:54
you can spawn thousands of thousands of
28:56
curtains and not see much impact to your
28:59
performance it's really easy to use and
29:03
there's something somewhat gratifying
29:05
about writing suspend fun all the time I
29:08
think it's just a nice thing to do so
29:12
let's go back to our example the prints
29:14
hello world after two seconds let's say
29:17
you have some very complex async let's
29:20
behavior where a lot of operations going
29:22
on and you know you might want to
29:27
refactor this so how would you do so
29:29
well you can actually use up by easily a
29:31
proteins so you just move it to a new
29:33
function this function is now suspended
29:35
and it delays and prints world it has no
29:38
knowledge about its execution
29:39
environment it just prints world so then
29:42
you can launch it in a protein and
29:44
execute it this is really useful if you
29:47
want to extract in things into new
29:48
classes new methods and here with
29:51
because you're not tied to excuse me not
29:54
tied to any other dependencies you can
29:56
just say this method suspends now fun
29:59
pipe you can actually write suspend
30:00
phone in without using curtains as well
30:03
you just can't consume it you can also
30:07
actually my dispatcher as well in the
30:09
example here I've specified this back to
30:11
star I owe it physically but I recommend
30:13
not doing this because you won't be able
30:16
to replace this and the test so you
30:19
wanna be able to inject it there's a
30:21
great library from Rick bizarro where he
30:23
overrides all kind of over overloads the
30:27
Kotlin current in context with the
30:30
dispatches then you can call in line
30:32
execute with dispatchers dot IO and this
30:38
is even easier to test as well you can
30:39
just call run blocking test and then you
30:42
just execute your functions as you would
30:44
normally it's important remember as well
30:47
though if you have like a infinite
30:48
suspended function like a flow
30:50
collection that doesn't actually
30:51
terminate you will actually block your
30:55
test as well so you might want to have
30:56
multiple executions of unblocking tests
30:58
or launch a sink or where appropriate
30:60
you can find a common testing library
31:02
here i come and we're still on version
31:05
1.3 3 but if not then i'm sure you find
31:09
the right version some further reading
31:11
for you and if you're interested there's
31:13
a code lab sodomite in java to Kotlin
31:15
which is usable
31:16
there's the colon quarantines tests
31:19
library on github all of this is open
31:21
source and we have this video that I
31:26
have embarrassingly forgotten that title
31:28
to so my apologies there but I'm sure
31:30
it's very cool and this comparison
31:35
between our X Java I made by some other
31:38
developer that's totally mock me and
31:39
totally not trying to shamelessly self
31:41
plug its own content
31:44
so in closing thank you all for
31:46
listening that has been thanks so much
31:51
ash really really appreciate your
31:53
joining this you know one of the what
31:54
are the downsides of a of an of a
31:57
webinars that you don't get these
31:58
audible feedback so I've prepared the
32:02
the clapping out for you I'm going to
32:04
give it a couple taps here
32:07
Bravo so just that's special for you
32:10
today just so you can get that audible
32:13
feedback so we have a great list of
32:15
questions lined up for you that have
32:18
been that have been collecting this time
32:20
so I'm gonna have really share his
32:21
screen I'm gonna shut off my video and
32:24
you should see then at the bottom of
32:25
your screen all the questions from
32:27
slider that have been voted on come up
32:29
so we've got about 10 minutes and I'll
32:30
I'll spring back in here with video and
32:32
audio as soon as we're ready to jump to
32:34
the dmitriy on the next talk so feel
32:36
free to read the question and didn't
32:38
jump at it
32:38
alright cool just know when I when I'm
32:43
when to use lazy I went to use late in
32:46
it bar good question so I would also
32:50
like to throw in the fact that you don't
32:52
have you can also use the non-null
32:54
delegate as in addition to lazy if you
32:58
are trying to avoid malleability here so
33:01
each of these three options lazy late in
33:04
it and nominal are quite similar will be
33:07
the especially lazy it's a bit different
33:08
but it's really up to you because
33:12
there's each one has some pros least one
33:14
has some cons and it really depends on
33:17
your use case as long as you understand
33:19
the benefits of each one so for example
33:22
lazy is actually going to create a
33:25
delegate property for you so this is
33:27
actually an object that has to be
33:28
created so there's memory consumption
33:30
there and also it has an underlying
33:33
implementation about how the hand will
33:34
thread safety so by default if you don't
33:36
specify a thread safety scheme it will
33:40
then use what's called a double lock
33:42
synchronization which means it checks
33:45
for the existence of the variable then
33:47
does similar lock then checks again and
33:48
this kind of operations can be a bit
33:51
expensive especially if all you're
33:53
trying to do is offset the
33:55
initialization but the benefit of that
33:58
is that you get to use a lazy property
33:60
that is immutable so different compare
34:03
that to Layton it's a latent is
34:06
obviously doesn't require any object
34:09
instantiation so you don't have
34:10
requiring delegates there no fancy
34:12
language features besides relating it
34:14
but the problem there is that it's
34:16
mutable you have to then set it so then
34:19
it can be actually changed again so you
34:21
won't be a benefit for mutability there
34:23
and it can still be meld because if you
34:26
don't set it you'll still get an
34:27
initialized property exception whereas
34:30
you know lazy is there's no chances are
34:31
happening same applies to nominal
34:33
nominal later a very similar except that
34:37
one uses the delegate one does not so
34:40
hope that answers your question
34:44
[Music]
34:46
any reason why coffeemaker was using
34:49
field injection and inject internal
34:51
light in it instead of inject
34:52
constructor yes very well knows it this
34:56
was purely a contrived example there was
35:00
no reason at all other than the fact
35:02
that I wanted to show that if you use
35:05
injection on a fused field injection
35:08
which we often have to do in Android or
35:10
activities and fragments unless to using
35:13
the fragment factory or activity factory
35:15
we still have to make use of these field
35:17
injections this is why lay in it and
35:19
this is why I wants to talk about null
35:22
ability and in its aspect if you are
35:24
using constructor in projection then
35:26
good for you you are a good citizen
35:28
always prefer constructor injection over
35:31
field injection because then you can
35:34
actually then rely upon immutability and
35:37
all other null safe values without
35:40
having to worry about anything overhead
35:41
of either using non no law or lay in it
35:44
or lazy
35:49
any suggestions on a good article to
35:52
understand the scope idiom there are a
35:57
lot of examples out there
35:59
unfortunately I can't think of one off
36:01
the head but you're probably not going
36:04
once are going to find out it is is the
36:08
reasons why to use different ones so
36:11
there are four main scoping up four main
36:14
scoping methods that is apply also run
36:17
and let now each of these basically have
36:21
a different signature that make them
36:22
better for use in different
36:24
circumstances apply and also will return
36:28
the object that you call the method on
36:30
and less and run will actually return
36:32
the last expression in your Lander block
36:34
so you can think of let and run more as
36:38
like math than you know additional
36:42
features also and apply stuff like you
36:47
know and and do this as well but the
36:50
difference in these two sin in these two
36:52
is that they have a different signature
36:54
where instead of the lambda property
36:56
receiving the receiver has a argument
36:59
you receive it as a sort of context I'll
37:04
try them find a good article that
37:06
explains us in death and the the
37:07
pitfalls as well and I'll try and share
37:09
on Twitter if you follow me good reason
37:12
to follow me okay thanks so next what
37:18
our runtime pile time performance
37:20
implications of using cotton syntactic
37:22
sugar if it needs to convert it back to
37:24
Java bytecode
37:30
good one so I think it's important
37:34
remember that the Kotlin compiler is
37:36
like hyper optimized the jetbrains team
37:39
work extensively on these on the common
37:45
compiler and it's you know this is
37:48
probably gonna be happening mostly in
37:49
compiled in build environments so you're
37:52
not gonna have as much of the issue
37:54
performance because you've already
37:56
compiled it and such there is going to
37:60
be probably a small impact or overhead
38:03
in some circumstances but in most of
38:06
time it's gonna be negligible or
38:08
non-existent so I would probably say the
38:12
benefit of using some of these kind of
38:15
idiomatic features outweighs the costs
38:18
of having any performance impacts if
38:23
there are anything that is
38:26
okay so next uestion did you refactor
38:30
the legacy code at once or
38:31
piece-by-piece which approach did you
38:33
prefer why
38:34
definitely piece by piece don't try and
38:37
attack everything in one go because
38:40
you're gonna end up with like a really
38:44
bug prone environment if you try and
38:45
refactor everything in one go then
38:47
you're doing way too much and you're not
38:50
gonna benefit from be able to understand
38:51
the the requirements that the reasons
38:54
why this existed in the first place and
38:57
it's much better to sort of go with a
38:58
Boy Scouting approach Boy Scouting
39:00
approach is where you if you're working
39:03
in the area of the code anyway then just
39:06
work in that area and in its surrounding
39:09
areas and make it a little bit nicer
39:10
than the way you found it and then over
39:13
time you'll find you have a better
39:14
understanding of the code you have a
39:16
better cleaner implantation you have
39:17
more testing I test coverage if you want
39:20
to use that as a metric and it'll be
39:23
much much safe way of doing it it'll
39:25
take longer admittedly but it's much
39:29
much safer
39:31
cool people try to avoid the double bang
39:34
or the question mark could you mention
39:36
some cases when these are fine to be
39:38
used yeah sure so when we started using
39:43
cutting across the door by an operator
39:45
was seen as abhorrent it was ugly and
39:47
horrible and nobody wants to see it in
39:49
their code so ever start using anything
39:51
else they can find
39:53
so either questions mark or might have
39:55
none no Lee might have lay in it you
39:57
might have these throw exceptions
39:59
personally that's what I prefer to try
40:01
and do is is to avoid double balance by
40:03
having eager throwing throwing
40:06
exceptions works well for me but you
40:12
know there are situations where
40:13
something you are categorically sure
40:16
that this can never be null but simply
40:19
it's annotated from Java as being
40:22
knowable there's nothing you can do
40:24
about that and it's like an impossible
40:26
exception
40:27
I refer back to the slides of the you
40:29
know impossible state exception where
40:31
you know you're very sure this is not
40:32
going to happen and even then it can be
40:35
useful to you know throw an exception if
40:38
there's even the slightest remote
40:40
possibility but if you are categorically
40:44
100% sure that it's not gonna be null
40:46
feel free to use dollar bang I mean it
40:49
means that you've thought about the use
40:51
case and you've considered the language
40:53
features because you know double bang is
40:55
a common feature it's it's acceptable
40:57
for use in my opinion just make sure you
40:59
do so carefully and with consideration
41:01
and not just as a fallback all right ash
41:07
we've got time for one more question I
41:09
mean it looks like this the next two
41:11
questions were voted on the same number
41:12
of times so I'm gonna let you choose
41:13
which one of those questions you want to
41:16
answer
41:28
okay so I'm okay this fit oh no they
41:32
just didn't put it on okay so actually
41:34
it's been but it no then the other side
41:37
I don't know probably
41:39
static sleeping discouraged as their
41:40
members of a companion objects but our
41:43
top level functions and vast an object
41:45
have a static as well yes this is true
41:47
this applies also to extension functions
41:51
which are technically static functions
41:53
but it's important to remember that you
41:56
know you consider it how it is perceived
41:59
in in Colin so you know you might have a
42:03
top level function but then might end up
42:05
in a java class anyway now it might be
42:11
wrong to say the discourage but the
42:12
gates you can actually sort of interpret
42:14
for the language itself that it's used
42:16
less or least static keyword was just
42:18
not included anywhere and that's because
42:21
you know static can mean a lot of things
42:22
can have a lot of results a lot of side
42:24
effects so yes you're right but I think
42:31
we can still take the benefit of of
42:33
these things and still please actually
42:37
as well I think you're using mojito with
42:39
with the extension functions can
42:40
actually be successful and but very
42:42
quickly ATS the second one because I'm
42:44
gonna be both any distance on using
42:46
curtains when calling coming from Java
42:48
files you can't sorry well well that was
42:53
there was a quick quick answer on the
42:55
last one anyway thanks again
42:58
ash for being here really appreciate
42:60
this session I know we're looking
43:01
forward to potentially hearing from you
43:03
is again later in our jetpack series I
43:05
think knowing you for a while I'm sure
43:06
you would describe yourself as a
43:08
lifelong proponent and and a fragments
43:12
right lifetime user loving it
43:15
never been skeptical about it right no
43:19
so yeah I know
43:20
we might I just everyone joining us
43:22
today if you come in on one of our
43:24
future jetpack series you know you might
43:26
be seeing ash again talking about his
43:29
experiences of fragrance and Lavagirl I
43:31
breath and implementations there so ash
43:34
thanks again for being with us today
43:35
look forward to hearing from you again
43:38
and I'm going to now
43:41
Thanks
droidcon News
Tech Showcases, Developer Resources & Partners
EmployerBrandingHeader
jobs.droidcon.com
![]() Latest Android Jobs
Kotlin Weekly
![]() Your weekly dose of Kotlin
ProAndroidDev
![]() Android Tech Blogs, Case Studies and Step-by-Step Coding
Zalando
![]() Meet one of Berlin's top employers
Academy for App Success
![]() Google Play resources tailored for the global droidcon community |
Droidcon is a registered trademark of Mobile Seasons GmbH Copyright © 2020. All rights reserved.