<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Dmitry &lt;Dima&gt; Sitnikov on Medium]]></title>
        <description><![CDATA[Stories by Dmitry &lt;Dima&gt; Sitnikov on Medium]]></description>
        <link>https://medium.com/@fo2rist?source=rss-505a1bed252d------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*bIyCkcXAGazj8Ag7HWTUuQ.png</url>
            <title>Stories by Dmitry &amp;lt;Dima&amp;gt; Sitnikov on Medium</title>
            <link>https://medium.com/@fo2rist?source=rss-505a1bed252d------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 20:54:27 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@fo2rist/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[The Sponsors]]></title>
            <link>https://fo2rist.medium.com/the-sponsors-f089f0e81d5c?source=rss-505a1bed252d------2</link>
            <guid isPermaLink="false">https://medium.com/p/f089f0e81d5c</guid>
            <category><![CDATA[management]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[information-technology]]></category>
            <dc:creator><![CDATA[Dmitry <Dima> Sitnikov]]></dc:creator>
            <pubDate>Tue, 02 Jun 2026 03:45:09 GMT</pubDate>
            <atom:updated>2026-06-02T03:45:09.487Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>The Sponsors</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*z14Avt58CJHe0SjsIXcqaQ.png" /></figure><p>When I was a kid, my father had a word for the car speeding ahead of us. He called it a “sponsor.” It was a joke, but the logic was clear: that driver in front would be the one to get fined — even though we were speeding too. The police can only stop one car at a time. So the sponsor takes the hit, and everyone else carries on.</p><p>This analogy applies to many organizations.</p><p>When you penalize teams for taking on risky and challenging projects, most teams will simply stop trying. Not because they lack ambition, but because no one wants to be the sponsor.</p><p>In large companies, leadership has limited bandwidth. Executives can only closely evaluate a handful of projects at any given time. The result is predictable: the most visible work gets attention, scrutiny, and resources, while most teams operate below the radar. And yet those under-the-radar teams make up the majority of the organization’s capacity.</p><p>Instead of moving at full speed, they self-regulate. Teams learn that visibility brings risk — more oversight, shifting priorities, unrealistic expectations, or becoming the next restructuring target. Staying unnoticed feels safer than standing out.</p><p>Innovation doesn’t slow because people lack ideas or motivation. It slows because the system trains people to optimize for safety instead of progress. The result is an organization with enormous theoretical capacity running at a fraction of its speed.</p><p>Organizations that want sustained innovation need to create space where experimentation is rewarded without automatically increasing scrutiny. Teams need to move quickly without feeling that success itself is a liability. When people stop optimizing for survival and start optimizing for outcomes, the dormant capacity inside large organizations becomes one of their strongest competitive advantages.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f089f0e81d5c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Android A/B testing Made Simple With Cadabra Library]]></title>
            <link>https://medium.com/swlh/android-a-b-testing-with-cadabra-library-10290ef03f57?source=rss-505a1bed252d------2</link>
            <guid isPermaLink="false">https://medium.com/p/10290ef03f57</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[a-b-testing]]></category>
            <category><![CDATA[development]]></category>
            <dc:creator><![CDATA[Dmitry <Dima> Sitnikov]]></dc:creator>
            <pubDate>Tue, 01 Dec 2020 04:17:03 GMT</pubDate>
            <atom:updated>2020-12-20T00:27:27.365Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JxziYYk884aH6c0R7Oo-FA.jpeg" /><figcaption>Photo from by <a href="https://unsplash.com/photos/yu5e2otbgb4">B</a><a href="https://unsplash.com/@brianisalive">rian Wangenheim</a></figcaption></figure><p>A/B testing is not easy: designing an experiment and analyzing data properly is a massive task, and technical implementation adds even more complexity to the mix. In this article, I will show how to streamline that last part of the A/B testing process on Android to focus on what matters the most — your data.</p><h3>A/B testing complexity</h3><p>Let’s start with the complexity associated with A/B testing before I offer the solution. So, what are the problems?</p><ul><li><strong>Async communications</strong> — the configuration of the experiment is often located at the server so the client needs to fetch it first, and this operation is asynchronous. That brings many questions: how do we show the UI? Do we need to wait? How do we check the latest configuration is loaded?</li><li><strong>Multi-layer changes</strong> — with most modern apps adopting one or another form of layered architecture an A/B test touches almost every layer in the app: it needs to be received from the network, stored somewhere in persisted storage, tracked on the domain-logic layer, and displayed through UI layer. That’s too many places to make a mistake (e.g <a href="https://medium.com/@burkedamian/a-b-testing-on-android-with-a-clean-architecture-c66c6bfd2131">see this article</a>).</li><li><strong>Multi-experiment tracking </strong>— with more and more experiments added to the app it’s harder to track which experiments are present at all, which can be active at the time, and whether they interfere with each other.</li><li><strong>Sunsetting </strong>— after the experiment is over one needs to go and clean up the code from all the layers affected at the previous step. Things like configuration models and resources often get forgotten along the way and stay in the code base for months after they aren’t needed anymore.</li><li><strong>Boilerplate </strong>— UI changes may be as simple as a single button’s color change or as complex as a whole new layout, in both cases at least one if-else/switch-case is required. And all should be done in a way they won’t get lost during sunsetting.</li></ul><h3>Solution requirements</h3><p>If we were given enough time to design a complete solution to the aforementioned problems how would it look like? Here is my proposed library requirements. (<em>Scroll to the last paragraph to get straight to the code samples</em>)</p><ul><li><strong>Fully synchronous experiment configuration fetching</strong> — most of the tools that define the cohorts for A/B not making the decision in real-time, and not delivering it instantaneously either, there is no point in trying to get the current state of the server-side config: whatever state was actual at the moment of app launch should be the state of the A/B test deeper in the app flow (BTW recommended <a href="https://firebaseopensource.com/projects/firebase/quickstart-android/config/readme/">config fetching interval for Firebase is 12h</a>). That doesn’t just reduce the bandwidth usage and increases responsiveness, it eliminates tricky bugs caused by fetching the updated config while one or more experiments have already been shown to a user.</li><li><strong>Ability to enable the experiment locally </strong>— A and B groups for an experiment should be defined in advance and stay intact (that’s the best way to keep them truly independently randomized) but the experiment itself may not be available yet to a user until a certain event happens. It’s then required to activate experimental UI A or B immediately after, ideally without network round-trip, or extra code that checks for experiment activation status.</li><li><strong>Single point of configuration </strong>— to keep track of all experiments we need to keep them registered in one place so it’s easy to see what’s active now. We’ll also need this point to set the configuration for integration and functional tests.</li><li><strong>Statically typed enum-like configuration</strong>—once the experiment is started the sub-parameter can not change otherwise we’ll get inconsistent data. That immutability, in turn, allows us to create a data-class with a complete set of required parameters for each experiment variant. The enum nature will prevent us from accidentally skipping one of the options within the <em>switch</em> or <em>when</em> statement. Once the experiment is over we can remove the class, and the code won’t compile until we properly remove all the places the experiment was affecting.</li><li><strong>Automatic resources resolving </strong>— many experiments are as simple as showing a new layout for the same data. It would be much more convenient to provide two layouts like cart_screen_variant_compact / cart_screen_variant_verbose for an experiment that has variants “Compact” and “Verbose” and let the framework inflate proper layout automatically. And during the sunset phase, we can then remove all the resources with either _verbose or _compact suffix and be sure nothing unused is left.</li><li><strong>Testability</strong> — we don’t want to see a random experiment’s variant during the testing phase, so there should be an easy way to launch any given variant, and it should be possible to mock the experimentation framework when needed.</li></ul><h3>Solution</h3><p>With all these requirements in mind, I’ve created a library let’s see how that works (links to the library repo and maven below)!</p><p>Here is an example of the minimal A/B test configuration, for a simple test.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/256/1*sHi8Q1kOpp5vNurG-DdNBg.png" /><figcaption>Both layouts and content can be changed by Cadabra</figcaption></figure><p>(I’ll cover more use-cases in a separate article, but <a href="https://github.com/fo2rist/cadabra">the repo</a> already contains the sample project, and <a href="https://fo2rist.github.io/cadabra/">the documentation</a> describes the solutions for the most common cases)</p><h4>A simple experiment with automatic resources resolution</h4><p>All we need to do is</p><ul><li>define an enum that extends theVariant interface</li></ul><pre>enum class <strong>AutoResourceExperiment</strong> : Variant {<strong>STRANGE</strong>, <strong>CHARM</strong>}</pre><ul><li>and register it like that</li></ul><pre>CadabraAndroid.<strong><em>initialize</em></strong>(this)<br>CadabraAndroid.<strong><em>config</em></strong><br>        .<strong><em>startExperiment</em></strong>(<br>           <strong>AutoResourceExperiment</strong>::class,<br>           RandomResolver(<strong>AutoResourceExperiment</strong>::class))</pre><p>With auto-resources resolving layouts and strings that have suffixes _strange or _charm (according to the declared variants) will be automatically resolved by the special context wrapper, with the additional safety layer of defaulting to the explicitly provided resource if the desired one is not found.</p><pre>val ct = cadabra.<strong><em>getExperimentContext</em></strong>(<strong>AutoResourceExperiment</strong>::class)</pre><pre><em>// use `_strange` by default and `_charm` if Variant CHARM is active</em><br>showAlertDialog(<br>    ct.<strong><em>getStringId</em></strong>(R.string.dialog_title_strange),<br>    ct.<strong><em>getLayoutId</em></strong>(R.layout.dialog_layout_strange))</pre><p>The experiment context is bound to a single experiment so it won’t accidentally pick up the wrong resource if variant “Strange” is active for another experiment, but it’s a good practice to give variant longer more specific names.</p><p><strong>An experiment with custom data</strong></p><p>Should the experiment require more complex parameters than resources, they can be provided as Variant fields</p><pre>enum class <strong>FancyExperiment</strong>(<br>    val screenLayout: <em>Layout</em>,<br>    val screenContent: <em>Content</em>,<br>    val itemsLimitPerPage: <em>Int</em><br>) : Variant {<br>    <strong><em>CHARM</em></strong>(<em>Layout</em>.<em>WIDE</em>, <em>Content</em>.<em>COMPLETE</em>, 10),<br>    <strong><em>STRANGE</em></strong>(<em>Layout</em>.<em>COMPACT</em>, <em>Content</em>.<em>FAVORITES</em>, 20),<br>}</pre><p>And later retrieved via Cadabra singleton</p><pre>val aVariant = cadabra.getExperimentVariant(<strong>FancyExperiment</strong>::class)</pre><pre>when (aVariant.<em>screenLayout</em>) {<br>    <em>WIDE </em>-&gt; setContentView(R.layout.activity_wide)<br>    <em>COMPACT </em>-&gt; setContentView(R.layout.activity_compact)<br>}<br><em>loadContent</em>(<br>    favoritesOnly = aVariant.<em>screenContent</em> == Content.<em>FAVORITES</em>,<br>    numberOfItems = aVariant.<em>itemsLimitPerPage</em><br>)</pre><h4>Experiments activation</h4><p>For the real-life scenario, we’d need some service to control the experiments, like Firebase, which is supported out of the box</p><pre>CadabraAndroid.<strong>config</strong><br>    // register experiments without starting<br>    .<strong><em>registerExperiment</em></strong>(<strong>FancyExperiment</strong>::class)<br>    // load experiments config from Firebase<br>    .<strong><em>startExperimentsAsync</em></strong>(<strong>FirebaseConfigProvider</strong>())</pre><p><em>FirebaseConfigProvider</em> is part of the library, and any other services including custom in-house endpoints can be added via extensible providers API.</p><p>Note the explicit registration step, which prevents accidental starting of the experiment that’s not ready yet or has been disabled already.</p><h3>Design</h3><p>The key design aspects of the library</p><ul><li>It’s Kotlin-first but fully supports Java: all companion’s methods exported as statics, there are no coroutines or flows, and both <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html"><em>Class</em></a> and <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-class/"><em>KClass</em></a> parameters are supported.</li><li>It’s lightweight and modularized: can be imported as core-only for pure Java/Kotlin modules or as an Android library to enable automatic resource resolving.</li><li>It’s extensible: the most basic ways of resolving the active experiment’s variant are supported out of the box, including <a href="https://firebase.google.com/docs/remote-config">Firebase Remote Config</a>, but custom resolvers are allowed.</li><li>It’s testable: the entry point is designed as a minimalistic interface, not a class, so if you need to provide fake/mock implementation for tests, that can be done in a couple of lines of code. If you ever tried to mock Firebase SDK you know what I’m talking about.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/200/1*AVmGBg_o7kPx-c37D2Px-w.png" /></figure><p>That’s pretty much it. Check the repository for more examples and the documentation, and please reach out if you feel that you have a use-case that Cadabra doesn’t cover well.</p><ul><li><a href="https://github.com/fo2rist/cadabra">fo2rist/cadabra</a></li><li><a href="https://mvnrepository.com/artifact/com.fo2rist.cadabra">Maven Repository: com.fo2rist.cadabra</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=10290ef03f57" width="1" height="1" alt=""><hr><p><a href="https://medium.com/swlh/android-a-b-testing-with-cadabra-library-10290ef03f57">Android A/B testing Made Simple With Cadabra Library</a> was originally published in <a href="https://medium.com/swlh">The Startup</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kotlin scope and extension functions. How to not harm your code.]]></title>
            <link>https://proandroiddev.com/kotlin-scope-and-extension-functions-b35925ec96b7?source=rss-505a1bed252d------2</link>
            <guid isPermaLink="false">https://medium.com/p/b35925ec96b7</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[best-practices]]></category>
            <dc:creator><![CDATA[Dmitry <Dima> Sitnikov]]></dc:creator>
            <pubDate>Sat, 10 Oct 2020 23:58:36 GMT</pubDate>
            <atom:updated>2020-10-26T16:42:34.158Z</atom:updated>
            <content:encoded><![CDATA[<p>Scope functions in Kotlin are powerful tools that can make the code more concise but, like any powerful tool, can also ruin it if not used properly. This article covers the typical scope function issues and gotchas and offers mitigation practices.</p><p>(The article is based on my 25 min <a href="https://www.droidcon.com/media-detail?video=414726423">Droidcon Online presentation</a>, but provides more examples and details. Scroll down for the best practices list.)</p><h4>0. Scope functions overview</h4><p>First, let&#39;s do a recap.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hny0oYGHV5BSFAHiwHNpaQ.png" /><figcaption>Kotlin standard library offers five scope functions, four of which are defined as extensions</figcaption></figure><p><a href="https://kotlinlang.org/docs/reference/scope-functions.html"><em>Scope function</em></a> is the function executes arbitrary code (lambda that you pass) in the scope of the context-object.</p><p><a href="https://kotlinlang.org/docs/reference/extensions.html">Extension function</a> is the function that takes a receiver, which becomes <em>this</em> inside the function and serves as the context.</p><h4>1. Problem definition</h4><p>So what the problem with them, and how can they harm the code?</p><ul><li>Each <strong>extension function switches the context </strong>of execution and the context <strong>of the reader</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jAVCZZTrWD0thFx8ipdlDg.png" /></figure><ul><li>Each <strong>scope function adds context</strong> to the one that already exists (context of our class or outer function). The more we need to memorize, the harder it’s to read the code. We also need to remember which scope functions return the result and which return the scope-object itself.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*b5DVn3-p0QOck8htVZT90w.png" /></figure><p>That may seem easy but try to recall which two functions on this image take lambda with a receiver (T.() -&gt; R) and which two return the result of the lambda?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zebY1VBDqiuUMAVKPNf_Xw.png" /><figcaption>Answer: <strong><em>with</em></strong> and <strong>apply</strong> take lambda with a receiver, <strong>with</strong> and <strong>let</strong> return the result of lambda (same does extension function <strong>run</strong>, not listed on the picture)</figcaption></figure><p>In some extreme cases, accidental use of the wrong scope or extension function can even lead to error, during compilation or in runtime.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bIN63casiAvRT7bUKnGc3Q.png" /><figcaption>The “same” extension function may have different behavior, in this case in compile time</figcaption></figure><p>Enough theory, let’s check some production code!</p><h4>3. Examples from real life</h4><p>a) That one I found in the medium article about the “best” practices, which suggests several improvements, like the following</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NL5JohMi1YwqbOGk3JcKPg.png" /></figure><p>as you can see the “improved” approach indeed is much shorter, but it’s not clear at all whether it returns the file, or the path, or nothing at all. What’s not obvious either is that path.let part is not needed at all, the function can be reduced to fun makeDir(path: String) = File(path).also{ it.mkdirs() }</p><p>b) and here is the one from the app I’m working on</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/866/1*fw1iICnTy0VUkZIh3dV_xA.png" /></figure><p>it’s kinda OK, but only because of IDE hint, during code-review, it looks like that (now it’s hard to tell what’s first and second)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/866/1*SPieYf13wlRkMu_qNcqErw.png" /></figure><p>that can be slightly improved if we use lambda with parameter instead of a lambda with receiver</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/866/1*WTHOXsRQaGEZNQccwCuueQ.png" /></figure><p>and even further with explicit name and restructuring of a pair</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/867/1*2MlbyA1CxmgtpmyGsv8JFw.png" /></figure><p>but let’s compare it to the version without any scope functions. It’s actually shorter and reads equally well.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/866/1*DefPJ-68H49wSspzbOtHBw.png" /></figure><p>c) that’s not to say no one should use clever tricks with scope or extension function. Here is the parameterized JUnit4 test, that doesn’t look great</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vhpUVN2MG3OgudOIgYq90A.png" /></figure><p>but with customand and shouldReturn functions it’s now 100% clear how to read test data.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nWw71QGMlnjx5apoBiS15w.png" /></figure><h4>4. Recommendations</h4><p>Kotlin’s own documentation <a href="https://kotlinlang.org/docs/reference/scope-functions.html#function-selection">offers the guide</a> for scope functions, but it’s quite vague and examples demonstrate mostly the capabilities rather than the good style, and there is no guide for extension functions whatsoever. So here is my proposed guide, which consists of mnemonics (for each function) and rules (for general cases).</p><p><strong>Scope functions unofficial guide</strong></p><p><strong><em>Mnemonics</em></strong></p><ul><li>[If I need to]<em> Let</em> it work with a nullable value → <strong>let</strong>.<br>The key is that it lets us use the object that may not be available sometimes. nullable?.let { log(it) }</li><li>[If I need to] <em>Apply</em> configuration → <strong>apply</strong>.<br>The key is that we change some properties we can’t set via the constructor. ServerConfig(host).apply { port = 8888 }</li><li>[If I need to]Return an object, and <em>also</em> do something → <strong>also</strong>.<br>The key is that we do all the main job in the function and ready to return an object, but also need to do something auxiliary, like logging.<br>return Something(withParameters).also { log(&quot;Created $it&quot;) }</li><li>[If I need to]Do multiple similar things <em>with</em> an object → <strong>with</strong>.<br>The key is that we are working with one and only one object doing multiple related operations with it.<br>with(service) { connect(); sendData(data); disconnect() }</li><li>Don’t use <strong>run</strong>! Run away from it!<br>Really, there is no reason to, other functions cover everything.</li></ul><p><strong><em>Rules</em></strong></p><ul><li>If it <strong>returns the result</strong> — <strong>keep</strong> it <strong>one line</strong>.<br>That rule helps a lot with the readability of long lambdas where the last statement happens to be a return value, when it’s one line it’s much easier to see that something is returned without explicit “return”.</li><li>If it <strong>works with an object</strong> — use a <strong>single object</strong>.<br>Multiple receivers are hard to track, and two separate this in one scope is enough.</li><li><strong>Establish patterns</strong>.<br>Even if some clever trick may not be obvious, it becomes clear and mundane when used often enough. So find use-cases and use the same functions for them every time: e.g. <em>let</em> for nullable variables, <em>apply</em> for builders, <em>also</em> for logging, etc.</li><li><strong>Don’t try to make the code shorter</strong>.<br>That’s never the goal, even Kotlin’s developer and advocate Roman Elizarov <a href="https://medium.com/@elizarov/with-the-receiver-in-scope-7b52bdcca6e9">in his review of functions with receiver</a> emphasizes that the brevity should not come at the expense of clarity.</li></ul><p><strong>Extension function unofficial guide</strong></p><ul><li><strong>apply</strong> action <strong>to</strong> the <strong>receiver</strong>. <br>Non-infix extension function should not treat left (receiver) and right (arguments) sides equally, it applies an action to the left with parameters from the right. In the example below the second function has the signature fun String.connect(vararg params: String) that doesn’t make much sense.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1qIfEgE6EDl9Zz9ussaqKQ.png" /></figure><ul><li><strong>nest</strong> under an object or an extra <strong>package</strong>.<br>Extension almost always requires an extra nesting level that matches the file name they’re defined at so that the imports make sense for the reader. In the example below function names are very generic (and, or) but the extra package testutils clarifies the first case.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/753/1*i52xmBvqOF5oFOrfgmOqzg.png" /></figure><ul><li><strong>avoid</strong> using <strong>existing names</strong> (e.g. <em>toString</em>, <em>to</em>, <em>run</em>).<br>Failing on that can cause severe real-time issues. Build-in extensions do not require any imports, so if the code contains any custom function with a name like <em>run, plus,</em> <em>let</em> it will work till the moment it’s copied somewhere or IDE reorganizes the imports, at which point it would likely still remain compilable, but will produce an unexpected result.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/755/1*fEAaZkw8n4I_YjFDAV8O6Q.png" /></figure><h4>5. Summary</h4><p>It’s easy to prevent Kotlin features abuse with little discipline a couple of rules. Focus on the business task and readability rather than on cleverness and brevity, and the can solve that problem entirely!</p><p>Safe coding!</p><p>Here is the original #droidcon presentation, and full code from this video can be found <a href="https://github.com/fo2rist/droidcon-kotlin-scope-extension-functions">here</a>.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fplayer.vimeo.com%2Fvideo%2F414726423%3Fapp_id%3D122963&amp;dntp=1&amp;display_name=Vimeo&amp;url=https%3A%2F%2Fplayer.vimeo.com%2Fvideo%2F414726423&amp;image=http%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F887923116_1280.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=vimeo" width="1920" height="1080" frameborder="0" scrolling="no"><a href="https://medium.com/media/0cfe5f63c571acc3a4b597404ab95dcb/href">https://medium.com/media/0cfe5f63c571acc3a4b597404ab95dcb/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b35925ec96b7" width="1" height="1" alt=""><hr><p><a href="https://proandroiddev.com/kotlin-scope-and-extension-functions-b35925ec96b7">Kotlin scope and extension functions. How to not harm your code.</a> was originally published in <a href="https://proandroiddev.com/">ProAndroidDev</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[No more NPE. Converting Java file to Kotlin safely.]]></title>
            <link>https://proandroiddev.com/converting-java-file-to-kotlin-safely-d7d3ffc36b08?source=rss-505a1bed252d------2</link>
            <guid isPermaLink="false">https://medium.com/p/d7d3ffc36b08</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[android-app-development]]></category>
            <dc:creator><![CDATA[Dmitry <Dima> Sitnikov]]></dc:creator>
            <pubDate>Thu, 19 Mar 2020 02:02:15 GMT</pubDate>
            <atom:updated>2020-03-24T15:38:44.622Z</atom:updated>
            <content:encoded><![CDATA[<h3>No more NPE: Converting Java to Kotlin safely</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WZ_3h_l4FiwDaQT-HnLOFA.jpeg" /><figcaption>Image by <a href="https://www.flickr.com/photos/mattcrampton/3249191779">Matt Crampton</a></figcaption></figure><p>So what’s the problem with NullPointerException in Kotlin? Both <a href="https://developer.android.com/kotlin">Google</a> and <a href="https://kotlinlang.org/">JetBrains</a> promote Kotlin as safe &amp; interoperable language, <a href="https://android-developers.googleblog.com/2020/03/handling-nullability-in-android-11-and.html">not necessarily emphasizing enough that it’s not intrinsically free from NPEs</a>, in fact, if misused Kotlin code <a href="https://twitter.com/VasiliyZukanov/status/1143783168631291904">will throw as many</a> <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-kotlin-null-pointer-exception/">KNPE</a>s and <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-uninitialized-property-access-exception/">similar exceptions</a>. <strong>How do we convert old Java code into Kotlin safely</strong> then?</p><h4>1. Know the exact sources of the problems</h4><ul><li>Kotlin is not that safe on the boundaries: <em>Nullable/NonNull </em>annotations in Java code by default produce warnings in Java and compiler errors Kotlin and passing null to the NonNull parameter does nothing in Java, until you dereference this null, but it throws a runtime error immediately in Kotlin. That leads to two problems: 1) all ignored warnings or missed annotation can “leak” nulls into Kotlins “null-safe” variables 2) the Java code that was avoiding NPEs can start crashing after 1:1 conversion into Kotlin.</li><li><strong>Kotlin is </strong><a href="https://proandroiddev.com/safe-parsing-kotlin-data-classes-with-gson-4d560fe3cdd2"><strong>not safe on deserialization</strong></a>: serialization is <a href="https://www.youtube.com/watch?v=V1vQf4qyMXg&amp;feature=youtu.be&amp;t=56m12s">not safe and quite tricky even in Java</a> but Kotlin adds a couple more potential issues to that: default values, sealed classes and nullability itself. Since deserialization may create an instance without calling a user-defined constructor where all values are checked for null and set to defaults the resulting object can have nulls in non-nullable fields. And for the sealed classes it may produce a second instance of Kotlin’s singleton <em>object</em> and make all following <em>when</em> expressions with this object incorrect.</li><li><strong>Kotlin is not safe on lateinit properties</strong>: lateinit properties effectively work exactly the same way as nullable fields in Java, they may or may not reference an object if they don’t — the code will fail in runtime, and the only way to prevent it is to check if the property is initialized.</li></ul><p>Now, when the caveats are clear, comes the solution.</p><h4>2. Follow a formal migration plan</h4><p>The plan covers the migration of an existing Java class into Kotlin, writing a new Kotlin file would follow a subset of these rules.</p><p>1. Annotate all fields, parameters and return values with <em>Nullable/NonNull</em> annotations. Annotation for return values is based on the actual result, and for the public fields and method parameters, the <em>NonNull </em>can be used <strong>only </strong>if it’s possible to prove that no external code can pass null there. Use <em>Nullable</em> otherwise, or when in doubt. Note that it’s impossible to add annotations to the Java arrays so mark them with a plain comment for future.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4686fec9b358067bbb2b4dff7881636c/href">https://medium.com/media/4686fec9b358067bbb2b4dff7881636c/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b38a9902346346f1a6aa65c5ba8b7eec/href">https://medium.com/media/b38a9902346346f1a6aa65c5ba8b7eec/href</a></iframe><p>2. Fix all null-related warnings that may appear after annotations were added (there isn’t any in the example).</p><p>3. Convert the file into Kotlin using IDE or manually. If using the IDE don’t let it “correct” external code, it may produce too many unnecessary changes</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bdcd08238034f5b857e5f4734dfe59f6/href">https://medium.com/media/bdcd08238034f5b857e5f4734dfe59f6/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/65d7050a233f87a259a04421e4bdf3b3/href">https://medium.com/media/65d7050a233f87a259a04421e4bdf3b3/href</a></iframe><p>4. Add <em>JvmName/JvmStatic </em>annotations to fix the code that’s still used from Java to not produce unnecessary changes in the codebase.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/71567eaf31a76250c0ed7495b042bb86/href">https://medium.com/media/71567eaf31a76250c0ed7495b042bb86/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/03efbbe45341ce24400d1d703a232ebb/href">https://medium.com/media/03efbbe45341ce24400d1d703a232ebb/href</a></iframe><p>5. Fix all “!!” in the resulting Kotlin file. Note that most of the “!!”s in the auto-generated code are caused by not fixed nullability warnings.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1b07bfde2b95dcbefc854c31c965d192/href">https://medium.com/media/1b07bfde2b95dcbefc854c31c965d192/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/56a6aaef5f839856e14c60011040c7f7/href">https://medium.com/media/56a6aaef5f839856e14c60011040c7f7/href</a></iframe><p>6. Clean up the code.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4b8c5e3c7c689b7499f5f9af191ebf3e/href">https://medium.com/media/4b8c5e3c7c689b7499f5f9af191ebf3e/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0441431030afb16aff910e94e80b7948/href">https://medium.com/media/0441431030afb16aff910e94e80b7948/href</a></iframe><p>Here is the <a href="https://gist.github.com/fo2rist/c3f30c862f0f4f567541ae4d6076e378">complete sequence</a> on Gist.</p><p>That’s it! Stay safe!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d7d3ffc36b08" width="1" height="1" alt=""><hr><p><a href="https://proandroiddev.com/converting-java-file-to-kotlin-safely-d7d3ffc36b08">No more NPE. Converting Java file to Kotlin safely.</a> was originally published in <a href="https://proandroiddev.com/">ProAndroidDev</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The importance of the basics]]></title>
            <link>https://fo2rist.medium.com/the-importance-of-the-basics-931ce19bb5f3?source=rss-505a1bed252d------2</link>
            <guid isPermaLink="false">https://medium.com/p/931ce19bb5f3</guid>
            <category><![CDATA[engineering]]></category>
            <category><![CDATA[oop]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-design]]></category>
            <category><![CDATA[algorithms]]></category>
            <dc:creator><![CDATA[Dmitry <Dima> Sitnikov]]></dc:creator>
            <pubDate>Thu, 20 Feb 2020 22:42:36 GMT</pubDate>
            <atom:updated>2020-02-20T22:42:36.087Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*U8KO1kkQm1GUfxeCh6Ykzw.jpeg" /></figure><p>I decided to learn how to surf several months ago, I watched YouTube tutorials and have practiced weekly since then. Yet, I’m still pretty bad at that. So bad that this weekend I finally took the first professional lesson and that lesson taught me not just how to surf but also how to answer the question “<strong>Why do we need to learn all these basics like algorithms and data-structures?</strong>”</p><p>With my surfing activity, I was trying to overcompensate the lack of stability and speed with different timing and more intense paddling, effectively wasting a lot of time and energy doing so. Turns out the root cause was completely different and I simply didn’t place my feet the right way…</p><p>The same idea applies to the basic ideas of computer science: the hardware architecture defines which <strong>data structures and algorithms</strong> are more efficient, and the limitations and advantages of particular algorithms shape high-level design approaches (think about pointers, lists, hashmaps, mutexes, immutability, <a href="https://en.wikipedia.org/wiki/Functional_programming">functional programming</a>, <a href="https://en.wikipedia.org/wiki/Reactive_programming">reactive programming</a>, <a href="https://en.wikipedia.org/wiki/MapReduce">map-reduce</a>, etc.)</p><p>I wasn’t able to improve my ride by solving symptoms like low speed and poor balance with wrong and time-consuming measures like harder paddling, similarly, someone not familiar with the basic limitations of an algorithm or a library can waste months in attempts to improve the app performance tweaking inputs of this library based on suggestions from Stack Overflow and YouTube.</p><p>That doesn’t mean everyone should be able to write a sorting algorithm on a whiteboard (unless we a talking about passing an interview in Silicon Valley) but it definitely helps to know the typical efficiency and potential bottlenecks.</p><p>Data structures and sorting algorithms are low-level details, the <strong>higher-level design</strong> is vaguer and there is rarely a single indisputable best solution, but I’d say that the rule of basics still works. Say it’s unclear whether to apply relatively simple and well-known principles such as <a href="https://en.wikipedia.org/wiki/SOLID">SOLID</a> to an <a href="https://en.wikipedia.org/wiki/Object-oriented_programming">OOP</a> system. One can argue that printing and formatting a string are two different responsibilities while someone else can say that formatting is essential for printing. To resolve such contradiction we can again turn to basics and ask a simple question: “<strong>What is the fundamental problem the solution I’m applying was designed to solve?</strong>” The answer may be a bit more verbose than a distilled form of <a href="https://en.wikipedia.org/wiki/Single_responsibility_principle">SRP</a> but it will be more precise as well. Bob Martin coined the term SRP to address the problem of the requirements that change for different reasons and cause the code changes which in turn often leads to <a href="https://en.wikipedia.org/wiki/Software_regression">regressions</a>. In fact, the original definition of SRP is not complex</p><blockquote>“Software module <a href="https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html">should have one and only one reason to change</a>”</blockquote><p>what we have here is the definition of a broader basic problem that can answer not only the questions which libraries, classes, function to split but also which ones to join. So a better understanding of the underlying principle <a href="https://www.youtube.com/watch?v=tMW08JkFrBA">can lead to a better design</a>.</p><p>Like almost anything in this world, education isn’t free and <strong>learning basic stuff is a long, tedious process</strong> that never pays off immediately, but the fast “give me the single answer” approach may not pay off at all. A surf coach told me that I need to repeat feet positioning exercise twice a day, every day, at home, on the floor. I don’t need a beautiful blue ocean and golden beach for that, it’s not much fun, just a solid tangible result.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=931ce19bb5f3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Code Coverage. You Don’t Need It!]]></title>
            <link>https://medium.com/swlh/code-coverage-you-dont-need-it-6068bea66326?source=rss-505a1bed252d------2</link>
            <guid isPermaLink="false">https://medium.com/p/6068bea66326</guid>
            <category><![CDATA[code-quality]]></category>
            <category><![CDATA[code-coverage]]></category>
            <category><![CDATA[unit-testing]]></category>
            <category><![CDATA[testing]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Dmitry <Dima> Sitnikov]]></dc:creator>
            <pubDate>Sun, 19 Jan 2020 02:55:51 GMT</pubDate>
            <atom:updated>2020-01-19T02:55:51.847Z</atom:updated>
            <content:encoded><![CDATA[<p>For anything but Unit-tests.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Bp-kFUgcvQsib_RNZa1VRw.png" /></figure><p>My team works on one application, it has decent (80-90%) code coverage and yet every month we have regressions detected during manual QA process, which slip through automated tests. Why is that?</p><p>Well, because code coverage doesn’t warrant good tests. <strong>Test coverage information only helps with unit-tests</strong> and almost useless for everything else. Moreover, the mere presence of the coverage number can be harmful!</p><h4>What was wrong with our code coverage?</h4><p>Our <a href="https://softwareengineering.stackexchange.com/questions/191913/what-is-a-developer-in-test">SDET</a> team measured code coverage for end-to-end UI tests (those that would click on buttons in the app on users’ behalf). Some time ago management asked SDETs to measure the coverage and to achieve a certain number in it. So they did. In fact, to maintain a high number they have to update the tests every time the UI changes (and it changes with every release for a mobile app) so they spent more time (and money) fixing tests and reacting on false-positives than on increasing the <a href="https://test.io/blog/code-coverage-vs-test-coverage/">actual test coverage</a> (management even went that far to recommend measuring coverage for manual tests, which fortunately never happened, and we have different guidelines now so I can safely tell this story).</p><h4>Why exactly high-coverage-test doesn’t detect regressions?</h4><p>Let’s take a small library I’m working on as an example. Without the test for the root-class <em>CadabraImpl</em> the coverage looks like that</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FK6LZqyKscdf8IDJLEgyBQ.png" /></figure><p>Something is definitely not covered in <em>VariantKt</em> class, but let’s add the integration test for root-class <em>CadabraImpl</em> back and see…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*I8S50NQyV9Lm81xx9LRN4Q.png" /></figure><p><em>VariantKt </em>is a simple class that happens to be used in the larger one for which an integration test is required.</p><p>Integration tests always invoke constructors of different classes, call some methods, etc. to prove that classes work well together, but do nothing to prove their correctness, yet these calls will be detected by code-coverage reporting tool. The same happens with UI tests: even that application startup alone can produce significant coverage numbers, all the sub-modules initialized at startup will look like they’re covered. So integration and UI tests essentially become <a href="https://martinfowler.com/bliki/AssertionFreeTesting.html">assertion-free tests</a> in disguise if the code coverage interpreted as a measure of completeness because such tests never (as they should) have assertions to assess the behavior of all inner classes.</p><h4>What the coverage is all about then?</h4><p>It’s been a lot written on the topic (<a href="https://www.jamesshore.com/Blog/Dont-Measure-Unit-Test-Code-Coverage.html">e.g</a>). In short, similarly to Dijkstra’s famous phrase <em>“Testing shows the presence, not the absence of bugs”</em> we can say that <em>code coverage shows the absence, </em><a href="https://martinfowler.com/bliki/TestCoverage.html"><em>not the presence of tests</em></a>, and it definitely says nothing about their quality.</p><p>In the example above TDD style or bottom-up approach would do a better job: during the smaller class construction phase we can test it properly, make sure it works and only after that write some integration tests, the final coverage number would be same but our confidence in tests would be much higher.</p><p>Focusing on unit tests and covering small pieces at a time helps ensure every single part is working well, and there is no unused code (if it’s not covered maybe we should delete the code instead of adding a test). And not measuring coverage for integration and UI tests allows us to focus more on the actual purpose of such tests — integration aspects and observed behavior.</p><h4>Can we still have coverage?</h4><p>There may still be a reason or two to measure code coverage for non-unit tests or even <a href="https://reflectoring.io/100-percent-test-coverage/">strive for a high coverage number</a> and modern tools can alleviate the problem by showing not only the number and covered lines/branched but also the “source” of coverage (<a href="https://codecov.io/#features">e.g</a>) but measuring a single number without understanding and properly communicating the meaning of it most likely will produce yet another “dashboard promoting ignorance”.</p><p>Stay covered!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6068bea66326" width="1" height="1" alt=""><hr><p><a href="https://medium.com/swlh/code-coverage-you-dont-need-it-6068bea66326">Code Coverage. You Don’t Need It!</a> was originally published in <a href="https://medium.com/swlh">The Startup</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[RxJava. Where did my exception go?]]></title>
            <link>https://fo2rist.medium.com/rxjava-where-did-my-exception-go-eeab91af464a?source=rss-505a1bed252d------2</link>
            <guid isPermaLink="false">https://medium.com/p/eeab91af464a</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[unit-testing]]></category>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[rxjava]]></category>
            <dc:creator><![CDATA[Dmitry <Dima> Sitnikov]]></dc:creator>
            <pubDate>Sat, 23 Nov 2019 05:37:40 GMT</pubDate>
            <atom:updated>2019-11-24T13:39:46.625Z</atom:updated>
            <content:encoded><![CDATA[<h3>RxJava: Where did my exception go?</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sfrV7QNaWL8DVptjJaecGQ.png" /></figure><p>RxJava in the unit-tests can swallow the exception which would crash the real Android app. Here is how to fix the tests.</p><p>Suppose we’re using RxJava in our Android app, and we cover it with unit-tests. Does it mean the same code that passes the test won’t crash the app in production on the same input data? <strong>No! </strong>But why?</p><p>Let’s check the simplified example. The waitAndFail function emulates some background work and then it throws an exception. In theory, this test should fail, in practice, it prints an error message to the console and finished successfully. The same function used in the Android app will crash it.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/718523777739a5cf3bdf2c95d702a831/href">https://medium.com/media/718523777739a5cf3bdf2c95d702a831/href</a></iframe><p>But we’ll see something like that in the console</p><pre>io.reactivex.exceptions.OnErrorNotImplementedException: The exception was not handled due to missing onError handler in the subscribe() method call. Further reading: <a href="https://github.com/ReactiveX/RxJava/wiki/Error-Handling">https://github.com/ReactiveX/RxJava/wiki/Error-Handling</a> | java.lang.IllegalStateException<br> at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)<br>...</pre><p>The reason is that ART (and Dalvik) virtual machine, that runs the app, and local JVM, that runs the tests, have different uncaught error handlers. In Java, <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.UncaughtExceptionHandler.html">each thread has one</a>, and when the exception happens in the thread, JVM calls this thread’s handler. The default behavior for Android is to log the exception and terminate the process, while the default desktop JVM’s error handler prints the exception and ignores it. But if we get the exception in the test function it should fail, shouldn’t it? Yes, but RxJava doesn’t rethrow exceptions it captures and calls the tread’s handler directly, instead.</p><p>So how to fix that? How to make code under unit-tests crash when (and only when) the application would crash give correct feedback as early as possible?</p><p>JUnit allows us to add <a href="https://junit.org/junit4/javadoc/4.12/org/junit/Rule.html">rules</a> to the test to execute arbitrary code before and after each test, we can use that to install a scheduler that actually crashes to the main thread and to ensure the is executed in the same thread we can install RxJava’s handy <a href="http://reactivex.io/RxJava/javadoc/io/reactivex/schedulers/Schedulers.html#trampoline--">trampoline scheduler</a>. Now all our asynchronous code becomes synchronous, so the test will not finish before it actually gets to the exception and it will not ignore the exception anymore.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/262f6338e5e8e98194dc92a9471bd920/href">https://medium.com/media/262f6338e5e8e98194dc92a9471bd920/href</a></iframe><p>Then this rule can be used in any test (and in combination with different rules) as</p><pre>@get:Rule<br><strong>val rxRule </strong>= RxSchedulersTrampolineTestRule()</pre><p>The problem may sound a bit artificial, but in real life developers often forget onError function in subscribe or throw the exception from the wrong place, and if the test is not designed for such case the exception will slip through. So a strict rule serves as an extra guard rail, that can highlight the problem with the code or with the test itself.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=eeab91af464a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Safe Parsing Kotlin Data-classes with Gson]]></title>
            <link>https://proandroiddev.com/safe-parsing-kotlin-data-classes-with-gson-4d560fe3cdd2?source=rss-505a1bed252d------2</link>
            <guid isPermaLink="false">https://medium.com/p/4d560fe3cdd2</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[songs]]></category>
            <category><![CDATA[json]]></category>
            <category><![CDATA[android-app-development]]></category>
            <dc:creator><![CDATA[Dmitry <Dima> Sitnikov]]></dc:creator>
            <pubDate>Wed, 28 Aug 2019 02:58:42 GMT</pubDate>
            <atom:updated>2019-08-28T15:24:16.158Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MDdg805uu4WCWCwiWyB7SA.png" /></figure><p>Kotlin <a href="https://kotlinlang.org/docs/reference/data-classes.html">Data Classes</a> are great; they’re concise, they’re null-safe. <a href="https://github.com/google/gson">Gson</a> is great as well; it’s a de-facto standard for JSON parsing on Android for a good reason. But! Data classes parsed via Gson guarantee neither null-safety nor even default values. Or do they?</p><h4>The Problem</h4><p>There is an <a href="https://proandroiddev.com/most-elegant-way-of-using-gson-kotlin-with-default-values-and-null-safety-b6216ac5328c">excellent article</a> describing an issue. TL;DR if you have a data class like that</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/98c0a4a14122c8030d6284af511bc8ca/href">https://medium.com/media/98c0a4a14122c8030d6284af511bc8ca/href</a></iframe><p>the default values will be ignored, so JSON like {&quot;intValue&quot;:2} will produce object {intValue=2,srtValue=null} instead of expected {intValue=2,srtValue=&quot;default&quot;}</p><p>Good news, there is a way to fix that!</p><h4>The Solution</h4><p>Let’s change our data class a little bit.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a1df185de26f9fe9ad8ccd427d3b9066/href">https://medium.com/media/a1df185de26f9fe9ad8ccd427d3b9066/href</a></iframe><p>Notice the subtle difference? This class defines default values for <strong>all fields. </strong>That’s it! As soon as all the fields have the default values, Gson will respect them when the corresponding fields are missing in JSON (if you don’t need the default values, use nulls).</p><p>Why does it work?</p><h4>The Reason</h4><p>It really boils down to two features.</p><p><strong>1. Kotlin’s Java Overloads</strong>.</p><p>Compare two classes</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9b8620fd2eccbac3f4a159b745141198/href">https://medium.com/media/9b8620fd2eccbac3f4a159b745141198/href</a></iframe><p>the byte-code for them will result with the following Java</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8ac108f18bc1835f34660e8ff1ec1063/href">https://medium.com/media/8ac108f18bc1835f34660e8ff1ec1063/href</a></iframe><p>as soon as all fields have the default values, Kotlin compiler will generate default parameterless constructor in addition to the other overloaded versions it produces.</p><p><strong>2. Java’s Unsafe Invocations in Gson</strong></p><p>The presence of default constructor is important for Gson. The way it works is roughly the following (see <a href="https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java">ConstructorConstructor</a>’s code for more details):</p><ul><li>try to create an object via provided <a href="https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/InstanceCreator.java">InstanceCreator</a> implementation based on type-token</li><li>try to invoke the default constructor</li><li>try to invoke known constructor for maps, sets, queues, etc.</li><li>use <a href="https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/internal/UnsafeAllocator.java">unsafe allocation</a> if nothing helps (more details about <a href="http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/">unsafe allocation</a>)</li></ul><p>That means, if you don’t provide the instance creator and your class doesn’t have the default constructor, the object will be created <strong>without</strong> the constructor call. Kotlin puts all the null checks and default values assignments to the constructor, so all of them will be skipped.</p><p>So <strong>if you’re good with Gson</strong> and not ready yet to move to a new library that supports Kotlin defaults like <a href="https://github.com/square/moshi">Moshi</a>, <strong>define all default values in data classes</strong> and let Gson do the rest.</p><p>Is that it? Well…</p><h4>The caveat</h4><p>The solution above works well for JSON with missed fields, but there is one more problem. The nullability defined in Kotlin code may not be respected in JSON, and Gson will not complain about JSON like {&quot;intValue&quot;:2,&quot;strValue&quot;:null} that contains explicit null. If that kind of situation possible, define all non-primitive fields as nullable to avoid unexpected crashes in production.</p><p>Now that’s it. Happy parsing!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4d560fe3cdd2" width="1" height="1" alt=""><hr><p><a href="https://proandroiddev.com/safe-parsing-kotlin-data-classes-with-gson-4d560fe3cdd2">Safe Parsing Kotlin Data-classes with Gson</a> was originally published in <a href="https://proandroiddev.com/">ProAndroidDev</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Handling Exceptions. The Easy Way.]]></title>
            <link>https://proandroiddev.com/handling-exceptions-the-easy-way-3aeade554613?source=rss-505a1bed252d------2</link>
            <guid isPermaLink="false">https://medium.com/p/3aeade554613</guid>
            <category><![CDATA[exception]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[android-app-development]]></category>
            <dc:creator><![CDATA[Dmitry <Dima> Sitnikov]]></dc:creator>
            <pubDate>Tue, 09 Jul 2019 18:54:51 GMT</pubDate>
            <atom:updated>2019-07-14T17:20:43.647Z</atom:updated>
            <content:encoded><![CDATA[<h3>Handling Exceptions: The Easy Way</h3><p>The simple strategy for dealing with exceptions.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jJK-9alfR2vnBbXgkDMmkw.png" /></figure><p>Exception handling is still a debatable topic nearly 60 years after the <a href="https://en.wikipedia.org/wiki/Exception_handling#History">invention</a>. Thirty years later Java pioneered the <a href="https://en.wikipedia.org/wiki/Exception_handling#Static_checking_of_exceptions">checked exceptions</a>, another clever but often misused concept which drew a lot of criticism and was abandoned by followers like <a href="http://www.informit.com/articles/article.aspx?p=1849236&amp;seqNum=12">Scala</a> and <a href="https://kotlinlang.org/docs/reference/exceptions.html#checked-exceptions">Kotlin</a>. Anyway, the exceptions are still there for most of the application-level languages, and handling is on us.</p><p>So how should we work with exceptions? I want to advocate for the simple strategy I follow for the last several years.</p><h3>Pre-conditions</h3><p>Before starting with the strategy itself, let’s cover the typical edge cases and the assumptions it relies on.</p><h4>Not an exception — don’t throw</h4><p>To handle the exceptions properly, we should only throw the proper exceptions first. Start with Java <a href="https://docs.oracle.com/javase/tutorial/essential/exceptions/handling.html">official documentation</a> (<a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/exceptions/">same for C#</a>), consider <a href="https://howtodoinjava.com/best-practices/java-exception-handling-best-practices/">best practices</a>, and never throw unneeded exceptions anymore. Exceptions meant to be exceptional. Negative and empty results are not exceptions!</p><h4>Can’t control — accept</h4><p>In some cases, we can’t control how an exception should be handled (e.g., checked exception in Java) so there is no need to think about it: we should follow the platform recommendations. When file-reading function always throws EOF exception we have no option but to handle it.</p><h4>Don’t care — ignore</h4><p>Finally, if we don’t care about some exception, we can catch and ignore it. There is a bunch of libraries that don’t follow the best practices and throw random exceptions here and there. If the exception doesn’t provide the information and doesn’t mean any <strong>unrecoverable state</strong> or <strong>observable error,</strong> there is no need to waste time on it. Don’t forget to document the reason for ignoring the exception, though!</p><h3>The strategy</h3><p>Now, when everything else is covered in pre-conditions, we can focus on the actual exceptional cases such as NPEs, various I/O problems, etc. These are the <strong>real issues</strong> that may happen during the app execution and cause the <strong>unwanted and observable</strong> result to the end-user. The strategy is just three simple questions, ask them in the same order to find a way of handling the particular exception.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/854/1*a84f1fktujE5Jil1AB7raA.png" /></figure><p>That gives us four possible actions; let’s see how they work.</p><h4>Avoid</h4><p>The best exception is the exception that was never thrown. If the library throws when not initialized — initialize it. If the method can not work with nulls — make sure it impossible to pass the null. The code with lots of try/catch blocks is even harder to read than the code lots of if/else. Compare two approaches:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/25e2cabea1be7559ac0911ec4e714785/href">https://medium.com/media/25e2cabea1be7559ac0911ec4e714785/href</a></iframe><p>the difference is even more apparent when we only care about the positive scenario</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2ace0de57de9ea6a5e6d8f31ba2e7bdc/href">https://medium.com/media/2ace0de57de9ea6a5e6d8f31ba2e7bdc/href</a></iframe><h4>Recover</h4><p>Now we have a possible exception, say we need to dereference nullable object or perform an operation that may fail. Can this piece of code recover from that exception? I mean <strong>actually recover</strong>. For example, a networking layer can retry the call if it allowed doing so, but it can barely deal with the unparsable result, or the WiFi turned off. So it should not! No need to construct a fake result: yes, a banking app can display the account balance of $0.00 if it can not find the account but should it? An attempt to add the proper recovery code most likely will end up with the violation of <a href="https://en.wikipedia.org/wiki/Single_responsibility_principle">SRP</a> and an extreme number of injected dependencies.</p><h4>Pass</h4><p>Now we know that the piece of the code deals with an exception it unable to handle, but is that <strong>possible during normal execution</strong>? If yes and we already know, that we can neither avoid, nor recover, then the only action we can take is to wrap the exception to make it more specific and informative and re-throw. The upper layer, in turns, could be able to recover from that situation; in the example above it can refresh the list of accounts, or ask to reconnect WiFi.</p><h4>Crash</h4><p>Finally, if the answer to the last question was no. What does it mean that exception is impossible during normal execution? That means we violate some invariants that must be maintained by our system. An example would be the dereference of a nullable/late-init field that supposed to be injected in a class that’s always instantiated via <a href="https://en.wikipedia.org/wiki/Dependency_injection">DI</a> framework. In other words, we <strong>own and fully control the code, </strong>and it depends not on the environment (user, network, disk), but on usage. We may get such an exception only if we add incorrect instructions inside the system. And if that happens, we’d better know about it as soon as possible. Crashing may be unpopular advice but let’s consider the alternatives:</p><ul><li>Catch it and try to handle: that will result with the bloated code pretty much immediately. Can we put initialization checking logic into every single internal method? Shall we wrap every dereference of the variable that’s never null? Moreover, if the handling is complicated, it can cause even more bugs and will make the unit-testing harder for sure.</li><li>Swallow and ignore: that will lead to unpredicted behavior. Even if the app doesn’t crash is that better for a user when the buttons don’t do what they supposed to do, and the information on the screen is misleading? If some internal application invariant is broken, that means the logic is broken as well and the app is not useful anyway.</li><li>Log and re-throw: developers often add extensive logs but is it a good practice? If the upper layer can handle the exception, that means the logging was unnecessary, and if cannot and takes the same logging approach, it will bloat the logs making the issue harder to analyze. Logging — is the form of exception handling, do it only if it’s appropriate.</li></ul><p>Crashing, on the other hand, will let us know about the issue immediately on the testing phase, even before the QA team tries the latest version of the app. And what if the impossible possible and the app start crashing in the users’ hands? We still want to know about it ASAP. All other approached would delay the feedback loop: how long would it take for an average team to figure out that there is a spike of suspicious activity in the logs? How many users would get incorrect bank statements or even worse by that time?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cb7edb5be1c5b49ee7dc9c045e4ab6e2/href">https://medium.com/media/cb7edb5be1c5b49ee7dc9c045e4ab6e2/href</a></iframe><h4>Track</h4><p>As you can see, the previous rule only makes sense if we <strong>have a feedback loop!</strong> Good news that there is a bunch of alerting solutions for mobile and web applications. With proper alerts monitoring in place, we can react to the critical issues in days if not hours, preventing more harm to our users and ourselves.</p><p>So the whole strategy is just four rules of thumb:</p><ul><li><strong>Avoid if possible</strong></li><li><strong>Recover if not avoidable</strong></li><li><strong>Pass if possible</strong></li><li><strong>Crash &amp; Track otherwise</strong></li></ul><p>Let your code be exceptionally stable by letting it crash early!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3aeade554613" width="1" height="1" alt=""><hr><p><a href="https://proandroiddev.com/handling-exceptions-the-easy-way-3aeade554613">Handling Exceptions. The Easy Way.</a> was originally published in <a href="https://proandroiddev.com/">ProAndroidDev</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A non-traditional approach to TDD with Espresso]]></title>
            <link>https://proandroiddev.com/a-non-traditional-approach-to-tdd-with-espresso-4d16dead2c7a?source=rss-505a1bed252d------2</link>
            <guid isPermaLink="false">https://medium.com/p/4d16dead2c7a</guid>
            <category><![CDATA[tdd]]></category>
            <category><![CDATA[testing]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[espresso]]></category>
            <dc:creator><![CDATA[Dmitry <Dima> Sitnikov]]></dc:creator>
            <pubDate>Tue, 18 Jun 2019 02:59:43 GMT</pubDate>
            <atom:updated>2019-06-24T15:51:27.123Z</atom:updated>
            <content:encoded><![CDATA[<h3>An easy-to-start approach to TDD with Espresso</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Um6-OHeX6dcbzyfqBtcsLg.png" /></figure><p>A lot was written about the TDD approach, in essence, it relies on one assumption — your tests are fast. If the tests are slow Red—Green—Refactor cycle is permanently stuck on the tests execution phase rather than on coding. That also assumes that you do know how to write tests. Many people try and give up because they’re not feeling productive, and it’s hard to keep doing something that slows and sacrifice the performance for some imaginary future stability or maintainability gain.</p><p>But what if there is a way to try TDD, even with slow UI tests, and still increase the productivity and the code coverage at the same time?</p><p>The approach I adopted recently for <a href="https://developer.android.com/training/testing/espresso">Android Espresso</a> tests helped me both keep practicing in tests writing, hence developing the skill, and ship faster with simple steps.</p><h4><strong>1. Launch it</strong></h4><p>Every time I need to make a new screen in the app I start with an extremely minimalistic test that contains activity rule only. So once I launch any test the activity starts, and that’s when I write the setup code of the activity. That saves me the time I’d otherwise spend navigating to the new activity through the app.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e8cf2c49b3756b8f277dc187b0295503/href">https://medium.com/media/e8cf2c49b3756b8f277dc187b0295503/href</a></iframe><h4>2. <strong>Design it</strong></h4><p>Once the activity is running I need a way to keep it on the screen to design the layout. And here goes the infinite loop<a href="#f2b3">*</a>. The test itself is not executed in the application’s main thread, so it’s safe to sleep there and the application will keep working. After every significant layout change, I relaunch the test. (Yes, there is <a href="https://medium.com/google-developers/instant-run-how-does-it-work-294a1633367f">Instant Run</a> but it’s not stable and the <a href="https://medium.com/androiddevelopers/android-studio-project-marble-apply-changes-e3048662e8cd">new version</a> of the same feature is <a href="https://developer.android.com/studio/preview/features/#3.5">not available yet</a>)</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0c46868830ebc993b98395b8cd8fc59a/href">https://medium.com/media/0c46868830ebc993b98395b8cd8fc59a/href</a></iframe><h4>3. <strong>Test it</strong></h4><p>Now when the layout is pretty and looks exactly as designed, I can wire the logic (which is ideally already covered with the proper unit-tests) and at the same time some minimalistic integration test that will serve as the guard rail in the future and validate some basic things like “Is the header visible?”, “Can user scroll?”, “Is submit button actually disabled by default?” which can not be validated by the unit tests.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7d5441b189e317a8dd04a3724d07f2f9/href">https://medium.com/media/7d5441b189e317a8dd04a3724d07f2f9/href</a></iframe><p>That’s it! The whole boilerplate is a mere 3 lines of code. And the real tests are even less verbose with <a href="https://github.com/agoda-com/Kakao">Kakao</a> library and all view-access details isolated via the <a href="https://martinfowler.com/bliki/PageObject.html">Page Object</a> pattern.</p><p>Happy testing!</p><p>[<a href="#512f">*</a>] in fact I even have the template in Android Studio that replaces word <em>forever</em><strong> </strong>with `if (true) while(true) Thread.sleep(100);` that works equally well with Kotlin and Java files without modifications.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4d16dead2c7a" width="1" height="1" alt=""><hr><p><a href="https://proandroiddev.com/a-non-traditional-approach-to-tdd-with-espresso-4d16dead2c7a">A non-traditional approach to TDD with Espresso</a> was originally published in <a href="https://proandroiddev.com/">ProAndroidDev</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>