<?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 Armando Picón on Medium]]></title>
        <description><![CDATA[Stories by Armando Picón on Medium]]></description>
        <link>https://medium.com/@devpicon?source=rss-5c60da6ae31c------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*syWY9t24sRCEQqBOECXF3w.jpeg</url>
            <title>Stories by Armando Picón on Medium</title>
            <link>https://medium.com/@devpicon?source=rss-5c60da6ae31c------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 21 May 2026 08:16:46 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@devpicon/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[Delegation Pattern in Kotlin]]></title>
            <link>https://devpicon.medium.com/delegation-pattern-in-kotlin-c08b976995ca?source=rss-5c60da6ae31c------2</link>
            <guid isPermaLink="false">https://medium.com/p/c08b976995ca</guid>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[delegation-pattern]]></category>
            <category><![CDATA[android]]></category>
            <dc:creator><![CDATA[Armando Picón]]></dc:creator>
            <pubDate>Mon, 27 Jan 2025 06:05:04 GMT</pubDate>
            <atom:updated>2025-02-04T16:34:41.351Z</atom:updated>
            <content:encoded><![CDATA[<h3>Class delegation, property delegation, and more</h3><p>Some days ago, I needed to break the implementation of a complex ViewModel. Looking for some ideas I’ve found the Delegation Pattern.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Uq-4GOFzTw6NT6kw" /></figure><h4>What is the Delegation pattern?</h4><p>A design pattern where one object relies on another to perform specific tasks instead of doing it itself.</p><h4>Why use it?</h4><ul><li>Promotes composition over inheritance</li><li>Allows better reuse of functionality</li><li>Simplifies code by avoiding duplication</li></ul><h4>Kotlin’s support for Delegation</h4><p>Kotlin makes the Delegation Pattern easy by providing:</p><ul><li>Class delegation</li><li>Property delegation</li></ul><h3><strong>Class Delegation</strong></h3><p>In Kotlin, <strong>class delegation</strong> allows you to delegate the implementation of an interface to another object using the bykeyword.</p><pre>interface Logger {<br>    fun log(message: String)<br>}<br><br>class ConsoleLogger : Logger {<br>    override fun log(message: String) {<br>        println(&quot;ConsoleLogger: $message&quot;)<br>    }<br>}<br><br>class FileLogger : Logger {<br>    override fun log(message: String) {<br>        println(&quot;FileLogger: $message&quot;)<br>    }<br>}<br><br>class Application(logger: Logger) : Logger by logger<br><br>fun main() {<br>    val consoleLogger = ConsoleLogger()<br>    val fileLogger = FileLogger()<br><br>    // Pass the consoleLogger instance to Application<br>    val app1 = Application(consoleLogger)<br>    app1.log(&quot;Using console logger.&quot;) // ConsoleLogger: Using console logger.<br><br>    // Pass the fileLogger instance to Application<br>    val app2 = Application(fileLogger)<br>    app2.log(&quot;Using file logger.&quot;) // FileLogger: Using file logger.<br>}<br><br></pre><p>It is even possible to apply multiple implementations with the only restriction being that you have to decide which one to use during the object construction.</p><pre>interface Engine {<br>    fun start()<br>    fun stop()<br>    fun getStatus(): String<br>}<br><br>class ElectricEngine : Engine {<br>    override fun start() = println(&quot;⚡ Electric motor starting&quot;)<br>    override fun stop() = println(&quot;⚡ Electric motor stopping&quot;)<br>    override fun getStatus() = &quot;Electric Motor OK&quot;<br>}<br><br>class BasicEngine : Engine {<br>    override fun start() = println(&quot;🔥 Gas engine starting&quot;)<br>    override fun stop() = println(&quot;🔥 Gas engine stopping&quot;)<br>    override fun getStatus() = &quot;Gas Engine OK&quot;<br>}<br><br>class HybridCar(<br>    electricEngine: Engine,<br>    basicEngine: Engine,<br>    useElectric: Boolean<br>) : Engine by when {<br>    useElectric -&gt; electricEngine<br>    else -&gt; basicEngine<br>}</pre><p>Of course, you can apply multiple class delegations to a single class</p><pre>interface ElectricCar {<br>    fun chargeBattery()<br>    fun driveElectric()<br>}<br><br>interface GasolineCar {<br>    fun refuelTank()<br>    fun driveGasoline()<br>}<br><br>class GenericElectricCar : ElectricCar {<br>    override fun chargeBattery() {<br>        println(&quot;ElectricCar: Charging the battery.&quot;)<br>    }<br><br>    override fun driveElectric() {<br>        println(&quot;ElectricCar: Driving on electric power.&quot;)<br>    }<br>}<br><br>class GenericGasolineCar : GasolineCar {<br>    override fun refuelTank() {<br>        println(&quot;GasolineCar: Refueling the gas tank.&quot;)<br>    }<br><br>    override fun driveGasoline() {<br>        println(&quot;GasolineCar: Driving on gasoline.&quot;)<br>    }<br>}<br><br>class HybridCar(<br>    electricCar: ElectricCar,<br>    gasolineCar: GasolineCar<br>) : ElectricCar by electricCar, GasolineCar by gasolineCar</pre><h3>Property delegation</h3><p>In Kotlin, <strong>property delegation</strong> allows you to delegate the getter and setter logic of a property to another object. This is done using the bykeyword. Instead of directly managing the property, the responsibility is handed off to a “delegate” object that provides custom behavior for reading and writing the property.</p><h4>Built-in property delegates</h4><p>Kotlin provides some useful built-in property delegates:</p><ul><li><strong>Lazy initialization:</strong> lazy is a standard delegate for initializing a property lazily.</li></ul><pre>val myLazyValue: String by lazy {<br>    println(&quot;Initializing...&quot;)<br>    &quot;Hello, Kotlin!&quot;<br>}<br><br>fun main() {<br>    println(myLazyValue) // Prints: Initializing... Hello, Kotlin!<br>    println(myLazyValue) // Prints: Hello, Kotlin! (No reinitialization)<br>}</pre><ul><li><strong>Observable properties: </strong>Delegates.observable allows you to react to property changes.</li></ul><pre>import kotlin.properties.Delegates<br><br>var observedProperty: String by Delegates.observable(&quot;Initial Value&quot;) { _, old, new -&gt;<br>    println(&quot;Changed from $old to $new&quot;)<br>}<br><br>fun main() {<br>    observedProperty = &quot;New Value&quot; // Prints: Changed from Initial Value to New Value<br>}</pre><h4>Custom property delegates</h4><p>You can create your own property delegates by implementing the <strong>getValue</strong> and <strong>setValue</strong> operators</p><pre>import kotlin.reflect.KProperty<br><br>class CustomDelegate {<br>    private var value: String = &quot;Default&quot;<br><br>    operator fun getValue(thisRef: Any?, property: KProperty&lt;*&gt;): String {<br>        return value<br>    }<br><br>    operator fun setValue(thisRef: Any?, property: KProperty&lt;*&gt;, newValue: String) {<br>        value = newValue.uppercase()<br>    }<br>}<br><br><br>var myProperty: String by CustomDelegate()<br><br>fun main() {<br>    println(myProperty) // Prints: Default<br>    myProperty = &quot;hello&quot;<br>    println(myProperty) // Prints: HELLO<br>}</pre><p>You can find Property Delegation usage in Compose</p><p>The function remember{} in Compose has been designed using the concept of delegation in mind. Here I show you a very simplified example of it.</p><pre>import kotlin.reflect.KProperty<br><br>class RememberDelegate&lt;T&gt;(private val initializer: () -&gt; T) {<br>    private var value: T? = null<br><br>    operator fun getValue(thisRef: Any?, property: KProperty&lt;*&gt;): T {<br>        if (value == null) {<br>            value = initializer()<br>        }<br>        return value!!<br>    }<br><br>    operator fun setValue(thisRef: Any?, property: KProperty&lt;*&gt;, newValue: T) {<br>        value = newValue<br>    }<br>}<br><br><br>fun &lt;T&gt; customRemember(initializer: () -&gt; T): RememberDelegate&lt;T&gt; {<br>    return RememberDelegate(initializer)<br>}<br><br>fun main() {<br>    var rememberedValue by customRemember { &quot;Hello, World!&quot; }<br>    println(rememberedValue) // Prints: Hello, World!<br><br>    rememberedValue = &quot;New Value&quot;<br>    println(rememberedValue) // Prints: New Value<br>}</pre><h3>Conclusion</h3><p>The <strong>Delegation Pattern</strong> in Kotlin is a powerful way to simplify code and promote composition over inheritance. Kotlin’s built-in delegation support makes implementing this pattern easy and elegant.</p><ul><li>Promotes composition over inheritance</li><li>Allows better reuse of functionality</li><li>Simplifies code by avoiding duplication</li></ul><p>NOTE: I’ve created a playlist for 3 videos I recorded showing all these examples work (those videos are in Spanish)</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fvideoseries%3Flist%3DPLFSffqEi7-Dz1YvQUvA3iJ5ZvMI9Ja6tC&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fplaylist%3Flist%3DPLFSffqEi7-Dz1YvQUvA3iJ5ZvMI9Ja6tC%26si%3D3ULwVfIo5BSsrKxg&amp;image=https%3A%2F%2Fi.ytimg.com%2Fpl_c%2FPLFSffqEi7-Dz1YvQUvA3iJ5ZvMI9Ja6tC%2Fstudio_square_thumbnail.jpg%3Fsqp%3DCITfiL0G-oaymwEICKoDEPABSFqi85f_AwYI4eb_vAY%3D%26rs%3DAOn4CLCHnp4gaHvjEdyM5qSl3lcs2uox0g%26days_since_epoch%3D20123&amp;type=text%2Fhtml&amp;schema=youtube" width="853" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/fce2b37f2a629f2847fbddbafef7bacd/href">https://medium.com/media/fce2b37f2a629f2847fbddbafef7bacd/href</a></iframe><h4>References</h4><ul><li>Delegation | Kotlin Documentation<br><a href="https://kotlinlang.org/docs/delegation.html">https://kotlinlang.org/docs/delegation.html</a></li><li>Delegated properties | Kotlin Documentation<br><a href="https://kotlinlang.org/docs/delegated-properties.html">https://kotlinlang.org/docs/delegated-properties.html</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c08b976995ca" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Reflecting on Seven Years in Santiago: My Path in the Tech Industry]]></title>
            <link>https://devpicon.medium.com/reflecting-on-seven-years-in-santiago-my-path-in-the-tech-industry-d9215a65394b?source=rss-5c60da6ae31c------2</link>
            <guid isPermaLink="false">https://medium.com/p/d9215a65394b</guid>
            <category><![CDATA[development-and-growth]]></category>
            <category><![CDATA[storyofmylife]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Armando Picón]]></dc:creator>
            <pubDate>Tue, 03 Sep 2024 03:47:25 GMT</pubDate>
            <atom:updated>2024-09-03T03:47:25.145Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/720/1*LEOKL4HyqTnJCsrJNdsZCQ.png" /><figcaption>A picture of a zone known as “Sanhattan” in Santiago, Chile taken from San Cristobal hill</figcaption></figure><p>Almost seven years ago, I arrived in Santiago, Chile from Mexico. Having never been here before, I was unsure of what to expect. I remember being curious about my new job, colleagues, and the challenges ahead in a prominent startup founded years before. What I experienced during those first five and half years was valuable for me in terms of my professional career, I met great and passionate tech people. I gained valuable experience, being involved in recruitment, interviewing devs identifying which skills and values can fit our team.</p><p>On the technical side, I have always been someone who values reading and staying informed, but when it comes to making decisions, I rely more on my own experience and common sense rather than strictly following what the books say. This practical approach has guided me in working on evolving, well-designed architectures and being responsible for many of the technical decisions. When I’d been promoted to Technical Lead, I saw how by involving my teammates in technical discussions, we were able to create a sense of ownership over the product, which resulted in a more stable and cohesive team with less turnover during that time even during the pandemic.</p><p>Of course, many things have changed during the last few years, that startup was acquired by big tech, and the culture changed, and those enriching experiences came to a close, prompting me to seek new horizons.</p><p>On my community side, I’ve been involved with some developer communities like the community of Android and Kotlin. A lot of the content I consume to learn about different technologies and keep me up-to-date is thanks to people who share what they’ve learned so I’m committed to giving back to the community what I learn. Also, I believe that people grow not only by themselves but also by sharing what they learned and encouraging others to learn and grow. Building a strong community is not an easy task, but helps us to create strong connections and make some friends.</p><p>As I reflect on these years of growth and the dynamic experiences I have had, I’m reminded of the importance of being part of a team and a mission that truly resonates with me. I continue to seek out opportunities that challenge me and align with my passions, allowing me to contribute meaningfully and grow alongside like-minded professionals. I remain committed to pursuing excellence in every project I undertake, looking forward to what the future holds.</p><p>If you’d like to discuss these experiences or explore potential opportunities together, I’d be happy to grab a coffee or a drink and chat about it.</p><p>#thoughts #chile #developer</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d9215a65394b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Android — Basics of Drawing in Compose (1)]]></title>
            <link>https://devpicon.medium.com/android-basics-of-drawing-in-compose-1-3f706e588cfa?source=rss-5c60da6ae31c------2</link>
            <guid isPermaLink="false">https://medium.com/p/3f706e588cfa</guid>
            <category><![CDATA[drawing]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[compose]]></category>
            <dc:creator><![CDATA[Armando Picón]]></dc:creator>
            <pubDate>Tue, 23 Jul 2024 06:55:33 GMT</pubDate>
            <atom:updated>2024-07-23T06:55:33.297Z</atom:updated>
            <content:encoded><![CDATA[<h3>Android — Basics of Drawing in Compose (1)</h3><h4>I’m learning about drawing in Android with Compose; here you can find my thoughts.</h4><p>Since the first time I heard the word “Canvas,” I have been curious about what it is and why some developers talk a lot about it, but life took me to work on different aspects of Android app development, and I couldn’t find out what it means.</p><p>Until this year, when I was looking at some charts a colleague built in an Android app, the word “canvas” came back to me.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/0*VUF5lLEWEymHnhGQ.jpg" /><figcaption>A canvas</figcaption></figure><p><a href="https://www.merriam-webster.com/dictionary/canvas?utm_campaign=sd&amp;utm_medium=serp&amp;utm_source=jsonld">According to Merriam-Webster dictionary</a>, a canvas is “a piece of cloth backed or framed as a surface for a painting”.</p><p>Similarly, Android provides a canvas to draw whatever we want.</p><h4>Choosing our canvas</h4><p>Before starting, we need to choose where we will draw.</p><p>We can use one of the modifiers available for this purpose, like drawBehind(), drawWithContent() or drawWithCache(), or we can use a convenient composable called Canvas (behind the scenes, it is an Spacer using the drawBehind() modifier).</p><h4>Understanding the coordinate system</h4><p>It is very important to remember this: “The origin or point (0,0) is located at the top left corner of the screen (or canvas).”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/839/1*t_J4wrtcCIA04RfkDGD_jw.png" /><figcaption>the coordinates (x:0, y:0) are located at the top-left corner</figcaption></figure><p>This also works for the Offset, an object that declares how far from the origin an object will be placed.</p><h4>Which form do you want to draw?</h4><p>Well, at this point, Compose offers you several functions to help you to start drawing:</p><p>For basic shapes:</p><ul><li>drawRect()</li><li>drawCircle()</li><li>drawRoundedRect()</li><li>drawOval()</li><li>drawArc()</li><li>drawLine()</li><li>drawPoints()</li></ul><p>And:</p><ul><li>drawText()</li><li>drawImage()</li></ul><p>…and that’s it for now. I’m recording some videos about this topic (in Spanish). Here you can watch the first video:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FJSIm-_NJvTg%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DJSIm-_NJvTg&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FJSIm-_NJvTg%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/039daddc037de3d863797f65a3ccd08e/href">https://medium.com/media/039daddc037de3d863797f65a3ccd08e/href</a></iframe><h4>References</h4><ul><li>Graphic modifiers | Jetpack Compose<br><a href="https://developer.android.com/develop/ui/compose/graphics/draw/modifiers#drawing-modifiers">https://developer.android.com/develop/ui/compose/graphics/draw/modifiers#drawing-modifiers</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3f706e588cfa" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My honest opinion about Gemini in Android Studio]]></title>
            <link>https://devpicon.medium.com/gemini-in-android-studio-absolutely-better-than-the-former-studio-bot-f1f6a32f0718?source=rss-5c60da6ae31c------2</link>
            <guid isPermaLink="false">https://medium.com/p/f1f6a32f0718</guid>
            <category><![CDATA[gemini]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[gemini-in-android-studio]]></category>
            <category><![CDATA[android-studio]]></category>
            <dc:creator><![CDATA[Armando Picón]]></dc:creator>
            <pubDate>Mon, 20 May 2024 05:49:12 GMT</pubDate>
            <atom:updated>2024-05-20T15:44:14.709Z</atom:updated>
            <content:encoded><![CDATA[<h4>I can start with it’s better than the former Studio Bot but with some notes</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*aPWwtC1Cr21NGoxk" /><figcaption>Photo by <a href="https://unsplash.com/@cbpsc1?utm_source=medium&amp;utm_medium=referral">Clint Patterson</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>When Gemini in Android Studio was released, I was curious about how different or similar the experience would be to Github Copilot. I can say I’m gladly happy with the approach taken.</p><h4>First things first… we have the control</h4><p>Something I dislike about Copilot is the sensation of being tracked constantly without any chance to restrict what the model can read or not.</p><p>From the beginning, you’re aware of the different options for making the model aware of your project in Gemini in Android Studio. You can decide between using Gemini in Android Studio only as a conversational chat box, letting the model get context about the current project, or letting the model get context about all your projects. Also, you can include <strong>.aiexclude</strong> files to restrict access over parts of your project or even the entire project from the model.</p><p>When you let the model access your project, you can also enable the option for Gemini to act as a copilot, providing suggestions to complete the code in the same way as Github Copilot does.</p><h4>Accuracy of results</h4><p>Gemini in Android Studio promises you some features like code generation, answering questions, finding resources, code optimization and analyzing crash reports. I’ve tested all of these features, and everything went well until I made some complex requests.</p><p>Asking for the generation of a Person data class is not the same as asking how I can solve a bug with the <strong>BottomSheetDialogFragment</strong> that provokes the sheet to move to the top of the screen when the size of any child component changes. When I tried for this last request, Gemini gave me several bad answers and suggestions, even inventing its own classes. It was a total disaster in terms of trust.</p><h4>Not only with Gemini</h4><p>This problem is not exclusive to Gemini but Github Copilot and Chat GPT also; you can ask them something complex, and these tools usually offer you results far from something real or valuable. Without enough experience, a developer can waste time finding which of those wrong answers is correct.</p><p>This situation made me think about how confident those repositories are consumed by these models to be trained. However, this topic could be covered in a different article.</p><h4>My conclusion</h4><p>For me, <strong>Gemini in Android Studio is a good tool</strong>. Even when you restrict access to your project, disabling any chance to offer a suggestion, the chat box will help you ask about references or even solve routine tasks, so you don’t need to abandon your IDE to open a browser and make a search for a reference.</p><p>Recently, I shared a talk about Gemini in Android Studio (in Spanish) with the Android community in Santiago, Chile. Here are the slides and the recording.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fspeakerdeck.com%2Fplayer%2F80ecc2f3f4a74d21b5e8cd55b11cc203&amp;display_name=Speaker+Deck&amp;url=https%3A%2F%2Fspeakerdeck.com%2Fdevpicon%2Fgemini-in-android-studio&amp;image=https%3A%2F%2Ffiles.speakerdeck.com%2Fpresentations%2F80ecc2f3f4a74d21b5e8cd55b11cc203%2Fslide_0.jpg%3F30153656&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=speakerdeck" width="710" height="399" frameborder="0" scrolling="no"><a href="https://medium.com/media/971c36ebb6e0f7451e5351607f9f4c86/href">https://medium.com/media/971c36ebb6e0f7451e5351607f9f4c86/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FgkHe7giDoaU%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DgkHe7giDoaU&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FgkHe7giDoaU%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/ef98b0f8b381435b1ee300e9828a386e/href">https://medium.com/media/ef98b0f8b381435b1ee300e9828a386e/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f1f6a32f0718" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Gemini and Gemini in Android Studio: AI Powerhouses for Code]]></title>
            <link>https://devpicon.medium.com/gemini-and-gemini-in-android-studio-ai-powerhouses-for-code-861543610142?source=rss-5c60da6ae31c------2</link>
            <guid isPermaLink="false">https://medium.com/p/861543610142</guid>
            <category><![CDATA[gemini-in-android-studio]]></category>
            <category><![CDATA[ai-tools]]></category>
            <category><![CDATA[gemini]]></category>
            <category><![CDATA[android]]></category>
            <dc:creator><![CDATA[Armando Picón]]></dc:creator>
            <pubDate>Mon, 20 May 2024 05:14:18 GMT</pubDate>
            <atom:updated>2024-05-20T05:51:35.081Z</atom:updated>
            <content:encoded><![CDATA[<h4>This article had been written, or should I say ¿generated? with Gemini</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*xsbV_bO_Soln3RKj" /><figcaption>Photo by <a href="https://unsplash.com/@sepoys?utm_source=medium&amp;utm_medium=referral">Rohit Tandon</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p><strong>My prompt: Hey, can you help me write an article about Gemini in Android Studio? What’s relevant? What are the main features? How do we have control over which project can be read by the model? Include a comparison with the former Studio Bot. Differentiate between Gemini and Gemini in Android Studio.</strong></p><p>Google’s Gemini represents a major leap in AI capabilities. It’s a versatile large language model (LLM) designed for various tasks, from writing creative content to analyzing complex data. While Gemini is the broader technology, Gemini in Android Studio is a specialized application tailored for developers.</p><h4>Gemini: The Foundation</h4><p>Gemini is Google’s most advanced AI model. Its key features include:</p><ul><li><strong>Multimodal:</strong> It can process text, images, and potentially other formats, leading to richer interactions and outputs.</li><li><strong>General Purpose:</strong> Gemini isn’t limited to one domain. It’s designed for a wide range of applications across different industries.</li><li><strong>Flexible Deployment:</strong> Gemini can run on powerful servers or smaller devices, making it accessible for various use cases.</li></ul><h4><strong>Gemini in Android Studio: Your Coding Co-Pilot</strong></h4><p>Gemini in Android Studio (formerly Studio Bot) is the embodiment of Gemini’s power specifically harnessed for Android development. It leverages Gemini’s vast knowledge to provide:</p><ul><li><strong>Intelligent Code Generation:</strong> From creating UI elements to implementing complex features, Gemini helps you write code faster and more accurately. Describe what you need, and let Gemini handle the syntax.</li><li><strong>Expert Q&amp;A:</strong> Have a question about Android APIs, best practices, or error messages? Gemini provides insightful answers, drawing on its extensive knowledge of Android development.</li><li><strong>Context-Aware Suggestions:</strong> Gemini understands the nuances of your project and provides tailored recommendations, saving you time and effort.</li><li><strong>Future Crash Report Analysis:</strong> The upcoming integration of crash report analysis will enable Gemini to help you diagnose and fix issues more efficiently.</li><li><strong>Multilingual Support:</strong> Gemini is actively expanding its language support beyond English, increasing its accessibility for developers worldwide.</li></ul><p><strong>Comparing Gemini and Gemini in Android Studio:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/68b2ad1e730f6d594a8be927bf1156c7/href">https://medium.com/media/68b2ad1e730f6d594a8be927bf1156c7/href</a></iframe><p><strong>Privacy and Control in Gemini in Android Studio:</strong></p><p>Gemini in Android Studio is built with privacy in mind. By default, its responses are based solely on conversation history. You have full control over which project code, if any, to share with Gemini for more personalized suggestions.</p><p>To customize Gemini’s access, create a .aiexclude file in your project&#39;s root directory to specify which files or directories should remain private.</p><p><strong>Embracing the Future of Android Development:</strong></p><p>Gemini in Android Studio is a game-changer, empowering developers to work smarter, not harder. By leveraging AI assistance, you can accelerate your development process, improve code quality, and ultimately create better Android apps.</p><p><em>Don’t wait — dive into Gemini in Android Studio and experience the future of Android development today!</em></p><p><strong>If you reach this part, you can read </strong><a href="https://devpicon.medium.com/gemini-in-android-studio-absolutely-better-than-the-former-studio-bot-f1f6a32f0718"><strong>my honest opinion about Gemini in Android Studio</strong></a><strong>.</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=861543610142" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kotlin — Sealed classes vs Sealed interface]]></title>
            <link>https://devpicon.medium.com/kotlin-sealed-classes-vs-sealed-interface-68681f577b06?source=rss-5c60da6ae31c------2</link>
            <guid isPermaLink="false">https://medium.com/p/68681f577b06</guid>
            <category><![CDATA[kotlin-beginners]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[kotlin]]></category>
            <dc:creator><![CDATA[Armando Picón]]></dc:creator>
            <pubDate>Tue, 19 Mar 2024 23:44:34 GMT</pubDate>
            <atom:updated>2024-03-27T11:13:07.612Z</atom:updated>
            <content:encoded><![CDATA[<h3>Kotlin — Sealed classes vs Sealed interface</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/957/1*tzj3EcLsgcrcR6FzRnCuCg.png" /><figcaption>“an army of bugdroid with shields safeguarding a castle” — image generated by Midjourney</figcaption></figure><p>Some developers often have difficulties choosing between these two sealed components, so I intend to provide some clarity to help them understand when they use one or the other with this short article.</p><blockquote>Note for Spanish native speakers: Si eres hispanohablante y no tienes claro lo que es una Sealed class puedes visitar este artículo escrito en el 2020 por <a href="https://medium.com/u/fa74850821ac">Facundo Rodríguez Arceri</a> llamado “<a href="https://medium.com/droid-latam/sealed-classes-en-kotlin-por-qu%C3%A9-y-para-qu%C3%A9-67bb9e1f2e5e">Sealed classes en Kotlin: ¿Por qué y para qué?</a>” que sigue vigente aún y puede servirte como base para luego volver a este artículo.</blockquote><h4>Let’s begin with the basis…</h4><p>Why do we create a class or an interface regularly? I think answering this question could help us find reasons to choose between both sealed components.</p><p>A class can represent states and entities, while an interface helps us declare what behaviors are supported by a class but without describing how or creating a contract.</p><h4>Sealed class</h4><p>For instance, think about the state of a User profile screen with some data to be displayed. We usually represent creating a class like this:</p><pre>class UserProfileScreen(<br>  val name:String,<br>  val address:String,<br>  val tags:List&lt;String&gt;<br>)</pre><p>Even though this class can represent the state of the screen when the data is displayed to the users, we know that we’ll need at least one additional state to cover the loading state.</p><p>We could add a loading attribute to our UserProfileScreen class, which could violate the Single Responsibility principle. So here is when a Sealed class can help us.</p><pre>sealed class UserProfileState<br>data class UserProfileScreen(<br>    val name: String,<br>    val address: String,<br>    val tags: List&lt;String&gt;<br>) : UserProfileState()<br>data object LoadingUserProfileScreen : UserProfileState()</pre><p>Now, we have a better representation of the states, which is easier to identify and understand. But what do we gain by declaring states in this way?</p><ul><li>By default, every class in Kotlin is final, so you can’t create an inheritance without marking the parent class as open.</li><li>Make it possible to declare attributes to be shared by each subclass that extends the sealed class.</li></ul><h4>Sealed interface</h4><p>One way you can take a sealed interface is to declare common classes that are not exactly to be used in the same context. This is opposite to a sealed class that defines related types for the same context.</p><p>I will take the example <a href="https://kotlinlang.org/docs/sealed-classes.html#declare-a-sealed-class-or-interface">provided by the official documentation</a>.</p><pre>// Create a sealed interface<br>sealed interface Error<br><br>// Create a sealed class that implements sealed interface Error<br>sealed class IOError(): Error<br><br>// Define subclasses that extend sealed class &#39;IOError&#39;<br>class FileReadError(val file: File): IOError()<br>class DatabaseError(val source: DataSource): IOError()<br><br>// Create a singleton object implementing the &#39;Error&#39; sealed interface<br>object RuntimeError : Error</pre><p>Even though we declare error types, we can distinguish between those errors related to I/O operations and those related to runtime errors.</p><h4>Conclusion</h4><p>I did not want to be exhaustive about definitions and scenarios to use sealed classes or interfaces, only to mention something that would be helpful to identify when you can use one or the other.</p><p>Sealing a class or an interface lets you safeguard the possible states of any modification outside the scope of the package where these classes were declared. It is particularly helpful when you are creating libraries.</p><p>As <a href="https://kotlinlang.org/docs/sealed-classes.html#use-sealed-classes-with-when-expression">the documentation mentions</a>, you can use the sealed classes and interface with when expressions; it allows the compiler to check that all possible cases are covered.</p><p>And that’s it; I hope this brief article will be useful. I’m open to receiving comments about how you use these sealed components or if you have other criteria to choose between them.</p><p>See you next time…</p><h4>References &amp; other articles</h4><ul><li>Sealed classes and interfaces | Kotlin documentation<br><a href="https://kotlinlang.org/docs/sealed-classes.html">https://kotlinlang.org/docs/sealed-classes.html</a></li><li>Sealed classes en Kotlin: ¿Por qué y para qué? (in Spanish)<br><a href="https://medium.com/droid-latam/sealed-classes-en-kotlin-por-qu%C3%A9-y-para-qu%C3%A9-67bb9e1f2e5e">https://medium.com/droid-latam/sealed-classes-en-kotlin-por-qu%C3%A9-y-para-qu%C3%A9-67bb9e1f2e5e</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=68681f577b06" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Android — Scalable dependency management with version catalogs]]></title>
            <link>https://devpicon.medium.com/scalable-dependency-management-with-version-catalog-4a0cbf5d5859?source=rss-5c60da6ae31c------2</link>
            <guid isPermaLink="false">https://medium.com/p/4a0cbf5d5859</guid>
            <category><![CDATA[dependency-management]]></category>
            <category><![CDATA[android-development]]></category>
            <category><![CDATA[gradle]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[version-catalog]]></category>
            <dc:creator><![CDATA[Armando Picón]]></dc:creator>
            <pubDate>Sat, 16 Dec 2023 01:08:08 GMT</pubDate>
            <atom:updated>2023-12-16T13:49:15.813Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*z8FhE8RX8y24Lgr21clDDg.png" /><figcaption>This digital illustration symbolizes efficient dependency management in software development, featuring an organized network of connections with subtle integrations of the Android and Gradle logos — DALL-E</figcaption></figure><p>I’m revisiting some helpful content for starting a new Android project. One of the pain points is how to handle a ton of dependency declarations for multi-module projects. Here is where version catalogs come to our rescue.</p><h3>Declaring dependencies</h3><p>Before discussing the version catalogs, we will see how dependencies are being declared in an Android project. To declare a dependency in an Android project, you would add something like the following code in your build.gradle.kts file:</p><pre>plugins {<br>  //...<br>}<br>android {<br>  //...<br>}<br>dependencies {<br>  // Here is where the dependencies are declared<br>  implementation(&quot;androidx.core:core-ktx:1.12.0&quot;)<br>  // ...other dependecies<br>}</pre><h3>Coordinates</h3><p>One important concept to have in mind is the concept of <strong><em>coordinates</em></strong>. Each coordinate is composed by “<strong>[group]:[artifact name]:[version</strong>]”. For example, in the example above, the coordinate of the core-ktx dependency is [androidx.core]:[core-ktx]:[1.12.0], so the same dependency can be decomposed in a declaration like this:</p><pre>implementation(group = &quot;androidx.core&quot;, name = &quot;core-ktx&quot;, version = &quot;1.12.0&quot;)</pre><p>Keep in mind this concept; we will return to it later.</p><h3>A common issue with multi-module projects</h3><p>In case you have more than one module in your project, each dependency needs to be declared on every module that requires the specific dependency. The problem arises with this approach because of having repetitive declarations; every time you want to update a dependency version, you have to make the change in every gradle file where the dependency is declared. This makes dependency handling redundant and messy.</p><p>Here is where <strong>Version catalogs</strong> come to our rescue.</p><h3>Version catalogs</h3><p>Version catalogs are a feature of Gradle, so you can use it if you use Gradle as your build system in your Android project. This allows you to declare and organize all your dependencies in a single file, which acts as a catalog where each dependency is associated with a single alias, making this catalog act as a source of truth and it can be referenced in every gradle file.</p><p>To enable this option, you need to follow these steps:</p><ol><li>Create a new file in the gradle folder at the project level with the name libs.versions.toml.</li><li>Declare the dependencies into that file.</li><li>Reference these declarations in every gradle file of each module.</li></ol><p>If you don’t know where the gradle folder is, you can typically find it at the root project level; you can use the Project view to look at it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/213/1*WkkqVaoiZfg1v9aYqQ_dCg.jpeg" /></figure><p>At this point, you can ask… how these declarations must be made into that file?</p><h3>Basic usage</h3><p>Now, let’s see the structure of the libs.versions.toml file.</p><pre>[versions]<br>core-ktx = &quot;1.12.0&quot;<br><br>[libraries]<br>androidx-core-ktx = { group = &quot;androidx.core&quot;, name = &quot;core-ktx&quot;, version.ref = &quot;core-ktx&quot; }</pre><p>In the most basic format, you have to declare two sections [versions] and [libraries], the first one is used to declare versions for each dependency, the second is for the dependencies itself.</p><p>For this example, we took the same dependency that has been declared in the first example of this article in the gradle file. In order to make the core-ktx dependency available in the libs catalog, we associate the alias androidx-core-ktx to the GAV (group, artifact, version) coordinates.</p><p><strong>The main benefit is these declarations are visible by all the modules in your project. So you can reference these declarations from your gradle file.</strong></p><pre>plugins {<br>  //...<br>}<br><br>android {<br>  //...<br>}<br><br>dependencies {<br>	// Here is where the dependencies are declared<br>	implementation(libs.androidx.core.ktx)<br>	// ...other dependecies<br>}</pre><p><em>Note: Every time you add a new declaration in the TOML file, you have to sync the project to make it available for the modules.</em></p><p>Also, using Version catalogs allows you to reference the same version for multiple different libraries, for example:</p><pre>[versions]<br>android-paging = &quot;3.2.1&quot;<br><br>[libraries]<br>android-paging-common = { module = &quot;androidx.paging:paging-common-ktx&quot;, version.ref = &quot;android-paging&quot; }<br>android-paging-runtime = { module = &quot;androidx.paging:paging-runtime-ktx&quot;, version.ref = &quot;android-paging&quot; }<br>android-paging-rxjava2 = { module = &quot;androidx.paging:paging-rxjava2-ktx&quot;, version.ref = &quot;android-paging&quot; }</pre><p>Here, we simplify the coordinates using the module to group the [group]:[artifact] pair and use the same version reference for all the android-paging dependencies.</p><h3>Going a bit further</h3><p>Not only you can declare the regular dependencies in that TOML file, but you can also declare your plugins and even create bundles for grouping dependencies.</p><h3>How to declare plugins</h3><p>To declare a plugin, you only need to add the [plugins] section.</p><pre>[versions]<br>//Here the versions are declared<br>android-gradle-plugin = &quot;8.2.0&quot;<br><br>[libraries]<br>//Here the libraries are declared<br><br>[plugins]<br>android-application = {id = &quot;com.android.application&quot;, version.ref = &quot;android-gradle-plugin&quot;}</pre><p>So, after syncing the project, we can change the references from this</p><pre>// Top-level build file where you can add configuration options common to all sub-projects/modules.<br>plugins {<br>    id(&quot;com.android.application&quot;) version &quot;8.2.0&quot; apply false<br>    //... more plugins are placed here<br>}</pre><p>To this</p><pre>// Top-level build file where you can add configuration options common to all sub-projects/modules.<br>plugins {<br>    alias(libs.plugins.android.application) apply false<br>    //... more plugins are placed here<br>}</pre><h3>How to create your own bundle</h3><p>To create a bundle, you have to add a [bundles] section into your TOML file. For example, here I’m adding the Room bundle.</p><pre>[versions]<br>room = &quot;2.6.1&quot;<br>ksp = &quot;1.9.0-1.0.13&quot;<br><br>[libraries]<br>androidx-room-compiler = { group = &quot;androidx.room&quot;, name = &quot;room-compiler&quot;, version.ref = &quot;room&quot; }<br>androidx-room-ktx = { group = &quot;androidx.room&quot;, name = &quot;room-ktx&quot;, version.ref = &quot;room&quot; }<br>androidx-room-runtime = { group = &quot;androidx.room&quot;, name = &quot;room-runtime&quot;, version.ref = &quot;room&quot; }<br><br>[plugins]<br>kotlin-symbol-processing = { id = &quot;com.google.devtools.ksp&quot;, version.ref = &quot;ksp&quot; }<br><br>[bundles]<br>android-room-bundle = [&quot;androidx-room-ktx&quot;, &quot;androidx-room-runtime&quot;]</pre><p>Again, you can use the bundle like this after syncing your project.</p><pre>plugins {<br>    // More plugins are added here...<br>		alias(libs.plugins.kotlin.symbol.processing)<br>}<br><br>android {<br>  //...<br>}<br><br>dependencies {<br>    // Some dependencies are declared here<br>    implementation(libs.bundles.android.room.bundle)<br>    ksp(libs.androidx.room.compiler)<br>}</pre><h3>Conclusion</h3><p>It’s also worth mentioning that using a version catalog is likely the best way to establish a single source of truth for all your project dependencies. It’s also worth mentioning that the official documentation has a section about this topic.</p><p>You can experiment with different strategies using bundles to organize the necessary dependencies for each project, avoiding the tedious process of checking each Gradle file to see what you’ve declared.</p><h3>References</h3><p>Migrate to version catalogs</p><p><a href="https://developer.android.com/build/migrate-to-catalogs">https://developer.android.com/build/migrate-to-catalogs</a></p><p>Sharing dependency version between projects</p><p><a href="https://docs.gradle.org/current/userguide/platforms.html">https://docs.gradle.org/current/userguide/platforms.html</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4a0cbf5d5859" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Android — A consideration about Transitioning from Views to Compose]]></title>
            <link>https://devpicon.medium.com/android-a-consideration-about-transitioning-from-views-to-compose-2c03c6eeedd9?source=rss-5c60da6ae31c------2</link>
            <guid isPermaLink="false">https://medium.com/p/2c03c6eeedd9</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[design]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[ui-design]]></category>
            <dc:creator><![CDATA[Armando Picón]]></dc:creator>
            <pubDate>Sat, 12 Mar 2022 18:55:53 GMT</pubDate>
            <atom:updated>2022-03-12T18:55:53.827Z</atom:updated>
            <content:encoded><![CDATA[<h3>Android — A consideration about Transitioning from Views to Compose</h3><p>In the last few months, my team and I have been thinking about the best way to adopt Compose. After checking a ton of articles and videos suggesting ways to make this transition, a couple of things helped us create a path for this.</p><p>Something my entire team shares is our desire to use or at least test all the new components the Android team releases as it is released. That is why we create our pet projects to use them and test them in a controlled environment.</p><p>We take our time adopting something new because it is irresponsible to introduce something new only because of <a href="https://en.wikipedia.org/wiki/Fear_of_missing_out">FOMO</a>. We know that our users do not care what or how many tools, old or new, we use. They only want a good experience when they are using our apps.</p><h4>Jetpack Compose</h4><p>As many of you know, Jetpack Compose is the newest way to create our UIs on Android. Using Kotlin as the language and the current version of Android Studio (Arctic Fox), we can create UIs declaring all the components required.</p><p>Even though we can create components on demand, Compose encourages the creation of reusable components, and this could be a problem if your application does not follow a design system.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/480/0*3HfyOAwruY7xy5iq.png" /><figcaption>Jetpack Compose is the new UI system provided by Android team</figcaption></figure><h4>Design system</h4><p>A design system is a group of allowed elements that different teams can use to design and implement new features. This set of elements helps us to standardize the look and feel of every screen, making it easier for the users to identify common behaviors when they use our app. Furthermore, they reduce the complexity that designing a new screen requires.</p><p>Counting with a design system provides you with several common components you can create and use across all the features of your app. But how can we create a design system? Here is where a methodology called Atomic Design enters the field.</p><h4>Atomic Design</h4><p>Atomic Design is a methodology for creating design systems. It drives composing screens by building with smaller reusable components toward building ever more complex constructions. This methodology was created for Web development, but we can use the same principles in developing mobile applications.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*UbPCB4UK6SzkOaPk.png" /><figcaption>Source: <a href="https://bradfrost.com/blog/post/atomic-web-design/">https://bradfrost.com/blog/post/atomic-web-design/</a></figcaption></figure><p>Under this metaphor:</p><ul><li>Atoms could be the view elements that Android provides us. These elements could be views or composable functions.</li><li>Molecules are a combination of different atoms. Under our Android Perspective, a molecule could be a component composed of different types of views (eg. an ImageView + a title TextView + a brief description with other TextView) or a bit complex Composable function that receives the content. A molecule should be reusable.</li><li>Organisms should be reusable sections composed of different molecules, atoms, or even other organisms. These sections could be populated by different data in different places in the application.</li><li>Templates, from the View perspective, should be a group of containers to distribute and organize elements into a screen. From the Compose perspective, Composable functions as Scaffold or any complex Composable function that receives other Composable functions and brings distribution of elements to the screen.</li><li>Pages should be our screens.</li></ul><h4>What does it look like?</h4><p>I’m sure an image is better than words, so look at this image below</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*BSTXxYv23cpVYRjD.png" /><figcaption>source: <a href="https://www.uplabs.com/posts/android-design-system">Android Design System — UpLabs</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*XutO1BJrTtlRqql1.png" /><figcaption>source: <a href="https://www.uplabs.com/posts/android-design-system">Android Design System — UpLabs</a></figcaption></figure><p>As you can see, these images show you some screens, their components, and elements that are part of them.</p><p>These pages called design kits usually are developed using tools like Figma, Sketch, or Adobe XD.</p><h4>Having a clear idea in our mind</h4><p>With our design system defined, we can start following the recommendations of other developers.</p><p>Start migrating a low-risk screen using any of the different ways to combine Views and Compose. You can even build new screens from zero. Having a design system allows you to create a palette of reusable components on a single module to build or migrate any screen you want in your project.</p><p>Obviously, you always can create components directly without a design system, but after seeing its benefits, I will recommend this way to work because it reduces some cognitive charge provoked when you have to build from scratch those components that a screen requires.</p><h4>References</h4><ul><li>Atomic Design<br><a href="https://bradfrost.com/blog/post/atomic-web-design/">https://bradfrost.com/blog/post/atomic-web-design/</a></li><li>UpLab<br><a href="https://www.uplabs.com/templates/android">https://www.uplabs.com/templates/android</a></li><li>Jetpack Compose<br><a href="https://developer.android.com/jetpack/compose">https://developer.android.com/jetpack/compose</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2c03c6eeedd9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Demystifying Clean Architecture]]></title>
            <link>https://devpicon.medium.com/demystifying-clean-architecture-1cf744a3692e?source=rss-5c60da6ae31c------2</link>
            <guid isPermaLink="false">https://medium.com/p/1cf744a3692e</guid>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[clean-architecture]]></category>
            <dc:creator><![CDATA[Armando Picón]]></dc:creator>
            <pubDate>Tue, 01 Feb 2022 01:33:15 GMT</pubDate>
            <atom:updated>2022-02-12T22:04:36.943Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/960/0*DTDlu71ZSTVsQsR1" /></figure><p><em>¿Buscas la versión en español de este artículo? </em><a href="https://medium.com/kotlin-dev-reactor/android-desmitificando-clean-architecture-2d0ed6aa2de6"><em>Haz click aquí</em></a></p><h3>Before We Start</h3><p>If this is your first time reading about Clean Architecture, you need to keep the following in mind,</p><ul><li><em>Clean Architecture</em> is the title of a book by Robert C. Martin, aka. Uncle Bob (2017). There is an article in their blog with the same title.</li><li>“Clean Architecture” is not actually architecture itself, but a guide with a specific set of principles. The author tries to synthesize elements in common on several architectures.</li><li>SOLID is an acronym created by Uncle Bob for his first five object-oriented design principles. “Clean Architecture” uses those principles as its foundation.</li><li>Uncle Bob’s guide leads you to structure your app with the <em>Domain</em> layer as its center. This is where you will find the application’s rules.</li><li>Developers often confuse N-layer-based architecture with “Clean Architecture.”</li><li>“Clean Architecture” is a mainstream phrase that developers use as an easier way to describe application structures to others.</li></ul><h3>What is architecture?</h3><p>Architecture is a structure, a way to distribute your application components in various groups. There is not a single way to organize your projects because it could depend on several aspects like project state, team size, time constraints, etc.</p><h3>Clean Architecture on Android</h3><p>Many developers point out Separation of Concerns and Testing as two of the main aspects of Clean Architecture. However, they forget that it is imperative to have a well-implemented <em>Domain</em> layer. Why? Because all of the application and business rule components are located in the <em>Domain </em>layer; they control the entire application.</p><p>How then would a project based on these principles be structured? There are two considerations to take into account before defining the structure:</p><ul><li>The Dependency Rule says that source code dependencies can only point inwards. Nothing in an inner circle can know anything about something in an outer circle.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/0*65sKA9eCQH8uB1Zy.png" /></figure><ul><li>There are data that need to cross boundaries, from out to inner layers and vice-versa. Because we have to respect the Dependency Rule, we solve this issue by using the Dependency Inversion principle.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/0*9GRnnN4My8JQpMuE.png" /></figure><p>Now, we can create a basic structure using three modules‒ Presentation, Domain, and Data. They will represent each one of the layers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/0*PVvoUA3pyMtaN5ZP.png" /></figure><h3>What components go into each layer?</h3><p>Remember, when we speak about architecture, we are speaking about structure and organization. This depends on the purpose of every component I added to the application.</p><p>The following describes a three-layered architecture represented in three modules:</p><ul><li>The <strong>Domain module</strong> contains components with the business and application rules like Interactors, Use Cases, and Domain classes, along with, the abstractions of repositories represented by interfaces. This module will be without reference to the Android Framework, and it should be created as a Kotlin Gradle module.</li><li>The <strong>Presentation module</strong> contains every UI element like Views or Composable functions. Under patterns like MVP or MVVM, components like Presenters or ViewModels reside here. Because this module will use dependencies from the Android Framework, this module must be created as an Android Gradle module.</li><li>The <strong>Data module</strong> contains every component related to consuming external services and the local persistence of data. Client implementations of Room, Retrofit, SharedPreferences or/and any third-party dependency will be placed in this module. Additionally, if we declare the abstractions of repositories in the <em>Domain</em> layer, the concrete implementations will be into the <em>Data</em> module too. This S sounds obvious, but this module must be created as an Android Gradle module too.</li></ul><h3>Dependency Inversion Principle</h3><p>Previously, we mentioned data needs to cross boundaries between layers. How do you consume components from the <em>Data</em> layer into components of your <em>Domain</em> layer? The answer is the Dependency Inversion principle.</p><p>This principle establishes two rules:</p><ul><li>High-level modules should not import anything from low-level modules. But they should depend on abstractions (interfaces).</li><li>The abstractions should not depend on details (concrete implementations), but details should depend on abstractions.</li></ul><p>According to these rules, we need to add an interface to the Domain module. This represents the operations that will be available in the Repository class. Adding an interface to the Domain module isolates the Use Case from any specific implementation. Following these rules, we also make the Data module depend on the Domain module, which helps us keep the concrete implementation separated from the Domain.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/0*wgDCT1G0Fy6K-jgS" /></figure><p>In order to ground these concepts, we will see how to put them in code. These definitions below t will be placed in the <em>Domain</em> module.</p><pre><em>interface </em>BookRepository {<br>    <em>suspend fun </em>getBooks():List&lt;Book&gt;<br>}</pre><pre><em>class </em>GetBooksUseCase(<br>    <em>private val </em>bookRepository: BookRepository<br>) { <em>/*...*/ </em>}</pre><p>Meanwhile, in the <em>Data</em> module, we will find the concrete implementation of that repository.</p><pre><em>class </em>BookRepositoryImpl (...) : BookRepository {<br>    <em>override suspend fun </em>getBooks(): List&lt;Book&gt; { /* ... */}<br>}</pre><p>Thus, having the repository abstraction will help us inject this repository into the Use Case component.</p><h3>Final thoughts</h3><ul><li>There is no single way to structure a project, and each architecture has its characteristics.</li><li>Even though you do not define an architecture, following the SOLID principles will lead you to maintain a well-organized code.</li><li>The revamped Android Architecture official guide offers you a structure-based in layers without a clear definition of a business layer.</li><li>Having a well-separated domain layer helps you define your Presentation and Data layer as you wish. For example, you could use a View-based UI system or Compose in your Presentation module, or use Retrofit, Volley, or Ktor in your Data module. Every change you made in any of these modules should not affect others.</li></ul><h3>References</h3><ul><li><em>Clean Architecture<br></em><a href="https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164">https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164</a></li><li>Dependency Inversion principle<br><a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">https://en.wikipedia.org/wiki/Dependency_inversion_principle</a></li><li>Architecting Android…Reloaded by Fernando Cejas<br><a href="https://fernandocejas.com/blog/engineering/2019-05-08-architecting-android-reloaded/">https://fernandocejas.com/blog/engineering/2019-05-08-architecting-android-reloaded/</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1cf744a3692e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Android — Desmitificando Clean Architecture]]></title>
            <link>https://medium.com/kotlin-dev-reactor/android-desmitificando-clean-architecture-2d0ed6aa2de6?source=rss-5c60da6ae31c------2</link>
            <guid isPermaLink="false">https://medium.com/p/2d0ed6aa2de6</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[architecture]]></category>
            <category><![CDATA[software-architecture]]></category>
            <dc:creator><![CDATA[Armando Picón]]></dc:creator>
            <pubDate>Thu, 30 Dec 2021 17:24:14 GMT</pubDate>
            <atom:updated>2022-02-12T22:03:10.309Z</atom:updated>
            <content:encoded><![CDATA[<h3>Android — Desmitificando Clean Architecture</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*Nk1jq6QYkEIwEn3ZS2J44g.png" /></figure><p><em>Looking for the English version of this article? </em><a href="https://devpicon.medium.com/demystifying-clean-architecture-1cf744a3692e"><em>Click here</em></a></p><h3>Antes de comenzar…</h3><p>Si es tu primera vez leyendo sobre <em>Clean Architecture</em> quizá te convenga saber algunas cosillas antes de seguir:</p><ul><li><em>Clean Architecture</em> es el título de un libro escrito por Robert C. Martin (aka. Uncle Bob)</li><li>No es una arquitectura en sí, sino una guía que encierra un conjunto de principios a seguir.</li><li>La base de esta guía se encuentra en aplicar los principios SOLID.</li><li>En términos generales, te intenta llevar a una estructura basada en el Dominio como punto central de tu aplicación (la capa en la que se implementará la lógica de tu aplicación). ¿Alguien habló de <em>Domain-driven development</em>?</li><li>Un buen número de desarrolladores la confunde la arquitectura con N-capas.</li><li>No es el santo grial, es una expresión algo <em>mainstream</em> entre los desarrolladores y por ende sirve como una forma fácil de describirle a un desarrollador de qué manera se ha estructurado un proyecto.</li></ul><h3>¿Qué es una arquitectura?</h3><p>Básicamente, es una estructura, una manera de distribuir los componentes que conforman una aplicación en distintas agrupaciones. Por esto mismo, no existe una única manera de organizar tu proyecto. Diversos aspectos como el estado de tu proyecto, el tamaño de tu equipo, el tiempo, etc influirán en las decisiones que tomes al momento de decidir la manera en la que organizarás los componentes de tu aplicación.</p><h3>Clean Architecture en el mundo Android</h3><p>Mucho se ha dicho y escrito sobre cómo aplicar <em>Clean Architecture</em> en las aplicaciones que desarrollamos, un buen número de desarrolladores te hablarán sobre <em>Separation of concerns and testing</em> como las principales características de seguir estos principios, suelen a su vez olvidar un aspecto muy importante sobre <em>Clean Architecture</em> y que consiste en que su base yace en la implementación de la capa de Dominio.</p><p>Dicho esto ¿cómo se estructuraría un proyecto base siguiendo estos principios? Para trabajar en esto es importante establecer dos consideraciones importantes:</p><ul><li>Existe una regla en <em>Clean Architecture</em> por la cual toda capa exterior dependerá de una capa interior (y no al revés), quedando para el final la capa de Dominio sin dependencia alguna.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*x8NeftsswbwipO6RNiTqNQ.png" /></figure><ul><li>Existe un flujo de datos que pasa por todas las capas externas e internas tanto de ida desde que se efectúe el ingreso de datos por parte del usuario (o de los sensores), pasando por la lógica de negocio/aplicación y terminando en la persistencia de los datos o el envío de los mismos a un servicio remoto, como también de vuelta con el resultado de la operación con el servicio hasta la presentación del resultado a nuestro usuario.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*B0Ia60Stn7r4sbYN63Kf2w.png" /></figure><p>Teniendo en cuenta estos dos aspectos, para una estructura básica contaríamos con tres módulos: <em>presentation</em>, <em>domain</em> y <em>data</em>. La relación entre estos sería de la siguiente manera:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*frzS0vpV803mrFKylT0STA.png" /></figure><h3>¿Qué componentes irían en cada capa?</h3><p>Es importante reiterar que al hablar de arquitectura, hablamos de organización y estructura, por lo tanto, la distribución y qué componentes en específico irán en cada módulo dependerá del patrón que decidas emplear y el propósito de cada módulo:</p><ul><li><em>Domain</em> deberá contener los elementos que contengan la lógica de tu aplicación y la lógica del negocio. Con ello en mente, tendremos clases de dominio, y además componentes que tendrán la lógica como son los Casos de Uso o Interactors. Este módulo NO debe depender del <em>Android framework</em> ni de dependencias de terceros. Este módulo puede ser un módulo Kotlin.</li><li><em>Presentation</em> tendrá los elementos que permitan mostrar información a nuestro usuario, recibir datos del mismo o de sensores. Además de los componentes visuales propios de Android (Activity y Fragment) y su sistema de UI (archivos XML o funciones de Compose), si se siguen patrones como MVP o MVVM, tendremos también Presenters o ViewModels respectivamente. Este módulo es un módulo Android.</li><li><em>Data</em> va a incluir todas las dependencias de networking (Retrofit, volley, etc) y de persistencia de datos (Room, SharedPreferences, DataStore, Firebase, etc). Si se emplea el patrón repositorio será en esta capa en la que tendremos la implementación de los repositorios y las fuentes de datos (<em>data sources</em>). Este módulo es un módulo Android también.</li></ul><p>Seguramente aquí te podría surgir la siguiente duda: si <em>Domain</em> no tiene visibilidad de <em>Data</em> ¿cómo es que podríamos inyectar los repositorios en nuestros casos de uso? La respuesta se encuentra en el principio de Inversión de Dependencia (<em>Dependency inversion</em>) de SOLID.</p><h3><em>Dependency inversion principle</em></h3><p>Este principio de SOLID establece dos consignas:</p><ul><li>Los módulos de alto nivel no deberían importar nada de un módulo de bajo nivel. Pero ambos deberían depender de abstracciones (interfaces).</li><li>Las abstracciones no deberían depender de los detalles. Los detalles (las implementaciones concretas) deberían depender de las abstracciones.</li></ul><p>Teniendo en mente esto, nuestro módulo <em>Domain</em> deberá ser propietario de la interfaz del repositorio que se implementará dentro del módulo <em>Data</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*jShiu5axVuAmjF0JWfX1uw.png" /></figure><p>En código esto luciría más o menos de la siguiente manera, en el módulo <em>Domain</em> estaría la abstracción de un BookRepository.</p><pre><em>interface </em>BookRepository {<br>    <em>suspend fun </em>getBooks():List&lt;Book&gt;<br>}</pre><pre><em>class </em>GetBooksUseCase(<br>    <em>private val </em>bookRepository: BookRepository<br>) { <em>/*...*/ </em>}</pre><p>Mientras que en el módulo <em>Data</em> iría su implementación.</p><pre><em>class </em>BookRepositoryImpl (...) : BookRepository {<br>    <em>override suspend fun </em>getBooks(): List&lt;Book&gt; { /* ... */}<br>}</pre><p>De este modo al momento de crear una instancia de nuestro caso de uso le podremos inyectar la implementación debido a la interfaz que hemos declarado.</p><h3>Conclusiones</h3><p>Podría mencionar algunas cosas como parte de la conclusión:</p><ul><li>Contar con una arquitectura o forma de organizar los componentes es mejor que no tener ninguna.</li><li><em>Clean Architecture</em> no es una arquitectura en sí, pero nos provee de una guía a seguir para estructurar nuestros proyectos.</li><li>Existen otras arquitecturas que no cuentan con mucha fama, pero no por ello son menos útiles.</li><li>Teniendo esta estructura, puedes usar lo que se te antoje tanto en la presentación (sea Views-XMLs o Compose) como a nivel del acceso a datos (Retrofit, Room, SharedPreferences, etc).</li><li>En mi experiencia, la buena aplicación de los principios SOLID te da una buena base para ir perfilando la arquitectura de tu proyecto.</li><li>La relanzada <a href="https://developer.android.com/jetpack/guide">guía oficial de arquitectura de Android</a> no sigue Clean Architecture, pero sí provee de una arquitectura separada en capas.</li></ul><h3>Referencias</h3><ul><li><em>Clean Architecture<br></em><a href="https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164">https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164</a></li><li>Dependency Inversion principle<br><a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">https://en.wikipedia.org/wiki/Dependency_inversion_principle</a></li><li>Architecting Android…Reloaded by Fernando Cejas<br><a href="https://fernandocejas.com/blog/engineering/2019-05-08-architecting-android-reloaded/">https://fernandocejas.com/blog/engineering/2019-05-08-architecting-android-reloaded/</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2d0ed6aa2de6" width="1" height="1" alt=""><hr><p><a href="https://medium.com/kotlin-dev-reactor/android-desmitificando-clean-architecture-2d0ed6aa2de6">Android — Desmitificando Clean Architecture</a> was originally published in <a href="https://medium.com/kotlin-dev-reactor">DevPicon by Armando</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>