<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Ryan Michael Kay - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Ryan Michael Kay - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Wed, 20 May 2026 22:46:09 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/ryan-michael-kay/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Choose the Best Programming Languages, Libraries, and Patterns ]]>
                </title>
                <description>
                    <![CDATA[ In my first few years learning software development and building applications, I was quite interested in finding the best programming language, platform, libraries, frameworks, patterns, and architectures available. I thought that by finding the best... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-choose-the-best-programming-languages-libraries-and-patterns/</link>
                <guid isPermaLink="false">6898d3414c52a26ffefb1693</guid>
                
                    <category>
                        <![CDATA[ Programming Blogs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ programming languages ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ryan Michael Kay ]]>
                </dc:creator>
                <pubDate>Sun, 10 Aug 2025 17:13:37 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1754846007203/c9db729e-ebed-4726-8e3e-5414c8e2714d.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In my first few years learning software development and building applications, I was quite interested in finding the best programming language, platform, libraries, frameworks, patterns, and architectures available. I thought that by finding the <em>best</em> things and focusing on those topics to the exclusion of others, I could avoid wasting precious time.</p>
<p>While I figured out early on that narrowing my focus by using a project-based learning approach (as opposed to the topic-by-topic laundry list approach) was important, finding the best tools for the job was a different matter. </p>
<p>If you happen to be searching for some of those things, then this article is for you. After over a decade of programming products, building client applications, answering thousands of questions from junior and intermediate developers, and wrestling with these questions myself, I will do my best to explain how to find the best <em>things</em>.</p>
<p>This article is intended for junior to intermediate level developers looking to get some practical answers to difficult problems. You will not need extensive programming experience to get through it and you may skip over any technical discussions specifics. Those are meant to be helpful pieces of information, but the core of this article is about how to make these decisions in general using what I call: The Law of Suitability.</p>
<p>The topics I will cover are:</p>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-find-the-best-anything">How to Find the Best Anything</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-how-to-find-the-best-water-bottle">How to Find the Best Water Bottle</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-find-the-best-programming-language">How to Find the Best Programming Language</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-navigating-public-and-expert-opinions">Navigating Public and Expert Opinions</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-low-level-vs-high-level">Low Level vs High Level</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-tightly-structured-static-vs-loosely-structured-dynamic">Tightly Structured (Static) vs Loosely Structured (Dynamic)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-popularity-is-only-one-factor">Popularity Is Only One Factor</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-popularity-is-not-a-guarantee-of-employment">Popularity Is Not A Guarantee Of Employment</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-hardware-amp-working-with-what-you-have">Hardware &amp; Working With What You Have</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-if-i-want-the-ai-to-code-for-me">What if I Want the AI to Code For Me?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-avoid-the-sunk-cost-fallacy">Avoid the Sunk-Cost Fallacy</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-find-the-best-libraries-and-frameworks">How to Find the Best Libraries and Frameworks</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-are-libraries-and-frameworks">What Are Libraries and Frameworks?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-choose-libraries-and-frameworks">How to Choose Libraries and Frameworks</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-find-the-best-programming-principles-and-practices">How to Find the Best Programming Principles and Practices</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-dry-dont-repeat-yourself">D.R.Y – Don’t Repeat Yourself</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-about-other-programming-principles">What About Other Programming Principles?</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-a-note-about-patterns-and-architectures">A Note About Patterns and Architectures</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-find-the-best-software-architecture">How to Find the Best Software Architecture</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-design-pattern-trap">The Design Pattern Trap</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-summary">Summary</a></p>
</li>
</ul>
<h2 id="heading-how-to-find-the-best-anything">How to Find the Best Anything</h2>
<p>I invite you to follow along with some basic non-technical examples which lay the groundwork for the rest of this article. The examples may sound silly to some, but I have layered in some conceptual patterns which you can apply to programming languages, tools, and concepts – as well as just about anything where terms like good, bad, best, or worst can apply.</p>
<h3 id="heading-how-to-find-the-best-water-bottle">How to Find the Best Water Bottle</h3>
<p>Suppose that you are looking to solve the problem of staying hydrated and wish to purchase a water bottle. </p>
<p>You consider that figuring out the best water bottle might involve looking into:</p>
<ul>
<li><p>Public opinions and reviews</p>
</li>
<li><p>Expert opinions and reviews</p>
</li>
<li><p>The manufacturer’s descriptions and reputation</p>
</li>
<li><p>Buying and testing water bottles (though preferably not all of them, as that costs too much time and money, generally)</p>
</li>
</ul>
<p>All of those things are fair for consideration. Something which is not well-tested in public presents uncertainty. Expert reviews can help inform your decision, but you have to consider the biases and motivations of such experts. You also should consider if the manufacturer has a history of quality, design, and customer support, or whether they’re simply maximizing profit.</p>
<p>After doing some research, you come up with these options:</p>
<ul>
<li><p>A plastic bottle of water from a vending machine</p>
</li>
<li><p>A high-tech metal bottle which you can even boil stuff in!</p>
</li>
<li><p>A simple but ethically sourced, refillable, BPA-free plastic water bottle</p>
</li>
</ul>
<p>However, you noticed that nobody seemed to universally agree about which option was the best. There were usually some common opinions, but it was never the case that every expert had the same evaluation or recommendation.</p>
<p>After reflecting on this, it became obvious that you need to consider how, when, and where you will be using this water bottle. In other words, you need to <strong>consider the context or situation</strong> of its usage.</p>
<p>Suppose three different contexts within which you have to make this decision:</p>
<ul>
<li><p>You are standing in a rest stop in Death Valley California (often thought to be the hottest place on Earth in summer) and there is a vending machine full of micro-plastic filled, old, generic, and cheap plastic bottles of water in front of you. But you have no other options and are very thirsty</p>
</li>
<li><p>You are in a camping store preparing for a camping trip to New Zealand with lots of hiking and not too much access to filtered water</p>
</li>
<li><p>You are looking on your favorite shopping website for something you can bring to work each day to avoid those dehydration headaches from not drinking enough water</p>
</li>
</ul>
<p>In summary, you shouldn’t ignore second-hand knowledge, expert opinions, popularity, ratings, reviews, testimonials, and even first-hand experience. But you will never find the best water bottle for every situation you find yourself in. The best “anything” depends on the problem you are trying to solve and the context (words like requirements or situation also apply here) of that problem. </p>
<p>In other words, none of these things have an absolute or fixed value – their value is always relative. I call that the <strong>Law of Suitability</strong>.</p>
<p>Let’s now discuss some examples which are directly related to software design and development. </p>
<h2 id="heading-how-to-find-the-best-programming-language">How to Find the Best Programming Language</h2>
<p>The Law of Suitability applies just as much to programming languages as it does to water bottles – even though the details and contexts are different. There is no such thing as the best programming language for every person, team, problem, or feature. </p>
<p>But I do have some specific details and contexts to offer which may help you answer that question for yourself. This section will cover concrete details and some general ideas on how to choose a programming language. These patterns also apply to frameworks, libraries, and most other aspects of programming.</p>
<p>If you are not interested in the topic of finding a programming language, feel free to skip to the next sections on topics like libraries, principles, and patterns.</p>
<h3 id="heading-navigating-public-and-expert-opinions">Navigating Public and Expert Opinions</h3>
<p>Firstly, you need to be skeptical of popularity and the opinions of experts and “influencers” here. </p>
<p>My general tip here is to be extremely cautious about anyone who makes one of these claims:</p>
<ul>
<li><p>“X” language is the best (though saying “X” language is my favourite is perfectly acceptable)</p>
</li>
<li><p>“X” language is the worst, is terrible, is dead, is garbage, is useless, and so on.</p>
</li>
</ul>
<p>There are three groups of people who generally make these sorts of statements:</p>
<ul>
<li><p>Actual experts who are voicing their personal preferences but presenting them as immutable facts (how I wish this was not so common in this industry)</p>
</li>
<li><p>Non-experts parroting opinions of the above group or who have not yet understood the Law of Suitability</p>
</li>
<li><p>Engagement farmers</p>
</li>
</ul>
<p>It’s also worth noting that people can be experts in a subset of problems but that doesn’t guarantee their opinions about all problems are expert level. </p>
<p>This doesn’t mean you should reflexively dismiss expert opinions in general. Consider both the track records of the person and the degree to which they pay attention to the context of their statement. </p>
<p>Let us look at two examples:</p>
<ul>
<li><p><em>Expert A</em> says: “Python has the best tooling, support, and ecosystem for ML development”</p>
</li>
<li><p><em>Expert B</em> says: “Python is the best programming language”</p>
</li>
</ul>
<p>While <em>Expert B</em> is obviously displaying a lack of precision (either deliberately or not) if you have followed me so far, <em>Expert A</em> is a different case. Whether or not the statements made by <em>Expert A</em> are true (for the record, I have written a bit of Python but no ML code), you can tell that they are considering details and context. Look for people like <em>Expert A</em>!</p>
<h3 id="heading-low-level-vs-high-level">Low Level vs High Level</h3>
<p>In simple terms, low level programming languages are difficult for humans to read and write. Also, they tend to be faster and have a lower memory footprint than high level languages. Conversely, high level languages are closer to human language which generally makes them easier for humans to work with.</p>
<p>I must confess, though, that I have seen plenty of examples of people writing unintelligible code in high level languages – please don’t do that.</p>
<p>Someone working on an embedded system might want to do so in a language like C or C++ to optimize performance or work around the limitations of memory and processing power.</p>
<p>But in enterprise systems, which need to run on a variety of platforms and which closely intermingle with business requirements, rules, and real world objects (thing products, users, and so on), lower level languages are not so popular. After all, upper and middle management generally tends to care about low level optimizations only to the extent it affects the user experience. </p>
<p>I love optimization in general, but never forget that everything is fast with small datasets (that is, when <em>n</em> is small) or high processing power. In simpler terms, sometimes human concerns like legibility are significantly more important than insignificant optimizations on efficiency.</p>
<h3 id="heading-tightly-structured-static-vs-loosely-structured-dynamic">Tightly Structured (Static) vs Loosely Structured (Dynamic)</h3>
<p>Ironically, the main downsides and benefits of a language like Java (which is very structured and verbose) versus a language like JavaScript (quite the opposite, depending on how you use it) are the same depending on the context. </p>
<p>Speaking of enterprise systems, using structures, types, interfaces, classes, threading, concurrency primitives, and similar programming constructs can have a variety of benefits. It can insulate you from safety while providing some flexibility via type hierarchies, interfaces, protocols, abstractions and so on.</p>
<p>Further, studying design patterns can teach you repeatable solutions to problems which have been encountered since the dawn of the general purpose computer – or shortly thereafter. </p>
<p>But the Law of Suitability still applies here. Maybe you just need to write a quick script to migrate some data from one SQL database to another. Maybe you know how to approach problems using a more functional approach that doesn’t require or discourages the use of objects, classes, or structs. Maybe you realize one day that trying to apply design patterns, architectures, hierarchies and similar constructs in every situation has actually created as many problems as they were solving. More on that later.</p>
<p>It’s also worth mentioning that most modern language designers and maintainers have understood that we developers like flexibility. Many of us want to avoid premature optimization and unnecessary structure but also don’t want our code to blow up because we accidentally told the program to add together 1.23356 + “Rhinoceros”. </p>
<p>The main point is that structure or a lack of structure is both a blessing and a curse, depending on where it is used.</p>
<h3 id="heading-popularity-is-only-one-factor">Popularity Is Only One Factor</h3>
<p>I’m not going to say that popularity is irrelevant and that you should start with the least popular hipster programming language you can find. No shade intended to hipster programming languages, but unpopularity is not generally a good thing in isolation, either.</p>
<p>The key point is that many people weighing in on programming languages (probably most) don’t have abundant experience working on a variety of platforms, languages, and settings. If someone has only ever written Python and enjoys doing so, they will naturally tend to regard it above others.</p>
<p>We humans have a tendency to find the first thing that works for us and then die on a hill defending it. But to take a more anecdotal approach here, I know a couple dozen intermediate to senior level developers who have extensive experience in Java and other programming languages. Despite Java still being ranked as one of the most popular languages globally, only one of those developers I know actually prefers to write in Java if they have the choice. </p>
<p>Don’t make the mistake of assuming that the first thing that works for many people will be the last thing you need to try out. I have from time to time experimented with languages such as Haskell, which taught me many valuable lessons about the benefits of making my code more functional (and functionally pure) in nature. </p>
<p>But I have zero intention of using Haskell as my go to solution for building GUI applications. </p>
<h3 id="heading-popularity-is-not-a-guarantee-of-employment">Popularity Is Not A Guarantee Of Employment</h3>
<p>One of the most common things you ought to consider is whether or not the language you pick will help you get a job – assuming that’s a concern. Influencers absolutely love to tell people to choose one particular language because it has the most public commits on GitHub, or another because it has the largest number of programmers using it (which is in practice something that’s impossible to say for sure). </p>
<p>Let me flip that on its head: suppose that the most common programming language and platform combination is JavaScript and web. Let’s further suppose that we have pretty concrete data on the number of job postings on the web which confirms that the largest volume of jobs available is for that combination. Let’s finally suppose that for whatever reason, you strongly dislike JavaScript and enjoyed building a website using PHP. </p>
<p>You will find voices who will tell you that PHP is a dead language and a dead end for job searching. </p>
<p>But if you go looking, you may notice that there is a good supply of job postings out there looking for PHP developers who can expand and maintain existing codebases. You might also have a much better chance of getting an interview because <em>the ratio of job postings to applications is significantly better for PHP developers</em> than JavaScript developers. In fact, my team recently hired a PHP developer!</p>
<h3 id="heading-hardware-amp-working-with-what-you-have">Hardware &amp; Working With What You Have</h3>
<p>This section is largely irrelevant to web developers, but may be extremely important for those looking to target specific hardware or operating systems. Simply put, if you don’t have a computer with Mac OS and XCode, you will have a very hard time developing an iOS app, for example. In my case, back in 2014, I chose Android development partly because I had studied a bit of Java – though a big consideration was that I had an Android phone. </p>
<p>There are some ways around this by paying to use a remote device (such as a remote Mac via an online service), but my experience with such services years ago is that they weren’t great.</p>
<p>Think about what resources you have and how that fits into what you want to build or whom you want to work for. If you have not much other than a cheap computer with a web browser, and you still want to build GUI applications, web development can be a great choice.</p>
<h3 id="heading-what-if-i-want-the-ai-to-code-for-me">What if I Want the AI to Code For Me?</h3>
<p>While this topic is worthy of a separate article, I don’t believe this is an unreasonable question to ask. A year ago, I would have told you that at best, the AI can write some basic code and help you learn some things which may or may not be wrong. </p>
<p>How things have changed! Though I would be bad at my job if I copy pasted code I didn’t understand or didn’t test, AI has absolutely become a force multiplier for me as a developer. </p>
<p>Back to the topic in question, how does this relate to choosing a programming language? Well, after telling you that popularity is not always a big deal, by the nature of how LLMs work, popularity is a factor. In terms of general use, languages like Python, JavaScript, and Java are likely to have the largest amount of training data. My experience has been that the languages I typically use, such as Kotlin, TypeScript, and Swift also do fine.</p>
<p>But there is a curious side effect of developing Android or iOS applications that I don’t experience so much in web development. The nature of these constantly changing platforms and SDKs, with tens of thousands of third party libraries, dozens of architectures, and endless opinions about best practices and anti-patterns, means that LLMs can have serious troubles with complexity or specificity. </p>
<p>I expect this issue to be fixed as LLM services improve correctness checking or other methods to reduce hallucinations.</p>
<h3 id="heading-avoid-the-sunk-cost-fallacy">Avoid the Sunk-Cost Fallacy</h3>
<p>Perhaps the most important point I can make in choosing a programming language is to avoid the sunk-cost fallacy. For the first several years of my part-time studies, I didn’t imagine learning a second language based on how difficult it was for me to learn Java.</p>
<p>Roughly 12 years later, I have written non-trivial code in Java, Kotlin, Swift, C++, TypeScript, and SQL. Further, I have dabbled with code in C, Python, JavaScript, Racket, Haskell, Objective C, Visual Basic, and C#. </p>
<p>It was not the case that I sought out to learn all of these things artificially – I don’t tend to learn things outside of the problems in front of me. It’s that these learning opportunities naturally unfolded along with my personal and professional interests. </p>
<p>Learning the fundamentals or approaching mastery of any general purpose programming language will have carry over to others. It’s true that someone learning Python or JavaScript without CS fundamentals is not going to have much of a clue how things work at the OS level or lower. </p>
<p>It’s also true that I have met several people who could probably code circles around me in C/C++/Assembly but never made it past building toy programs in University or College. </p>
<p>Just keep learning and try to find a balance between personal interest and professional goals.</p>
<h2 id="heading-how-to-find-the-best-libraries-and-frameworks">How to Find the Best Libraries and Frameworks</h2>
<p>The next few topics revolve around a question which we’ll revisit a couple of times before the end of this article: “<em>Does it solve more problems than it creates?</em>”</p>
<h3 id="heading-what-are-libraries-and-frameworks">What Are Libraries and Frameworks?</h3>
<p>Before we proceed, here’s a useful but not definitive definition about the relationship between libraries and frameworks. You’ll find other definitions, but there’s remarkably little consensus on topics like this in this industry.</p>
<p>For me, a library is code which you can take from somewhere and use it to build things. It could be anything from a single line to a large and complex sub-system – usually something in between. I could give you a long and pedantic definition, but that’s not appropriate for this context (suitability!). </p>
<p>One example could be Java’s Math (java.lang.Math) library, which provides you with the following: “<em>The class Math contains methods for performing basic numeric operations such as the elementary exponential, logarithm, square root, and trigonometric functions.</em>”</p>
<p>Some people use the term framework interchangeably with library, and I don’t have any problems with that. When I think of a framework, I’m thinking about something which you build stuff around and is not necessarily to do with solving a specific problem domain (such as mathematics). </p>
<p>An example of this would be RxJava, which is a rather complex framework you can use to bind together and manage data flows across an entire application. I’ve used this framework in almost a dozen applications which did very different things in principle.</p>
<p>I do consider a framework to be a library, fundamentally – they just have a different set of goals and often a larger footprint.</p>
<h3 id="heading-how-to-choose-libraries-and-frameworks">How to Choose Libraries and Frameworks</h3>
<p>When I think about choosing libraries and frameworks, I ask myself these questions:</p>
<ul>
<li><p>Does it solve more problems than it creates compared to writing my own solution?</p>
</li>
<li><p>Is it well-maintained (regularly worked on, responsive authors, backed by tech companies)?</p>
</li>
<li><p>Does it have good documentation (less of a problem now that we can leverage AI for this purpose)?</p>
</li>
<li><p>What kind of footprint does it have?</p>
</li>
</ul>
<p>Let’s take two examples. I won’t refer to the specific platform or name of these libraries to avoid offending anyone. But they were/are both used in mobile development (though they are solving common GUI problems on any platform).</p>
<p>Firstly, one of my favorite libraries had one job: It loads images into the UI. </p>
<p>Although devices are more powerful than they used to be, it can still be a problem to load large images on smart phones for display. Mobile operating systems can be aggressive about killing programs (that is, processes) which use up too much of the system’s resources.</p>
<p>This library handles all aspects of loading images that I’m concerned about:</p>
<ul>
<li><p>Loading the image into a particular widget</p>
</li>
<li><p>Displaying an appropriate loading indicator </p>
</li>
<li><p>Displaying an optional error or fallback state that tells the user something went wrong</p>
</li>
<li><p>Handling the complexities of asynchronously loading in (via URL/URI), processing, and compressing potentially large streams of bits (that is, image data)</p>
</li>
<li><p>Doesn’t inflate the packaged application’s size unnecessarily</p>
</li>
<li><p>Doesn’t change its public API frequently (think changing function names which cause people’s implementations to break when updating versions)</p>
</li>
<li><p>It solves problems that I’m not interested in solving</p>
</li>
</ul>
<p>Secondly, one of my least favorite libraries also had one job: Pagination. Pagination, or paging, in this case refers to loading data in <em>chunks</em> into an application. This is an extremely common pattern in shopping cart or social media applications. </p>
<p>The library I am thinking of approaches that problem like so:</p>
<ul>
<li><p>Tightly couples every layer of your client application (from front end to back end) to its dependencies</p>
</li>
<li><p>This tight coupling makes testing difficult without jumping through some hoops</p>
</li>
<li><p>Handles the core problem of pagination well unless you need customization or specialized cases</p>
</li>
<li><p>Frequently changed its public facing API</p>
</li>
<li><p>Solved (in general) a problem which I am quite happy to write my own solution for</p>
</li>
<li><p>Did not play well with other frameworks due to a restrictive set of types and lack of flexibility</p>
</li>
<li><p>Was constantly updated for a couple of years then ditched and marked deprecated</p>
</li>
<li><p>Did not inflate the packaged applications size too much but certainly more than my own solution would</p>
</li>
</ul>
<p>As you can see, even something which solves a core problem reasonably well, can still fail this simple test of: Does it solve more problems than it creates? Having written pagination code by myself on a couple of occasions now, I would have to be pretty strongly convinced not to. </p>
<h2 id="heading-how-to-find-the-best-programming-principles-and-practices">How to Find the Best Programming Principles and Practices</h2>
<p>There are more best practices and principles than I care to describe in detail. What I will do is explain why I treat programming principles as being distinct from immutable/unbreakable laws. Similarly to my goal of finding the best programming language, I wanted to find the best principles in order to write the best code. </p>
<p>The problem is that any programming principle I’ve come across has also been subject to the Law of Suitability. I’ll discuss one example from personal experience and point out that the question we asked above, “does it solve more problems than creates,” also applies here.</p>
<h3 id="heading-dry-dont-repeat-yourself">D.R.Y – Don’t Repeat Yourself</h3>
<p>This principle can be summarized with the idea that if you find duplicated code, you should pull it into a separate module (file, function, class, library, and so on). Without getting into the weeds, the act of pulling the duplicated code into a separate module can be thought of as a process of abstraction. </p>
<p>To be fair to the creators and proponents of this idea, it’s more nuanced than that. But many developers never bother to dig that deep into nuances – nor should they have to. I ran into the nuances simply by applying this idea more than I should have.</p>
<p>There a couple of cases where code duplication is sometimes preferable:</p>
<ul>
<li><p>You have a set of similar modules (say similar widgets or business rules) but they get used in different places for different reasons</p>
</li>
<li><p>You have a set of similar modules which might change for different reasons (for example, rapidly changing demands from product teams and clients with different priorities) </p>
</li>
<li><p>You’re deliberately grouping certain modules that work together in distinct packages, files, or directories to insulate modules/groupings from affecting each other</p>
</li>
<li><p>You find that you need to add details about one particular implementation into your abstraction, but those details don’t apply to other implementations (that is, it’s a bad abstraction)</p>
</li>
</ul>
<p>All of the things I listed above are summaries of things I have run into in the past. The key take away is that I broadly agree with avoiding code duplication. I also know of some cases where I prefer it. Suitability!</p>
<h3 id="heading-what-about-other-programming-principles">What About Other Programming Principles?</h3>
<p>In general, you can think of all programming principles like YAGNI, DRY, SRP (and other aspects of SOLID), and even software development methodologies like AGILE and Waterfall in the same way. Contextually, you can use them as guidelines to help avoid some common problems. But a person of sufficient creativity and experience can come up with a situation where following any of these principles creates more problems than it solves.</p>
<p>In many cases, you need to apply these things too much in order to understand what too much means in practical terms. Just be careful not to swing too far in the other direction when one of these principles really breaks down in front of you. I’ve also made that mistake and had to re-adjust.</p>
<p>To date, I haven’t come across a programming principle which is universally true. There are some which come close to that, but I can always imagine a situation where they’re not the best approach. Take a good one like: Always write the simplest code you can write. In other words, don’t add extra complexity without a reason. </p>
<p>Well, suppose you have a not great value system or incentive structure which encourages inflating your work artificially. Need I say more?</p>
<h2 id="heading-a-note-about-patterns-and-architectures">A Note About Patterns and Architectures</h2>
<p>I’ll now discuss the topic of patterns and architectures in software systems with respect to the Law of Suitability. Software architecture is the only thing I consider myself an expert in, and I have read multiple books on design patterns. I always try to provide some useful info on these topics when I get the chance.</p>
<h3 id="heading-how-to-find-the-best-software-architecture">How to Find the Best Software Architecture</h3>
<p>To summarize entire articles, courses, and public talks I have given on this topic: The best software architecture depends on project and personal requirements. </p>
<p>One way to grasp the main idea is to ask yourself whether the best architecture for a hospital is also a good fit for a 2-bedroom apartment. The obvious answer is that we might expect a few commonalities (doors, windows, bathrooms of some kind, and so on) among these different sets of requirements. But the ideal, or even just a good architecture for a 2 bedroom apartment cannot possibly be the same for a hospital. </p>
<p>In short, you will never find an architecture which works well for all projects and requirements.</p>
<p>Here is a list of architectures I have some familiarity with:</p>
<ul>
<li><p>Model-View-Controller</p>
</li>
<li><p>Model-View-Presenter</p>
</li>
<li><p>Model-View-ViewModel</p>
</li>
<li><p>VIPER</p>
</li>
<li><p>Clean Architecture (Robert C. Martin style)</p>
</li>
<li><p>Model-View-Intent</p>
</li>
</ul>
<p>To make matters more confusing, there are multiple different ways to implement these architectures – almost as many ways as developers implementing them! M-V-VM is one of the more common architectures in mobile development, and I can think of at least five different variations on how to achieve what some people think of as a single architecture.</p>
<p>Here are my general suggestions for working with these architectures:</p>
<ul>
<li><p>Be wary of adding unnecessary complexity with the more complex architectures (particularly Clean Architecture, as many people get this horribly wrong)</p>
</li>
<li><p>Don’t try to make the project requirements fit the architecture – work the other way around (the best indicator for this is noticing that something you’re trying to implement is made unnecessarily difficult because of the architecture you’re using)</p>
</li>
<li><p>Don’t be afraid of applying different approaches in different features of the same application instead of blindly applying the same pattern just for consistency’s sake</p>
</li>
</ul>
<h3 id="heading-the-design-pattern-trap">The Design Pattern Trap</h3>
<p>One of the most common engagement farming tactics I see on social media is to post lists of design patterns “that you must know” in order to get a job or to scare junior programmers into buying your low-quality, copy-pasted content of each pattern.</p>
<p>Don’t get me wrong, I loved studying design patterns and I use a couple key patterns in most GUI applications I build. The Observer (a.k.a. Publisher-Subscriber or Pub-Sub) Pattern really shines when you need to glue together a bunch of asynchronous data sources. I love seeing library developers give me a nice Builder Pattern to work with their APIs. I think understanding the basics of patterns like the Bridge or Facade can teach you how to hide details behind abstractions, which is actually simpler than the big scary words describing these things make it sound.</p>
<p>But I spend very little time in my day to day work thinking about or in design patterns. Instead, I’m always thinking about the kinds of attitudes and principles that give rise to these patterns: </p>
<ul>
<li><p>Promoting loosely coupled code (separating the creation and usage of dependencies and parameters, reasonable usage of abstraction)</p>
</li>
<li><p>Writing classes, interfaces, protocols, and functions which do one thing (though this “one thing” might be a macroscopic goal instead of a microscopic operation)</p>
</li>
<li><p>Avoiding complexity wherever possible (a common source of this complexity is over-use of abstractions)</p>
</li>
<li><p>Not pretending that every complex problem has a simple solution (that is, as simple as it can be but no simpler)</p>
</li>
<li><p>Avoiding pre-mature optimization</p>
</li>
</ul>
<p>Again, I will only apply these principles and attitudes to the extent that I find they solve more problems than they create. Design patterns, when applied too rigorously, can break many of those principles – particularly when it comes to avoiding complexity and pre-mature optimization. </p>
<p>Don’t try to make your project requirements fit your patterns. Instead, think about which patterns might suit your project requirements and deviate as necessary.</p>
<h2 id="heading-summary">Summary</h2>
<p>My goal with this piece was to provide three things:</p>
<ul>
<li><p>A practical overview of choosing a programming language and avoiding the traps the people can fall into when navigating these sorts of topics</p>
</li>
<li><p>A philosophical but pragmatic framework which you can use to evaluate the suitability of anything – with emphasis on learning and developing software</p>
</li>
<li><p>A breakdown of how I approach other topics like tools, architectures, and patterns</p>
</li>
</ul>
<p>While it can be important to consider things like job opportunities and your current hardware, don’t discount personal interest as a driving factor. From what little I remember about studying cognition (learning how to learn), interest is tightly coupled to motivation and memory. We can’t always exclusively do what interests us, but I suggest you look for intersections between personal and practical concerns as often as you can. </p>
<p>In closing, I encourage you to think about other areas where you might be able to explore the principles of suitability and the problems of tribalistic thinking. Change is constant and value is relative.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Abstraction in Programming? Explained for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ This article will not be a dry and boring explanation of abstract classes, interfaces, protocols, or similar software entities. I will explain what they are in simple terms, but my main goal is to change how you think about abstractions in general. A... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-abstraction-in-programming-for-beginners/</link>
                <guid isPermaLink="false">66d460d3c7632f8bfbf1e49d</guid>
                
                    <category>
                        <![CDATA[ abstraction ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ryan Michael Kay ]]>
                </dc:creator>
                <pubDate>Wed, 21 Dec 2022 18:08:21 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/12/smartphone-g7993a9917_1280-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>This article will not be a dry and boring explanation of abstract classes, interfaces, protocols, or similar software entities.</p>
<p>I will explain what they are in simple terms, but my main goal is to change how you think about abstractions in general. All of this is in service of helping you develop the art of programming.</p>
<p>These are the topics I will cover:</p>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-an-abstraction">What is an abstraction?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-abstractions-in-your-programs">How to use abstractions in your programs</a><br>  – <a class="post-section-overview" href="#heading-how-to-use-interfaces-and-protocols">How to use interfaces and protocols</a><br>  – <a class="post-section-overview" href="#heading-how-to-use-function-types-and-lambda-expressions">How to use function types and lambda expressions</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-is-abstraction-the-most-important-idea-in-programming">Is abstraction the most important idea in programming?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-much-abstraction-do-i-need">How much abstraction do I need?</a></p>
</li>
</ul>
<p>The code samples will be in Kotlin, but I have written the article assuming you only have basic programming knowledge in any industry standard language.</p>
<p>I also use a variety of approaches to cover both object-oriented and functional styles of code.</p>
<h2 id="heading-what-is-an-abstraction">What Is An Abstraction?</h2>
<p>To begin with, we will discuss what this term means in the most general sense. Here is a simplified definition I have come up with for an abstraction:</p>
<blockquote>
<p>“A <strong>less detailed representation</strong> of an object or concept in nature.”</p>
</blockquote>
<p>I know my definition sounds very vague, but we will discuss some clear examples shortly. First, we must understand what <strong>detail</strong> is.</p>
<h3 id="heading-what-is-detail">What Is Detail?</h3>
<p>Detail refers to the quantity, or density perhaps, of information. Here are two examples of data models which are more and less detailed:</p>
<pre><code class="lang-pgsql"><span class="hljs-keyword">User</span> {
  <span class="hljs-type">name</span>,
  id
}
</code></pre>
<pre><code class="lang-pgsql"><span class="hljs-keyword">User</span> {
  <span class="hljs-type">name</span>: String,
  id: <span class="hljs-type">Integer</span>,
  phone: <span class="hljs-type">Integer</span>,
  email: String
}
</code></pre>
<p>There is no need to overthink this point! More details is another way of saying more information or more complexity.</p>
<p>The only other key point is to understand what a <strong>representation</strong> is.</p>
<h3 id="heading-how-to-represent-something">How to Represent Something</h3>
<p>Suppose you are going to travel somewhere which has a particularly deadly kind of venomous snake. In order to gain information about this snake, you have a few different options:</p>
<ul>
<li><p>Read a verbal description of the snake and its behaviour</p>
</li>
<li><p>Look at a drawing or picture of the snake</p>
</li>
<li><p>Listen to audio of what it sounds like when behaving aggressively</p>
</li>
</ul>
<p>All of the above points are examples of different kinds of representations, or abstractions, of the venomous snake.</p>
<p>In each case, some pieces of information, which accurately represent properties of the real snake, are conveyed. However, neither a verbal description, nor an image, nor a recording can bite you!</p>
<p>Here we see the main utility of abstractions: <strong>Conveying important information</strong> (also known as details or properties) of an object or concept, <strong>while leaving out the unnecessary information</strong>.</p>
<h2 id="heading-how-to-use-abstractions-in-your-programs">How to Use Abstractions In Your Programs</h2>
<p>Before we discuss some specifics, it is worth mentioning that everything in a computer program is technically an abstraction.</p>
<p>In fact, <strong>programming languages, as well as all forms of mathematics, are systems of abstractions</strong>.</p>
<p>However, programmers tend to think of abstractions as a narrow band of software entities usually referred to as:</p>
<ul>
<li><p>Interfaces or Protocols</p>
</li>
<li><p>Abstract Classes</p>
</li>
<li><p>Function Types/References/Signatures</p>
</li>
<li><p>Super/Parent-Classes</p>
</li>
</ul>
<p>Unfortunately, the names and mechanics of the above software entities can vary substantially in different programming languages.</p>
<p>For this reason, I will take two examples which may be more or less appropriate to your preferred languages:</p>
<ol>
<li><p>An interface or protocol (which will also cover abstract classes)</p>
</li>
<li><p>A function type or method reference</p>
</li>
</ol>
<p>In any case, don't worry so much about the names or any minor differences in how these things work across languages. Instead, I invite you to focus on the general ideas.</p>
<h2 id="heading-how-to-use-interfaces-and-protocols">How to Use Interfaces and Protocols</h2>
<p>I will use the term interface from here on, but this term is synonymous with protocol. I will also use the term function synonymously with method.</p>
<p>Interfaces allow you to define behaviour of functions, classes, or objects, without defining their implementation.</p>
<p>Don't worry, I am not like some teachers who throw out some jargon and pretend like I am teaching you something.</p>
<p>Let's look at exactly what I mean by behaviour and implementation.</p>
<p><strong>Behaviour</strong> literally means a function declaration:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">UserDataSource</span> </span>{
<span class="hljs-comment">//this line below has a function declaration but no function "body"</span>
  <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getUserById</span><span class="hljs-params">(id: <span class="hljs-type">String</span>)</span></span>: User?
}

<span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span></span>(
  <span class="hljs-keyword">val</span> id: String,
  <span class="hljs-keyword">val</span> someData: Any
)
</code></pre>
<p>You can see the footnotes below regarding my usage of the term “function declaration.”</p>
<p>To translate this into English, this function declaration says the we are defining a function which:</p>
<ul>
<li><p>Is named “getUserById”</p>
</li>
<li><p>Accepts a String type called “id” as an argument when called</p>
</li>
<li><p>Returns a “User” or a null value if no user exists (this is because we have a “?” after the “User” type)</p>
</li>
</ul>
<p><strong>Implementation</strong> refers to the function body:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">//Note that ":" is short for extends/implements in Kotlin for the class</span>
<span class="hljs-comment">//declaration</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserDatabase</span></span>(): UserDataSource {
<span class="hljs-comment">//the curly braces, and everything between them, is the implementation</span>
  <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getUserById</span><span class="hljs-params">(id: <span class="hljs-type">String</span>)</span></span>: User? {
    <span class="hljs-keyword">var</span> user: User? = <span class="hljs-literal">null</span>
    <span class="hljs-comment">//… not important for this example</span>
    <span class="hljs-keyword">return</span> user
  }
}
</code></pre>
<p>Another name for the function inside of the interface is an <em>abstract function</em>. Hopefully, our discussion on abstract meaning “<em>less detail</em>” is starting to make more sense here!</p>
<p><strong>Some notes for accuracy:</strong></p>
<ol>
<li><p>Some languages have features to define properties, variables, and even implementations (that is, function declarations + function bodies) within interfaces. This does not change the primary purpose of interfaces, though.</p>
</li>
<li><p>The term function declaration will be defined differently depending on the language. Instead of worrying about verbal definitions, please consider my code examples to follow what I mean.</p>
</li>
</ol>
<h3 id="heading-what-about-abstract-classes">What About Abstract Classes?</h3>
<p>Apart from in Python (and perhaps other languages I am not aware of), abstract classes are very similar to interfaces except for one key difference: a <strong>class may only inherit from a single abstract class.</strong></p>
<p>In my opinion, before languages started to include ways for interfaces to define their own implementations, the use of abstract classes versus interfaces was clear:</p>
<ul>
<li><p>If you only want to share behaviour across a set of software entities, use an interface</p>
</li>
<li><p>If you want to share implementation <strong>and</strong> behaviour, use an abstract class instead</p>
</li>
</ul>
<p>Unfortunately, this distinction is very blurry since many languages now have features to add implementation to interfaces (like Java’s Default Methods).</p>
<p>The only general recommendation I can make which does not account for the specific details of any particular programming language is this: Use the simplest construct to get the job done.</p>
<h2 id="heading-how-to-use-function-types-and-lambda-expressions">How to Use Function Types and Lambda Expressions</h2>
<p>There are different ways to achieve abstraction without defining interfaces or classes. But the amount of structure these language features require is still subject to language specifics.</p>
<p>Kotlin provides enough of these features that you will hopefully be able to make some connections with your preferred languages.</p>
<h3 id="heading-how-to-use-function-types-instead-of-an-interface">How to Use Function Types Instead Of An Interface</h3>
<p>We will start with a practical example and then explain the finer details part by part.</p>
<p>Suppose we want to set up an abstract function (recall that this means a function with no implementation) to handle a click event.</p>
<p>Using something like an interface, we could do the following:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">//assume this is an platform/OS component that tells you when</span>
<span class="hljs-comment">//a user clicks something on screen</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PlatformComponent</span></span>(
  <span class="hljs-keyword">var</span> clickListener: ClickListener? = <span class="hljs-literal">null</span>
) {
  <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">userClickedScreen</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">//Note: the "?" means handleClick() is only</span>
    <span class="hljs-comment">//called when clickListener is NOT NULL</span>
    clickListener?.handleClick()
  }
}
<span class="hljs-comment">//This interfaces hides (abstracts) the concrete class/type</span>
<span class="hljs-comment">//which handles the click</span>
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">ClickListener</span> </span>{
  <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">handleClick</span><span class="hljs-params">()</span></span>
}
<span class="hljs-comment">//This concrete class/type handles the click</span>
<span class="hljs-comment">//by extending the interface</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ScreenController</span></span>() : ClickListener {
  <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">handleClick</span><span class="hljs-params">()</span></span> {
    println(<span class="hljs-string">"Click handled."</span>)
  }
}

<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
  PlatformComponent(
    ScreenController()
  ).userClickedScreen()
}
</code></pre>
<p>An alternative approach is to use a function type instead of an interface:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
  <span class="hljs-keyword">val</span> controller = ScreenController()
  <span class="hljs-keyword">val</span> component = PlatformComponent(
    <span class="hljs-comment">//The double colon tells the compiler that we are referring to</span>
    <span class="hljs-comment">//the function handleClick defined in ScreenController</span>
    controller::handleClick
  )
  component.userClickedScreen()
}

<span class="hljs-comment">//assume this is an platform/OS component that tells</span>
<span class="hljs-comment">//you when a user clicks something on screen</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PlatformComponent</span></span>(
  <span class="hljs-keyword">var</span> clickListener: () -&gt; <span class="hljs-built_in">Unit</span>
) {
  <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">userClickedScreen</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">//This is equivalent to calling ScreenController.handleClick(),</span>
    <span class="hljs-comment">//but PlatformComponent does not know that. Abstraction!</span>
    clickListener()
  }
}
<span class="hljs-comment">//This concrete class/type handles the click</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ScreenController</span></span>() {
  <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">handleClick</span><span class="hljs-params">()</span></span> {
    println(<span class="hljs-string">"Click handled."</span>)
  }
}
</code></pre>
<p>In this example, we can see how there is even less structure required to achieve the same result. But keep in mind that having less structure does not immediately imply better code. Really, <strong>it depends</strong>.</p>
<p>In any case, with a practical example in mind, we can break down how this code actually works in more detail.</p>
<h3 id="heading-how-to-use-function-references">How to Use Function References</h3>
<p>If you are unfamiliar with how function types, method references (or whatever else they are called) work, this section explains them in Kotlin. Feel free to jump to the next section if you are already familiar.</p>
<p>Similar to most modern programming languages, we can create a reference variable to a particular function in Kotlin:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">var</span> clickListener: () -&gt; <span class="hljs-built_in">Unit</span>
</code></pre>
<p>In Kotlin, function types have the following syntax:</p>
<pre><code class="lang-kotlin">(optional list of parameter types) -&gt; <span class="hljs-keyword">return</span> type
</code></pre>
<p>For example:</p>
<ul>
<li><p><code>(Int, Int) -&gt; Int</code> means that the associated function must take in two Int parameters, and return a single Int</p>
</li>
<li><p><code>() -&gt; Unit</code> means that a function has no parameters and executes without returning a meaningful value</p>
</li>
</ul>
<p>Unit is roughly equivalent to Java’s void return type or Python’s None type – at least in principle.</p>
<p>When it comes time to call (invoke) a function reference, we have two options:</p>
<ul>
<li><p><code>clickListener()</code> for short</p>
</li>
<li><p><code>clickListener.invoke()</code> is the full syntax, which is necessary when making null-safe calls like <code>clickListener?.invoke()</code>, for example</p>
</li>
</ul>
<h3 id="heading-how-to-use-lambda-expressions">How to Use Lambda Expressions</h3>
<p>In the previous example, it is worth noting that ScreenController does not care what the actual function it is invoking happens to be named.</p>
<p>We can take this level of abstraction even further, by not even defining a ScreenController:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
  <span class="hljs-comment">//note that the outer parenthesis are optional in Kotlin,</span>
  <span class="hljs-comment">//but may make this easier to understand</span>
  <span class="hljs-keyword">val</span> component = PlatformComponent(
    { println(<span class="hljs-string">"Click handled."</span>) }
  )
  component.userClickedScreen()
}
<span class="hljs-comment">//assume this is an platform/OS component that tells</span>
<span class="hljs-comment">//you when a user clicks something on screen</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PlatformComponent</span></span>(
  <span class="hljs-keyword">var</span> clickListener: () -&gt; <span class="hljs-built_in">Unit</span>
) {
  <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">userClickedScreen</span><span class="hljs-params">()</span></span> {
    clickListener()
  }
}
</code></pre>
<p>Unlike the previous examples, this one is <strong>not intended to resemble a practical scenario</strong> – just to demonstrate a lambda expression.</p>
<p>The actual lambda expression is this:</p>
<p><code>{ println(“Click handled.”) }</code></p>
<p>As you can see, it does not get much more abstract than a lambda expression.</p>
<p>On the surface, it's almost like defining only the implementation but not the behaviour. But at least in Kotlin, the lambda expression must conform to the type we are assigning it to.</p>
<p>In this case, <code>{ println(“Click handled.”) }</code> has no parameters and does not return a meaningful value. So it conforms to <code>() -&gt; Unit</code>.</p>
<h3 id="heading-which-approach-should-i-use">Which Approach Should I Use?</h3>
<p>You may wonder which approach you should be using – assuming your language allows for multiple approaches.</p>
<p>The most accurate answer I can give you is that there is no general rule.</p>
<p>Plenty of teachers these days will say “<em>x</em> is worse than y” or simply “<em>x</em> is bad,” because it works great for clickbait and search engine optimization.</p>
<p>But a language, platform, code construct, architecture, and just about anything else can only be judged good, bad, better, or worse relative to your requirements.</p>
<p>In fact, different requirements are the reason we have languages as different as Python and Java which are both extremely popular.</p>
<p>So instead, try different approaches and be skeptical of anyone who makes absolute statements without discussing requirements.</p>
<h2 id="heading-is-abstraction-the-most-important-idea-in-programming">Is Abstraction the Most Important Idea in Programming?</h2>
<p>The point of this article was never to say: <em>“Using interfaces and abstract classes everywhere will make you a better programmer.”</em></p>
<p>In fairness, as many developers do, I went through a phase around 2016–2018 where I did actually think that statement was pretty accurate.</p>
<p>Instead, the point of this article is to explain two things:</p>
<ul>
<li><p>Abstraction in programming, in my opinion, <strong>should</strong> <strong>not specifically mean abstract classes, or any particular code construct</strong></p>
</li>
<li><p>Abstraction in programming is a <strong>process</strong> by which we design our software entities according to <strong>how much detail</strong> they internally (privately) contain and externally (publicly) provide</p>
</li>
</ul>
<p>In a sense, every decision we make about the structure of our code, regardless of the language, comes down to this process of abstraction.</p>
<p>With that being said, how do we know when making some aspect of our program more abstract is beneficial, useless, or detrimental?</p>
<h2 id="heading-how-much-abstraction-do-i-need">How Much Abstraction Do I Need?</h2>
<p>I can only think of one kind of situation where you should strongly consider using something like an interface or function type.</p>
<p>Recall that these software entities provide variability of implementation but consistent behaviour. Further, that implementation typically refers to the body of a function.</p>
<p>Two things follow from that observation:</p>
<ul>
<li><p>If no variability of implementation is required, there is not likely to be a benefit of using a more abstract software entity.</p>
</li>
<li><p>If variability of implementation is required, using a more abstract software entity is likely beneficial.</p>
</li>
</ul>
<p>We will now discuss two situations I have encountered where variability is a requirement.</p>
<h3 id="heading-how-to-make-your-code-easier-to-test">How to Make Your Code Easier to Test</h3>
<p>Suppose that we have some kind of software entity, which must request some user data from a database or network adapter:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PresentationLogic</span></span>(
 <span class="hljs-keyword">val</span> datasource: Datasource
) {
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">start</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">val</span> someData = datasource.getData()
        presentData(someData)
    }

    <span class="hljs-comment">//...</span>
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Datasource</span></span>() {
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getData</span><span class="hljs-params">()</span></span>: Data {
        <span class="hljs-keyword">var</span> someData = getLocalOrRemoteData()
        <span class="hljs-comment">//... error handling and so on</span>

        <span class="hljs-keyword">return</span> someData
    }
}
</code></pre>
<p>Also suppose that we want to test <code>PresentationLogic</code> without needing a real datasource to supply the data.</p>
<p>There are a few different ways to solve this problem (see the note below), but a simple solution is to make the datasource more abstract:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PresentationLogic</span></span>(
 <span class="hljs-keyword">val</span> datasource: DatasourceInterface
) {
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">start</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">val</span> someData = datasource.getData()
        presentData(someData)
    }

    <span class="hljs-comment">//...</span>
}

<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">DatasourceInterface</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getData</span><span class="hljs-params">()</span></span>: Data
}
</code></pre>
<p>From there, we can create a fake implementation of the datasource in a test environment:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FakeDatasource</span></span>(): DatasourceInterface {
        <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getData</span><span class="hljs-params">()</span></span>: Data {
            <span class="hljs-keyword">return</span> Data()
        }
}

<span class="hljs-meta">@Test</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">testLogic</span><span class="hljs-params">()</span></span> {
    <span class="hljs-keyword">val</span> logic = PresentationLogic(
       <span class="hljs-comment">//here we provide the fake version</span>
       FakeDatasource()
    )
}
</code></pre>
<p>Using abstraction, PresentationLogic does not know or care whether it is talking to a fake or real datasource. By extension, it does not need to change to work with either of them. Variability of implementation!</p>
<p>Note that there are other way to achieve this variability apart from using an interface. You could use a mocking library, or configure a build tool to swap out implementations.</p>
<p>There is no clear answer to which approach is better outside of discussing specific requirements.</p>
<p>Also, note that this approach would not actually work unless the details of how the datasource is created are kept separate from <code>PresentationLogic</code>.</p>
<p>This is commonly referred to as Dependency Injection, which I will discuss in a separate article.</p>
<h3 id="heading-how-to-work-with-different-versions-and-vendors-of-a-service">How to Work With Different Versions and Vendors of a Service</h3>
<p>Suppose that for some reason, you must work with different versions or vendors of the same service depending on different requirements.</p>
<p>An example could be supporting both AWS and Firebase to store the same data. Another example could be supporting a legacy version of a service along with a newer version of that same service.</p>
<p>In any case, it is another situation where variability of implementation is expected.</p>
<p>The code examples we will discuss have the following requirements:</p>
<ul>
<li><p>A client program must use three services, all from different vendors, to perform the same behaviour</p>
</li>
<li><p>The decision to choose a particular service is determined at runtime based on the environment (platform, OS, hardware, and so on) of the client program</p>
</li>
</ul>
<p>For those wondering, “client” in this context is a generic word for some program or software entity which uses other programs or software entities.</p>
<p>For example, YouTube’s website and mobile apps are “client apps” of YouTube’s backend servers.</p>
<p>Without applying any abstraction, our client program will need to know about every possible service and be told which service to choose:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">clientProgram</span><span class="hljs-params">(
    request: <span class="hljs-type">Request</span>, 
    awsService: <span class="hljs-type">AwsService</span>,
    firebaseService: <span class="hljs-type">FirebaseService</span>,
    parseService: <span class="hljs-type">ParseService</span>
)</span></span>: Result {
    <span class="hljs-keyword">val</span> use: USE_SERVICE = determineBestService()

    <span class="hljs-keyword">val</span> result = <span class="hljs-keyword">when</span> (use) {
        USE_SERVICE.AWS -&gt; awsService.executeRequest(request)
        USE_SERVICE.FIREBASE -&gt; firebaseService.executeRequest(request)
        USE_SERVICE.PARSE -&gt; parseService.executeRequest(request)
    }

    <span class="hljs-comment">//assume additional work is done before returning the result</span>
    <span class="hljs-keyword">return</span> result
}

<span class="hljs-keyword">enum</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">USE_SERVICE</span> </span>{
    AWS,
    FIREBASE,
    PARSE
}
</code></pre>
<p>Notice that clientProgram has a parameter which refers to specific vendors of the service:</p>
<ul>
<li><p>Amazon Web Services (AWS)</p>
</li>
<li><p>Firebase</p>
</li>
<li><p>The now defunct Parse service from Facebook</p>
</li>
</ul>
<p>It follows that any changes to our services will require <code>clientProgram</code> to be refactored (rewritten) appropriately.</p>
<p>The reason I chose Parse as one of the example services is specifically because it was shut down, despite being widely used. There are various reasons why a particular service may no longer fit requirements, but not working any more is a good one.</p>
<p>An alternative approach would be to hide all the details about the service being used from clientProgram. You could use an interface, but for variety’s sake I have used a function type instead:</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">//Creating the services</span>
    <span class="hljs-keyword">val</span> awsService = AwsService()
    <span class="hljs-keyword">val</span> firebaseService = FirebaseService()

    <span class="hljs-comment">//determining which service to use must </span>
    <span class="hljs-comment">//not be included in clientProgram</span>
    <span class="hljs-keyword">val</span> use: USE_SERVICE = determineBestService()

    <span class="hljs-comment">//Assign serviceToUse to the appropriate function</span>
    <span class="hljs-keyword">val</span> serviceToUse: (Request) -&gt; Result = <span class="hljs-keyword">when</span> (use) {
        USE_SERVICE.AWS -&gt; awsService::executeRequest
        USE_SERVICE.FIREBASE -&gt; firebaseService::executeRequest
    }

    <span class="hljs-keyword">val</span> request = getRequest()

    clientProgram(
       request,
       serviceToUse
    )
}


<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">clientProgram</span><span class="hljs-params">(
    request: <span class="hljs-type">Request</span>, 
    service: (<span class="hljs-type">Request</span>) -&gt; <span class="hljs-type">Result</span>
)</span></span>: Result {

    <span class="hljs-keyword">val</span> result = service.invoke(request)

    <span class="hljs-comment">//assume additional work is done before returning the result</span>

    <span class="hljs-keyword">return</span> result
}

<span class="hljs-keyword">enum</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">USE_SERVICE</span> </span>{
    AWS,
    FIREBASE
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AwsService</span></span>() {
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">executeRequest</span><span class="hljs-params">(request: <span class="hljs-type">Request</span>)</span></span>: Result = Result()
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FirebaseService</span></span>() {
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">executeRequest</span><span class="hljs-params">(request: <span class="hljs-type">Request</span>)</span></span>: Result = Result()
}
</code></pre>
<p>The end result of this abstraction is that we can change services without needing to change <code>clientProgram</code> – assuming our behaviour does not change.</p>
<p>I want to point out that I am not advocating that you hide every service behind some kind of abstraction. If no variability is required or expected, there may not be any benefit to extra abstraction.</p>
<h1 id="heading-closing-thoughts">Closing Thoughts</h1>
<p>I hope it is clear when reading this article that my intention is not to push dogmatic opinions about how abstract your code should be.</p>
<p>As a junior and intermediate developer, it took me a few years to realize that it really does depend on project requirements.</p>
<p>I also hope that this article gave you some new ideas and perspectives about what abstraction is and how it can be applied in your code. Good luck and happy coding!</p>
<h3 id="heading-before-you-go"><strong>Before you go...</strong></h3>
<p>If you liked this article and want more information on these principles and code constructs, check out my free, full length <a target="_blank" href="https://youtu.be/FL2SMZxNQlc">programming fundamentals course</a>. It includes professionally written English, Burmese, and Arabic subtitles.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Clear Code – How to Write Code That Is Easy to Read ]]>
                </title>
                <description>
                    <![CDATA[ This article is a follow up to a tweet I made on how I deal with my poor ability to remember code. It may seem funny to you, but I do actually tend to forget what I write shortly after writing it. https://twitter.com/wiseAss301/status/159118167805122... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/clear-code-how-to-write-code-that-is-easy-to-read/</link>
                <guid isPermaLink="false">66d460c7b3016bf139028d87</guid>
                
                <dc:creator>
                    <![CDATA[ Ryan Michael Kay ]]>
                </dc:creator>
                <pubDate>Mon, 28 Nov 2022 12:26:28 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/11/cafe-gc5d844b68_1280.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>This article is a follow up to a tweet I made on how I deal with my poor ability to remember code. It may seem funny to you, but I do actually tend to forget what I write shortly after writing it.</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/wiseAss301/status/1591181678051229696?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1591181678051229696%7Ctwgr%5E0c73a629a6c4b95546c3202d41070cd1ff69b172%7Ctwcon%5Es1_&amp;ref_url=https%3A%2F%2Fcdn.embedly.com%2Fwidgets%2Fmedia.html%3Ftype%3Dtext2Fhtmlkey%3Da19fcc184b9711e1b4764040d3dc5c07schema%3Dtwitterurl%3Dhttps3A%2F%2Ftwitter.com%2Fwiseass301%2Fstatus%2F1591181678051229696image%3Dhttps3A%2F%2Fi.embed.ly%2F1%2Fimage3Furl3Dhttps253A252F252Fabs.twimg.com252Ferrors252Flogo46x38.png26key3Da19fcc184b9711e1b4764040d3dc5c07"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p> </p>
<p>First, we will discuss why you may want to write more legible code as opposed to short, concise code. Afterwards, we will look at the following strategies on how to do that with:</p>
<ul>
<li><p>Variable, value, reference, class, object, and function naming</p>
</li>
<li><p>Helper functions</p>
</li>
<li><p>Code comments</p>
</li>
<li><p>Enums/dictionaries/sealed classes/etc.</p>
</li>
<li><p>Package organization and naming</p>
</li>
</ul>
<p>Basic code literacy is recommended to get the most out of this article. However, I have tried to make it accessible to beginners where possible.</p>
<p><img src="https://images.unsplash.com/photo-1535930891776-0c2dfb7fda1a?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDE1Mnx8cmVhZGluZ3xlbnwwfHx8fDE2Njg4MTYyMjQ&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Image" width="2000" height="1500" loading="lazy"></p>
<p><em>Photo by [Unsplash](https://unsplash.com/@jamie452?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Jamie Street / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit)</em></p>
<h2 id="heading-does-efficiency-come-from-fewer-keystrokes">Does Efficiency Come From Fewer Keystrokes?</h2>
<p>I recall as a junior developer, thinking that short or abbreviated names for identifiers – basically any code construct us developers are allowed to name – were more efficient.</p>
<p>My logic was simple: If it takes me less time to write it, then I can get the job done faster.</p>
<p>This logic would make sense if the following things were true:</p>
<ul>
<li><p>I, or someone else, would never have to read or fix what I wrote in the past</p>
</li>
<li><p>I did not often forget what a variable, or several variables were, as I was reading through a function</p>
</li>
<li><p>I did not occasionally have to write some code which was truly complex and obscure</p>
</li>
<li><p>I could rename ridiculous or obscure external library functions, classes, or properties to something more sensible</p>
</li>
</ul>
<p>The point is that, for me, <strong>I find few situations where being concise actually saves time</strong>. Further, modern IDEs have this useful feature called code completion which saves most of the keystrokes anyways.</p>
<p>You may not feel the same way, and that is perfectly okay! Take whatever works for you in this article and throw away the rest.</p>
<h2 id="heading-how-to-name-classes-variables-and-functions">How To Name Classes, Variables, and Functions</h2>
<p>I will now share what I do to make my code easier for myself and others to read. The code examples I use will be in Kotlin, but the points I make should be applicable to most platforms and languages.</p>
<p>There are two important things to know when learning about how to name software entities. Before getting to that, this term software entities refers to any of the following:</p>
<ul>
<li><p>Classes, structs, objects</p>
</li>
<li><p>Variables, values, references, pointers</p>
</li>
<li><p>Functions, methods, algorithms, commands</p>
</li>
<li><p>Interfaces, protocols, abstractions</p>
</li>
</ul>
<p>Essentially, anything which a programmer has to name when writing a program.</p>
<h3 id="heading-how-descriptive-names-should-be">How Descriptive Names Should Be</h3>
<p>My goal for naming software entities is this: The name should <strong>reduce any confusion about what a software entity does, or is.</strong></p>
<p>The details of how it does something are not usually necessary.</p>
<p>The context, or everything around, of a software entity is important when deciding on a name. Something may require more or less details depending on its context.</p>
<p>Let us consider three examples:</p>
<ol>
<li><p><code>getFormattedDate(date: String) : String</code></p>
</li>
<li><p><code>getYYYYMMDDFormattedDate(date: String) : String</code></p>
</li>
<li><p><code>getYYYYMMDDFormattedDateFromIso8601Format(date: String) : String</code></p>
</li>
</ol>
<p>The production application I am currently working on frequently requires transforming dates to and from different formats.</p>
<p>In that context, I absolutely use names like example 3, which is much clearer than example 1.</p>
<p>Another option might be to change the parameter name in example 2 to something like <code>iso8601Date</code>.</p>
<p>While I do suggest you be consistent in your approach in a given codebase, feel free to experiment with what works for you. The point is to add as much information as is necessary to clear up any ambiguity.</p>
<p>If I was writing a one-off program that only ever converts one format to another, then example 1 is fine. <strong>Adding more information than necessary is not what I am advocating here.</strong></p>
<h3 id="heading-the-more-something-does-the-harder-it-is-to-name">The More Something Does, the Harder It Is to Name</h3>
<p>If you find yourself having trouble naming something, it is most often (though not always) because it does too many things that are not conceptually related.</p>
<p>The degree to which software entities are conceptually related is known as <a target="_blank" href="https://en.wikipedia.org/wiki/Cohesion_\(computer_science\)">cohesion</a>.</p>
<p><strong>By looking at what parts of a program are cohesive or not</strong>,** you can begin to understand what should be separated or grouped together.**</p>
<p>This process can be done from various perspectives, which I will try to explain by example.</p>
<p>Suppose you have four software entities:</p>
<ol>
<li><p><code>StoreUserInCloud</code></p>
</li>
<li><p><code>StoreUserOnDisk</code></p>
</li>
<li><p><code>StoreMessage</code></p>
</li>
<li><p><code>EditUserUI</code></p>
</li>
</ol>
<p>The first perspective we can consider is the real-world information which these entities are concerned with. From that perspective, we can see that <code>StoreUserInCloud</code>,<code>StoreUserOnDisk</code>, and <code>EditUserUI</code>use the same model of information: A User.</p>
<p>However, there is another perspective that we must keep in mind, particularly when designing graphical user interface (GUI) programs.</p>
<p>Every GUI program can be broken down into three principal layers:</p>
<ul>
<li><p>User Interface (commonly called “View”)</p>
</li>
<li><p>Logic (commonly refers to things like Controllers and Presenters)</p>
</li>
<li><p>Model (data storage and access, or the state itself depending on your definition)</p>
</li>
</ul>
<p>This does not mean that you should only ever look at a program as having these three layers! The three layer approach is a generalization which is <strong>frequently insufficient</strong>.</p>
<p>In any case, from that perspective, <code>StoreMessage</code> has more in common with the other storage entities than does <code>EditUserUI</code>.</p>
<p>Being able to look at your programs from multiple perspectives is something that will come as you build more complex programs.</p>
<p>The key takeaway is that separating your codebase into cohesive, related parts will generally make software entities easier to name.</p>
<h2 id="heading-how-to-use-helper-functions">How to Use Helper Functions</h2>
<p>Helper functions, particularly when combined with good function naming practices, can greatly improve the readability of your code.</p>
<p>Helper functions are also an opportunity to apply a core principle of software architecture: Separation of concerns.</p>
<h3 id="heading-how-to-create-sudoku-puzzles-with-helper-functions">How to Create Sudoku Puzzles with Helper Functions</h3>
<p>We will now look at a practical example to demonstrate extensive usage of helper functions. Please try to imagine how much harder this code would be to follow if everything was just in a single, giant function!</p>
<p>In the past, I worked on a large but cohesive part of a program: A <a target="_blank" href="https://en.wikipedia.org/wiki/Sudoku">Sudoku</a> builder which uses graph data structures and algorithms. Even if you are not familiar with Sudoku or graph DSA, I believe you will still be able to follow the main point.</p>
<p>You can find the full <a target="_blank" href="https://github.com/BracketCove/GraphSudokuOpen/tree/master/app/src/main/java/com/bracketcove/graphsudoku/computationlogic">source code here</a>.</p>
<p>We can break the process of generating a playable Sudoku puzzle into five steps:</p>
<ul>
<li><p>Creating the nodes of the puzzle (representing the tiles)</p>
</li>
<li><p>Creating the edges of the puzzle (edges in this case is another word for relationships/references between the tiles: Either row, column, or subgrid)</p>
</li>
<li><p>Seeding (adding) some values to the data structure to make solving it faster</p>
</li>
<li><p>Solving the puzzle</p>
</li>
<li><p>Unsolving a certain number of tiles so that the game is actually playable by a user</p>
</li>
</ul>
<p>I used something similar to the builder pattern to represent these steps in the function I call to create the puzzle:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">internal</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">buildNewSudoku</span><span class="hljs-params">(
    boundary: <span class="hljs-type">Int</span>,
    difficulty: <span class="hljs-type">Difficulty</span>
)</span></span>: SudokuPuzzle = buildNodes(boundary, difficulty)
        .buildEdges()
        .seedColors()
        .solve()
        .unsolve()
</code></pre>
<p>Although the idea of “nodes” and “edges” are technical definitions within <a target="_blank" href="https://en.wikipedia.org/wiki/Graph_theory">graph theory</a>, this code clearly reflects the five steps I had decided on.</p>
<p>We will not look at the entire codebase, but I want to highlight how the helper functions continue to break down the logic and promote readability:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">internal</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> SudokuPuzzle.<span class="hljs-title">buildEdges</span><span class="hljs-params">()</span></span>: SudokuPuzzle {
    <span class="hljs-keyword">this</span>.graph.forEach {
        <span class="hljs-keyword">val</span> x = it.value.first.x
        <span class="hljs-keyword">val</span> y = it.value.first.y

        it.value.mergeWithoutRepeats(
                getNodesByColumn(<span class="hljs-keyword">this</span>.graph, x)
        )

        it.value.mergeWithoutRepeats(
                getNodesByRow(<span class="hljs-keyword">this</span>.graph, y)
        )

        it.value.mergeWithoutRepeats(
                getNodesBySubgrid(<span class="hljs-keyword">this</span>.graph, x, y, boundary)
        )

    }
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>
}

<span class="hljs-keyword">internal</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> LinkedList<span class="hljs-type">&lt;SudokuNode&gt;</span>.<span class="hljs-title">mergeWithoutRepeats</span><span class="hljs-params">(new: <span class="hljs-type">List</span>&lt;<span class="hljs-type">SudokuNode</span>&gt;)</span></span> {
    <span class="hljs-keyword">val</span> hashes: MutableList&lt;<span class="hljs-built_in">Int</span>&gt; = <span class="hljs-keyword">this</span>.map { it.hashCode() }.toMutableList()
    new.forEach {
        <span class="hljs-keyword">if</span> (!hashes.contains(it.hashCode())) {
            <span class="hljs-keyword">this</span>.add(it)
            hashes.add(it.hashCode())
        }
    }
}

<span class="hljs-keyword">internal</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getNodesByColumn</span><span class="hljs-params">(graph: <span class="hljs-type">LinkedHashMap</span>&lt;<span class="hljs-type">Int</span>,
        LinkedList&lt;SudokuNode&gt;&gt;, x: <span class="hljs-type">Int</span>)</span></span>: List&lt;SudokuNode&gt; {
    <span class="hljs-keyword">val</span> edgeList = mutableListOf&lt;SudokuNode&gt;()
    graph.values.filter {
        it.first.x == x
    }.forEach {
        edgeList.add(it.first)
    }
    <span class="hljs-keyword">return</span> edgeList
}
<span class="hljs-comment">//...</span>
</code></pre>
<p>To summarize this process, the helper functions provide two benefits:</p>
<ul>
<li><p>They are a stand in for a blob of code which does something</p>
</li>
<li><p>That blob of code can be given a descriptive name</p>
</li>
</ul>
<p>Both of those benefits can lead to greater legibility as the code becomes less cluttered and more descriptive.</p>
<p>If you are wondering what should and should not be a helper function, I suggest you practice different approaches to see what works for you.</p>
<h2 id="heading-how-to-use-code-comments">How to Use Code Comments</h2>
<p>My personal preference on code comments is that they have two primary usages: First, comments help describe complex functions in detail.</p>
<p>Second, to clear up any confusion about a line or block of code.</p>
<h3 id="heading-how-to-use-comments-to-design-new-functions">How To Use Comments to Design New Functions</h3>
<p>When I come across functions which I expect to be difficult to write, I will describe what the function does using either plain language or pseudocode.</p>
<p>How I do this has changed over the years, so I encourage you to try different approaches.</p>
<p>In the examples from the previous section, I had omitted the code comments:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">/**
 * 1. Generate a Map which contains n*n nodes.
 * 2. for each adjacent node (as per rules of Sudoku), add an Edge to the hashset
 *  - By column
 *  - By row
 *  - By n sized subgrid
 *
 *  LinkedHashMap: I chose to use a LinkedHashMap because it preserves the ordering of
 *  the elements placed within the Map, but also allows lookups by hash code, which are
 *  generated by x and y values.
 *
 *  As for the LinkedList in each bucket (element) of the map, assume that the first element
 *  is the node at hashCode(x, y), and subsequent elements are edges of that element.
 *  Apart from the ordering the first element as the Head of the LinkedList, the rest of
 *  the elements need not be ordering in any particular fashion.
 *
 *
 *  */</span>
<span class="hljs-keyword">internal</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">buildNodes</span><span class="hljs-params">(n: <span class="hljs-type">Int</span>, difficulty: <span class="hljs-type">Difficulty</span>)</span></span>: SudokuPuzzle {
    <span class="hljs-keyword">val</span> newMap = LinkedHashMap&lt;<span class="hljs-built_in">Int</span>, LinkedList&lt;SudokuNode&gt;&gt;()

    (<span class="hljs-number">1</span>..n).forEach { xIndex -&gt;
        (<span class="hljs-number">1</span>..n).forEach { yIndex -&gt;
            <span class="hljs-keyword">val</span> newNode = SudokuNode(
                    xIndex,
                    yIndex,
                    <span class="hljs-number">0</span>
            )

            <span class="hljs-keyword">val</span> newList = LinkedList&lt;SudokuNode&gt;()
            newList.add(newNode)
            newMap.put(
                    newNode.hashCode(),
                    newList
            )
        }
    }
    <span class="hljs-keyword">return</span> SudokuPuzzle(n, difficulty, newMap)
}
</code></pre>
<p>The amount of detail I add to these comments depends on the context. If I am working in a team, I will usually try to keep this much shorter than what you see above, and only include information that I feel is necessary.</p>
<p>The example above was a personal learning project that I expected to share with others. This is why I even included my decision making process on the types used to represent a Sudoku puzzle.</p>
<p>For fans of test driven development, you might try writing out the pseudocode steps of an algorithm before writing the test:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">/**
     * On bind process, called by view in onCreate. Check current user state, write that result to
     * vModel, show loading graphic, perform some initialization
     *
     * a. User is Anonymous
     * b. User is Registered
     *
     * a:
     * 1. Display Loading View
     * 2. Check for a logged in user from auth: null
     * 3. write null to vModel user state
     * 4. call On start process
     */</span>
    <span class="hljs-meta">@Test</span>
    <span class="hljs-function"><span class="hljs-keyword">fun</span> `On bind User anonymous`<span class="hljs-params">()</span></span> = runBlocking {

        <span class="hljs-comment">//...</span>
    }
</code></pre>
<p>This allows you to design the unit at a <strong>higher level of abstraction</strong> before writing the implementation. The time you spend designing at higher levels of abstraction can save you time in the long run.</p>
<h3 id="heading-how-to-use-inline-code-comments-effectively">How to Use Inline Code Comments Effectively</h3>
<p>There are two primary situations where I will write an inline code comment:</p>
<ul>
<li><p>When I feel that the purpose of a line or block of code will not be clear to myself or anyone else reading it later</p>
</li>
<li><p>When I have to call some poorly named library function which has a confusing or misleading name</p>
</li>
</ul>
<p>By far, the most complex Sudoku algorithm in my program is the <a target="_blank" href="https://github.com/BracketCove/GraphSudokuOpen/blob/master/app/src/main/java/com/bracketcove/graphsudoku/computationlogic/SolveSudoku.kt">solver algorithm</a>. In fact, it's so long that I will only post a snippet of it here:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">internal</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> SudokuPuzzle.<span class="hljs-title">solve</span><span class="hljs-params">()</span></span>
        : SudokuPuzzle {
    <span class="hljs-comment">//nodes that have been assigned (not including nodes seeded from seedColors()</span>
    <span class="hljs-keyword">val</span> assignments = LinkedList&lt;SudokuNode&gt;()

    <span class="hljs-comment">//keep track of failed assignment attempts to watch for infinite loops</span>
    <span class="hljs-keyword">var</span> assignmentAttempts = <span class="hljs-number">0</span>
    <span class="hljs-comment">//Two stages of backtracking, partial is half the dataset, full is a complete restart</span>
    <span class="hljs-keyword">var</span> partialBacktrack = <span class="hljs-literal">false</span>

    <span class="hljs-keyword">var</span> fullbacktrackCounter = <span class="hljs-number">0</span>

    <span class="hljs-comment">//from 0 - boundary, represents how "picky" the algorithm is about assigning new values</span>
    <span class="hljs-keyword">var</span> niceValue: <span class="hljs-built_in">Int</span> = (boundary / <span class="hljs-number">2</span>)

    <span class="hljs-comment">//to avoid being too nice too soon</span>
    <span class="hljs-keyword">var</span> niceCounter = <span class="hljs-number">0</span>

    <span class="hljs-comment">//work with a copy</span>
    <span class="hljs-keyword">var</span> newGraph = LinkedHashMap(<span class="hljs-keyword">this</span>.graph)
    <span class="hljs-comment">//all nodes which are of 0 value (uncolored)</span>
    <span class="hljs-keyword">val</span> uncoloredNodes = LinkedList&lt;SudokuNode&gt;()
    newGraph.values.filter { it.first.color == <span class="hljs-number">0</span> }.forEach { uncoloredNodes.add(it.first) }

    <span class="hljs-keyword">while</span> (uncoloredNodes.size &gt; <span class="hljs-number">0</span>) {
    <span class="hljs-comment">//...</span>
    }
<span class="hljs-comment">//...</span>
}
</code></pre>
<p>In this case, inline comments were necessary as I would frequently forget what some of these variables were while reading through this giant algorithm.</p>
<p>Another case where I will add an inline comment is when I have to explain or remind myself about code which I do not have control over.</p>
<p>For example, the infamous <a target="_blank" href="https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#MONTH">Java Calendar API</a> uses zero-based indexing for months. This is arguably really stupid, as I am not aware of any standard that represents January with 0, nor do I care if one exists!</p>
<p>I cannot share the code with you as it is proprietary, but suffice it to say that I have comments in my current team’s codebase that explains random <code>- 1</code> statements to conform to the Calendar API.</p>
<h2 id="heading-how-to-use-enums-and-dictionaries">How To Use Enums and Dictionaries</h2>
<p>There are other names for these kinds of code constructs, but these are the two I am familiar with. Suppose you have a restricted, or limited, set of values which you use to represent something.</p>
<p>For example, I needed a way to limit the number of tiles that are included in a new Sudoku puzzle, based on:</p>
<ul>
<li><p>The size of the puzzle (4, 9, or 16 tiles per column/row/subgrid)</p>
</li>
<li><p>The difficulty of the puzzle (easy, medium, or hard)</p>
</li>
</ul>
<p>Through extensive testing, I arrived at the following values as modifiers:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">enum</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Difficulty</span></span>(<span class="hljs-keyword">val</span> modifier:<span class="hljs-built_in">Double</span>) {
    EASY(<span class="hljs-number">0.50</span>),
    MEDIUM(<span class="hljs-number">0.44</span>),
    HARD(<span class="hljs-number">0.38</span>)
}

<span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SudokuPuzzle</span></span>(
        <span class="hljs-keyword">val</span> boundary: <span class="hljs-built_in">Int</span>,
        <span class="hljs-keyword">val</span> difficulty: Difficulty,
        <span class="hljs-keyword">val</span> graph: LinkedHashMap&lt;<span class="hljs-built_in">Int</span>, LinkedList&lt;SudokuNode&gt;&gt;
        = buildNewSudoku(boundary, difficulty).graph,
        <span class="hljs-keyword">var</span> elapsedTime: <span class="hljs-built_in">Long</span> = <span class="hljs-number">0L</span>
)<span class="hljs-comment">//...</span>
</code></pre>
<p>These values are used in various places where the logic must change based on the difficulty.</p>
<p>Sometimes, you do not even need to have values associated with human-readable names. I used a different enum to represent different solving strategies to ensure a puzzle is playable relative to the selected difficulty:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">enum</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SolvingStrategy</span> </span>{
    BASIC,
    ADVANCED,
    UNSOLVABLE
}

<span class="hljs-keyword">internal</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">determineDifficulty</span><span class="hljs-params">(
    puzzle: <span class="hljs-type">SudokuPuzzle</span>
)</span></span>: SolvingStrategy {
    <span class="hljs-keyword">val</span> basicSolve = isBasic(
        puzzle
    )
    <span class="hljs-keyword">val</span> advancedSolve = isAdvanced(
        puzzle
    )

    <span class="hljs-comment">//if puzzle is no longer solvable, we return the current strategy</span>
    <span class="hljs-keyword">if</span> (basicSolve) <span class="hljs-keyword">return</span> SolvingStrategy.BASIC
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (advancedSolve) <span class="hljs-keyword">return</span> SolvingStrategy.ADVANCED
    <span class="hljs-keyword">else</span> {
        puzzle.print()
        <span class="hljs-keyword">return</span> SolvingStrategy.UNSOLVABLE
    }
}
</code></pre>
<p>A good principle in designing any system is this: <strong>Fewer moving parts generally have fewer things that can go wrong</strong>.</p>
<p>Placing restrictions on values and types, and giving them good names, not only makes your code easier to read, <strong>it can protect it from errors as well</strong>.</p>
<h2 id="heading-how-to-organize-and-name-packages-folders-and-directories">How to Organize and Name Packages, Folders, and Directories</h2>
<p>No guide on code legibility would be complete without some discussion on packages. If the platform and language of your preference does not use this term, assume I mean folder or directory instead.</p>
<p>This is something which I have changed my opinions on several times, and that is reflected in my older projects.</p>
<p>Two common approaches to package organization are:</p>
<ul>
<li><p>Package by architectural layer</p>
</li>
<li><p>Package by feature</p>
</li>
</ul>
<h3 id="heading-how-to-do-package-by-layer">How to Do Package By Layer</h3>
<p>Package by layer is the first and worst system I have ever used. The idea is usually to build your package structure around some architectural pattern like MVC, MVP, MVVM, and so on.</p>
<p>To take MVC as an example, your top level package structure would look like this:</p>
<ul>
<li><p>model</p>
</li>
<li><p>view</p>
</li>
<li><p>controller</p>
</li>
</ul>
<p>The first problem with this approach is that it assumes that every class or function fits comfortably in one of these layers. This is rarely the case in practice.</p>
<p>I also find this approach to be the least legible, as the top level tells you only the most general details about what to expect inside each package.</p>
<p>This approach can usually be improved upon by adding more “layers” to be more specific:</p>
<ul>
<li><p>ui</p>
</li>
<li><p>model</p>
</li>
<li><p>api</p>
</li>
<li><p>buildlogic/di</p>
</li>
<li><p>repository</p>
</li>
<li><p>domain</p>
</li>
<li><p>common</p>
</li>
</ul>
<p>This can work reasonably well in smaller codebases where all developers are familiar with the general pattern and style used.</p>
<h3 id="heading-how-to-do-package-by-feature">How To Do Package By Feature</h3>
<p>Package by feature has its own flaws, but is generally easier to read and navigate. This is assuming that you give the packages good names.</p>
<p>The term feature is tough to describe, but I would generally define it as this: A screen/page, or set of screens/pages that define a <strong>primary piece of functionality</strong> for users or customers.</p>
<p>For a social media app, we might see a structure such as:</p>
<ul>
<li><p>timeline</p>
</li>
<li><p>friends</p>
</li>
<li><p>userprofile</p>
</li>
<li><p>messages</p>
</li>
<li><p>messagedetail</p>
</li>
</ul>
<p>The core problem with package by feature is the opposite of package by layer: There will almost always be software entities which are used in multiple features.</p>
<p>There are two solutions to this problem. The first would be to have duplicate code in each feature.</p>
<p>Believe it or not, duplicating software entities <strong>can be incredibly useful in enterprise settings</strong> in specific situations.</p>
<p>However, it is not something I would recommend as a general rule.</p>
<h3 id="heading-how-to-do-a-hybrid-package-structure">How to Do a Hybrid Package Structure</h3>
<p>The solution I generally recommend to developers is what I like to call the hybrid approach. It is very simple, flexible, and should cover most of your requirements:</p>
<ul>
<li><p>timeline</p>
</li>
<li><p>friends</p>
</li>
<li><p>messages</p>
</li>
</ul>
<ul>
<li><p>allmessages</p>
</li>
<li><p>conversation</p>
</li>
<li><p>messagedetail</p>
</li>
</ul>
<ul>
<li>api</li>
</ul>
<ul>
<li><p>timeline</p>
</li>
<li><p>user</p>
</li>
<li><p>message</p>
</li>
</ul>
<ul>
<li>uicomponents</li>
</ul>
<p>Please do not take this example too seriously; I am trying to convey the general idea: Anything which is feature specific goes into that feature package. Anything which is shared across features goes into a separate package nested at the same level or a higher level.</p>
<p>Again, what defines a layer was a vague concept to begin with, so do not just follow a convention blindly. <strong>Think critically about what is clear, particularly to someone who is not familiar with the project</strong>.</p>
<h2 id="heading-closing-thoughts">Closing Thoughts</h2>
<p>Most of my preferences on code legibility and style have come from a great deal of trying different approaches. Sometimes these were approaches I saw others use and some of them came about naturally.</p>
<p>If you are able to put yourself in the position of someone less familiar with the code or program you are looking at, you will have an easier time making your code read like a book.</p>
<h3 id="heading-before-you-go">Before you go...</h3>
<p>If you liked this article and want more information on these principles and code constructs, check out my free, full length <a target="_blank" href="https://youtu.be/FL2SMZxNQlc">programming fundamentals course</a>. It includes professionally written English, Burmese, and Arabic subtitles.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Style and Theme an App With Jetpack Compose ]]>
                </title>
                <description>
                    <![CDATA[ In this article, we will learn how to style and theme an application in Jetpack Compose. Compose is a new UI framework for Android (though Desktop and Web support is being developed), which replaces the old XML-based View system. While still in beta ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-style-and-theme-an-app-with-jetpack-compose/</link>
                <guid isPermaLink="false">66d460cb47a8245f78752abd</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ android app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ User Interface ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ryan Michael Kay ]]>
                </dc:creator>
                <pubDate>Mon, 22 Mar 2021 13:48:12 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/6054c45f687d62084bf67e41.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, we will learn how to style and theme an application in Jetpack Compose.</p>
<p>Compose is a new UI framework for Android (though Desktop and Web support is being developed), which replaces the old XML-based View system.</p>
<p>While still in beta release as of writing this article, I do not expect this particular part of the library to change drastically for the stable release.</p>
<p>Topics include:</p>
<ul>
<li><p>A brief recap of the XML approach</p>
</li>
<li><p>How to migrate from the XML-based colors, themes, and typography (font) system</p>
</li>
<li><p>How to set up light and dark themes for your apps in only a few lines of code</p>
</li>
<li><p>How to use your new Kotlin-based style information in your composables</p>
</li>
<li><p>How to style Text Composables specifically</p>
</li>
</ul>
<p>Before proceeding, it is important that you understand what a composable is. I will not be stopping to explain that concept here, as I already have in <a target="_blank" href="https://www.freecodecamp.org/news/jetpack-compose-beginner-tutorial-composables-recomposition/">this article</a>.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/81r-vwPxlaw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-how-we-used-to-style-android-apps-using-xml-resources">How We Used to Style Android Apps Using XML Resources</h2>
<p>As usual, I like to share with you the motivations behind, and a bit of history on, these topics. In case you do not care, feel free to skip to the next section where we get into the practical stuff.</p>
<h3 id="heading-android-resources">Android Resources</h3>
<p>The Android app resources system is something which the Android team deserves a high five for, at least in my opinion. But like every design decision, a feature in one situation becomes a flaw in another situation.</p>
<p>To be specific, one of the greatest challenges for both platform and application developers alike is to create what I will call <strong>localized resources</strong>. I am referring to the challenge of building apps which:</p>
<ul>
<li><p>Display text and graphics in a variety of different languages and alphabets</p>
</li>
<li><p>Look and feel proportionate to a wide variety of form factors (dimensions, densities, and so on.)</p>
</li>
</ul>
<p>Those are just two common examples – there are plenty more. The resource system gives us a place where app developers can provide localized resources which the platform can select for at compile time. This saves us having to write that boilerplate code ourselves.</p>
<h3 id="heading-feature-or-flaw">Feature or Flaw?</h3>
<p>While I would never want to manage the boilerplate code necessary for localized string resources myself, that does not mean I enjoy writing XML.</p>
<p>In fact, <strong>there are very few things I would prefer to do in XML</strong> over a modern, idiomatic, and elegant language such as Kotlin or Swift. Personal preference aside, there is a more technical reason why XML resources are not always ideal.</p>
<p>Please note that this is not meant as a criticism of the platform developers/engineers. It is merely an observation of how design decisions always have benefits and costs.</p>
<p>In order to integrate our XML-based resources into our JVM-based application code, we must necessarily have <strong>layers of translation</strong> (compilation) and <strong>platform bridges</strong> (APIs). This can present difficulties for both platform and application developers.</p>
<p>Two common problems I ran into were:</p>
<ul>
<li><p>I want access to a resource in a place where I do not want tight coupling to the platform APIs which provide the resource</p>
</li>
<li><p>I have to write some ridiculous boilerplate code just to change the look of a View (that is, override something defined within resource styles and themes)</p>
</li>
</ul>
<p>The <strong>root problem</strong> for everyone involved is <strong>tight coupling</strong> to the View system and the Android resource system (which are themselves tightly coupled together).</p>
<p>For the platform developers, this means they have to build on top of, or work around gigantic and old codebases. Add that they must also try to have new features work on older Android OS versions, and that becomes a very thankless job.</p>
<p>The result for us application developers is most often a lot of <strong>boilerplate code,</strong> some <strong>hacky workarounds</strong> for things which intuitively seem like they should be one-liners. Not to mention the main API for getting these resources is <code>Context</code>, which is a class you really do not want to leak in memory.</p>
<p><strong>Enter Jetpack Compose.</strong></p>
<h2 id="heading-how-to-set-up-themes-colors-and-fonts-with-jetpack-compose">How to Set Up Themes, Colors, and Fonts with Jetpack Compose</h2>
<p>With our review of the old system out of the way, let's explore a much prettier and simpler way to style and theme an Android application. I said I would keep this practical, but allow one point.</p>
<p>Since we will be doing that work in Kotlin, it means one very important thing: Both we and the platform developers are much less bound by translation (compilation) and API bridges (Android's <code>R</code> class and <code>Context</code>) between XML and the JVM.</p>
<p>In simple terms, this means <strong>much less boilerplate code</strong>, and <strong>much more control at runtime</strong>.</p>
<p>For the practical part of this article, my suggestion to you is to follow this process in the order I explain it. I have structured it in the order I follow when writing this code in a new App.</p>
<h3 id="heading-how-to-replace-colorsxml-resources-with-kotlin-compose">How to Replace Colors.xml Resources with Kotlin Compose</h3>
<p>If you have not already decided upon a color scheme for your application, I suggest that you use the various resources available on the official Material Design website. Try out:</p>
<ul>
<li><p>The <a target="_blank" href="https://material.io/design/color/the-color-system.html#tools-for-picking-colors">color palettes</a></p>
</li>
<li><p>The <a target="_blank" href="https://material.io/resources/color/">color tool</a></p>
</li>
</ul>
<p>If you plan to support light and dark app themes (explained shortly), try to select a color scheme which supports white text and a color scheme which supports black text.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/color_text_palettes.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Example of light and dark color schemes.</em></p>
<p>Create a file called something like <a target="_blank" href="https://github.com/BracketCove/GraphSudokuOpen/blob/master/app/src/main/java/com/bracketcove/graphsudoku/ui/Color.kt">Color.kt</a> (the name does not matter) and fill it with immutable <strong>val</strong>ues:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">import</span> androidx.compose.ui.graphics.Color

<span class="hljs-keyword">val</span> primaryGreen = Color(<span class="hljs-number">0XFF00bc00</span>)
<span class="hljs-keyword">val</span> primaryCharcoal = Color(<span class="hljs-number">0xFF2b2b2b</span>)
<span class="hljs-keyword">val</span> accentAmber = Color(<span class="hljs-number">0xFFffe400</span>)

<span class="hljs-keyword">val</span> textColorLight = Color(<span class="hljs-number">0xDCFFFFFF</span>)
<span class="hljs-keyword">val</span> textColorDark = Color(<span class="hljs-number">0xFFf3f3f3</span>)
<span class="hljs-keyword">val</span> gridLineColorLight = Color.Black
<span class="hljs-comment">//...</span>
</code></pre>
<p>You can either use a predefined value like <code>Color.Black</code> or supply your own ARGB Hex value.</p>
<p>Since ARGB Hex is just a bunch of jargon to describe what the heck "<code>0XFF00bc00</code>" means, let me translate:</p>
<ul>
<li><p>First two characters <code>0x</code> tell the compiler that this is a hexadecimal number</p>
</li>
<li><p>Second two characters , "<code>FF</code>" or "<code>DC</code>", represent Transparency/Opaqueness/<strong>A</strong>lpha in Hex</p>
</li>
<li><p>The remaining six character pairs represent <strong>R</strong>ed, <strong>G</strong>reen, and <strong>B</strong>lue</p>
</li>
</ul>
<h3 id="heading-how-to-add-fonts-and-replace-the-fontfamily-attribute">How to Add Fonts and Replace the <code>fontFamily</code> Attribute</h3>
<p>Typography (fonts) is also very easy to manage. This is the kind of thing where Kotlin's <a target="_blank" href="https://kotlinlang.org/docs/functions.html#default-arguments">default arguments</a> are very useful.</p>
<p>Create a file called something like <a target="_blank" href="https://github.com/BracketCove/GraphSudokuOpen/blob/master/app/src/main/java/com/bracketcove/graphsudoku/ui/Type.kt">Type.kt</a> (the name still does not matter) and create <code>Typography</code> class...:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> typography = Typography(
    body1 = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = <span class="hljs-number">16</span>.sp
    ),

    button = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Bold,
        fontSize = <span class="hljs-number">32</span>.sp
    ),

    caption = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = <span class="hljs-number">12</span>.sp
    )
)
<span class="hljs-comment">//...</span>
</code></pre>
<p>...and some <code>TextStyle</code> classes:</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">//...</span>
<span class="hljs-keyword">val</span> mainTitle = TextStyle(
    fontFamily = FontFamily.Default,
    fontWeight = FontWeight.Light,
    fontSize = <span class="hljs-number">48</span>.sp,
    textAlign = TextAlign.Center
)

<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">dropdownText</span><span class="hljs-params">(color: <span class="hljs-type">Color</span>)</span></span> = TextStyle(
    fontFamily = FontFamily.Default,
    fontWeight = FontWeight.Normal,
    fontSize = <span class="hljs-number">32</span>.sp,
    textAlign = TextAlign.Center,
    color = color
)
<span class="hljs-comment">//...</span>
</code></pre>
<p>Whether you provide public functions or values (I advise against using <code>**var**</code> here) is up to your individual preference and current requirements.</p>
<h3 id="heading-how-to-create-an-app-theme-in-jetpack-compose">How to Create an App Theme in Jetpack Compose</h3>
<p>The last thing you need to configure before using your theme in your composables is a <code>MaterialTheme @Composable</code>. I have mine, and along with my light and dark color palettes in a file called <a target="_blank" href="https://github.com/BracketCove/GraphSudokuOpen/blob/master/app/src/main/java/com/bracketcove/graphsudoku/ui/GraphSudokuTheme.kt">GraphSudokuTheme</a>:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">import</span> androidx.compose.foundation.isSystemInDarkTheme
<span class="hljs-keyword">import</span> androidx.compose.material.MaterialTheme
<span class="hljs-keyword">import</span> androidx.compose.material.darkColors
<span class="hljs-keyword">import</span> androidx.compose.material.lightColors
<span class="hljs-keyword">import</span> androidx.compose.runtime.Composable
<span class="hljs-keyword">import</span> androidx.compose.ui.graphics.Color

<span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> LightColorPalette = lightColors(
    primary = primaryGreen,
    secondary = textColorLight,
    surface = lightGrey,
    primaryVariant = gridLineColorLight,
    onPrimary = accentAmber,
    onSurface = accentAmber
)

<span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> DarkColorPalette = darkColors(
    <span class="hljs-comment">//main background color</span>
    primary = primaryCharcoal,
    <span class="hljs-comment">//used for text color</span>
    secondary = textColorDark,
    <span class="hljs-comment">//background of sudoku board</span>
    surface = lightGreyAlpha,
    <span class="hljs-comment">//grid lines of sudoku board</span>
    primaryVariant = gridLineColorLight,
    onPrimary = accentAmber,

    onSurface = accentAmber

)

<span class="hljs-meta">@Composable</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">GraphSudokuTheme</span><span class="hljs-params">(
    darkTheme: <span class="hljs-type">Boolean</span> = isSystemInDarkTheme()</span></span>,
    content: <span class="hljs-meta">@Composable</span> () -&gt; <span class="hljs-built_in">Unit</span>
) {

    MaterialTheme(
        colors = <span class="hljs-keyword">if</span> (darkTheme) DarkColorPalette <span class="hljs-keyword">else</span> LightColorPalette,
        typography = typography,
        shapes = shapes,
        content = content
    )
}
</code></pre>
<p>Since you should already be familiar with what a composable is (I gave you fair warning), the only new thing here is <code>darkTheme: Boolean = isSystemInDarkTheme()</code>.</p>
<p>To give a simplified explanation, <code>isSystemInDarkTheme()</code> is a call which asks any compatible Android device for the user's preference of a light or dark theme.</p>
<p>It <strong>returns a boolean value</strong> which we can use in a Ternary (Conditional) Assignment expression such as <code>colors = if (darkTheme) DarkColorPalette else LightColorPalette</code>.</p>
<p>That is actually it. Colors, Fonts, and two Themes defined in a few minutes.</p>
<h2 id="heading-how-to-use-a-theme-in-compose">How to Use a Theme in Compose</h2>
<p>It is now time to use this Theme in your app. In this app, which only has two primary screens, I just use an <a target="_blank" href="https://github.com/BracketCove/GraphSudokuOpen/blob/master/app/src/main/java/com/bracketcove/graphsudoku/ui/activegame/ActiveGameActivity.kt">Activity</a> as a <strong>container</strong> for my composables:</p>
<pre><code class="lang-pgsql"><span class="hljs-keyword">class</span> NewGameActivity : AppCompatActivity(), NewGameContainer {
    //...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //...

        setContent {
            GraphSudokuTheme {
                NewGameScreen(
                    onEventHandler = logic::onEvent,
                    viewModel
                )
            }
        }
        //...
    }
</code></pre>
<p>Wherever you find yourself calling <code>setContent {}</code>, my suggestion for beginners is to immediately place your Theme composable inside of it. Doing so will cause the style information to <strong>cascade/inherit to each nested composable</strong>.</p>
<p>You are done! Almost.</p>
<h2 id="heading-how-to-override-styles-and-themes">How to Override Styles and Themes</h2>
<p>If you can help it, try to include any colors you will want in your light and dark palettes. This way, when you call <code>MaterialTheme.colors.&lt;Color&gt;</code>, the system will handle the conditional logic necessary to pick the appropriate palette:</p>
<pre><code class="lang-pgsql">@Composable
fun NewGameContent(
    onEventHandler: (NewGameEvent) -&gt; Unit,
    viewModel: NewGameViewModel
) {
    Surface(
        Modifier
            .wrapContentHeight()
            .fillMaxWidth()
    ) {
        ConstraintLayout(Modifier.background(MaterialTheme.colors.<span class="hljs-keyword">primary</span>)) { 
            //...
        }
        //...
      }
}
</code></pre>
<p>However, sometimes it is more suitable to write your own conditional logic...or I just got lazy. Fortunately Compose makes many such configurations available as properties:</p>
<pre><code class="lang-pgsql">@Composable
fun DoneIcon(onEventHandler: (NewGameEvent) -&gt; Unit) {
    Icon(
        imageVector = Icons.Filled.Done,
        tint = <span class="hljs-keyword">if</span> (MaterialTheme.colors.isLight) textColorLight 
        <span class="hljs-keyword">else</span> textColorDark,
        contentDescription = <span class="hljs-keyword">null</span>,
        modifier = Modifier
            .clickable(
            //...
            )
    )
}
</code></pre>
<p><code>MaterialTheme.Colors.isLight</code> returns a boolean indicating what mode they are in, then we can use another Ternary Assignment from there.</p>
<h3 id="heading-how-to-style-a-text-composable">How to Style a Text Composable</h3>
<p>Just set the <code>style</code> argument equal to one of your text styles (whether it comes from <code>MaterialTheme</code> or one of the styles within <code>Type.kt</code>):</p>
<pre><code class="lang-kotlin">Text(
    text = stat.toTime(),
    style = statsLabel.copy(
        color = <span class="hljs-keyword">if</span> (isZero) Color.White
        <span class="hljs-keyword">else</span> MaterialTheme.colors.onPrimary,
    fontWeight = FontWeight.Normal
    ),
    modifier = Modifier
        .wrapContentSize()
        .padding(end = <span class="hljs-number">2</span>.dp, bottom = <span class="hljs-number">4</span>.dp),
        textAlign = TextAlign.End
)
</code></pre>
<p><code>TextStyle</code> has its own <code>copy</code> function ready to go should you need to overwrite anything.</p>
<p>And that's it! You now know how to style and theme an application using Jetpack Compose. Thanks for reading :)</p>
<h3 id="heading-social"><strong>Social</strong></h3>
<p>You can find me on <a target="_blank" href="https://www.instagram.com/rkay301/">Instagram here</a> and on <a target="_blank" href="https://twitter.com/wiseAss301">Twitter here</a>.</p>
<h3 id="heading-here-are-some-of-my-tutorials-amp-courses"><strong>Here are some of my tutorials &amp; courses</strong></h3>
<p><a target="_blank" href="https://www.youtube.com/channel/UCSwuCetC3YlO1Y7bqVW5GHg">https://youtube.com/wiseass</a> <a target="_blank" href="https://www.freecodecamp.org/news/author/ryan-michael-kay/">https://www.freecodecamp.org/news/author/ryan-michael-kay/</a> <a target="_blank" href="https://skl.sh/35IdKsj">https://skl.sh/35IdKsj</a> (introduction to Android with Android Studio)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Handle UI Events in Jetpack Compose ]]>
                </title>
                <description>
                    <![CDATA[ In this short and practical article, we will talk about how to handle UI events in Jetpack Compose. In the old system, we used OnClickListeners and other interfaces. In Compose, we can take full advantage of Kotlin’s Sealed Classes, Function Types an... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-handle-ui-events-in-jetpack-compose/</link>
                <guid isPermaLink="false">66d460c99f2bec37e2da066a</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Android Studio ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Jetpack Compose ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kotlin ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ User Interface ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ryan Michael Kay ]]>
                </dc:creator>
                <pubDate>Tue, 16 Mar 2021 18:22:24 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/03/cat-4793068_1280-5.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this short and practical article, we will talk about how to handle UI events in Jetpack Compose.</p>
<p>In the old system, we used OnClickListeners and other interfaces. In Compose, we can take full advantage of Kotlin’s <strong>Sealed Classes</strong>, <strong>Function Types</strong> and <strong>Lambda Expressions</strong>.</p>
<p>If you do not know what a composable is, consider reading <a target="_blank" href="https://www.freecodecamp.org/news/jetpack-compose-beginner-tutorial-composables-recomposition/">this article which explains the fundamentals</a>.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/LrNPw1LQHEw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-how-to-model-ui-events-with-a-sealed-class">How to Model UI Events with a Sealed Class</h2>
<p>First, we must learn what is meant by UI Events and how to model them with Sealed Classes.</p>
<p>I have described this same process for <a target="_blank" href="https://medium.com/swlh/simplify-your-ui-interactions-with-events-java-kotlin-any-language-5062c1b1e0e4">Java and Kotlin</a> (with the old view system) before, so I will keep this brief.</p>
<h3 id="heading-the-process">The Process</h3>
<p>For each screen or sub-screen of your UI, ask yourself this question: What are all the different ways which the user can interact with it?</p>
<p>Let's take an example from my first app built fully in compose, <a target="_blank" href="https://play.google.com/store/apps/details?id=com.bracketcove.graphsudoku">Graph Sudoku</a>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/graph_sudoku_small_screen.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Screenshot of a Sudoku Android App</em></p>
<p>The sealed class I use to represent the UI interactions of this screen looks like this:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">sealed</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ActiveGameEvent</span> </span>{
    <span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OnInput</span></span>(<span class="hljs-keyword">val</span> input: <span class="hljs-built_in">Int</span>) : ActiveGameEvent()
    <span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OnTileFocused</span></span>(<span class="hljs-keyword">val</span> x: <span class="hljs-built_in">Int</span>, 
    <span class="hljs-keyword">val</span> y: <span class="hljs-built_in">Int</span>) : ActiveGameEvent()
    <span class="hljs-keyword">object</span> OnNewGameClicked : ActiveGameEvent()
    <span class="hljs-keyword">object</span> OnStart : ActiveGameEvent()
    <span class="hljs-keyword">object</span> OnStop : ActiveGameEvent()
}
</code></pre>
<p>To explain briefly:</p>
<ul>
<li><p>OnInput represents a user touching an input button (like 0, 1, 2, 3, 4)</p>
</li>
<li><p>OnTileFocused represents a user selecting a tile (like the amber highlighted one)</p>
</li>
<li><p>OnNewGameClicked is self-explanatory</p>
</li>
<li><p>OnStart and OnStop are lifecycle events which my composables do not care about, but they are used in the Activity which acts as a Container for the composables</p>
</li>
</ul>
<p>Once you have your sealed class set up, you can now handle a wide variety of events using a single event handler function. Sometimes it might make more sense to have multiple event handler functions, so keep in mind that <strong>this approach must be adapted to your project's specific requirements</strong>.</p>
<h2 id="heading-how-to-connect-your-software-architecture">How to Connect Your Software Architecture</h2>
<p>What you have handling these events is totally up to you. Some people think that MVVM is the golden standard of software architectures, but it seems like more and more people are realizing that <strong>there is no single architecture which works best for every situation</strong>.</p>
<p>For Android with Compose, my current approach is to use a very 3rd party minimalist approach which typically has these things in each feature (screen):</p>
<ul>
<li><p>A (Presentation) Logic class <strong>as an event handler</strong></p>
</li>
<li><p>A ViewModel to store the data necessary to render the View (as the name implies)</p>
</li>
<li><p>An Activity which acts as a Container (not a god object)</p>
</li>
<li><p>Composables to form the View</p>
</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/model_view_whatever-3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Model-View-Whatever</em></p>
<p>I do not care what you use as long as you are applying <a target="_blank" href="https://youtu.be/B_C41SF0KbI">separation of concerns</a>. This is how I arrived at this architecture, by simply asking what should and should not be put together in the same class.</p>
<p>Whether you want your ViewModel, a Fragment, or an Activity to be your event handler, all of them can be set up the same way: <strong>Function Types!</strong></p>
<p>Within your class of choice, set up an event handler function which accepts your sealed class as its argument:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ActiveGameLogic</span></span>(
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> container: ActiveGameContainer?,
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> viewModel: ActiveGameViewModel,
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> gameRepo: IGameRepository,
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> statsRepo: IStatisticsRepository,
    dispatcher: DispatcherProvider
) : BaseLogic&lt;ActiveGameEvent&gt;(dispatcher),
    CoroutineScope {
    <span class="hljs-comment">//...</span>
    <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">onEvent</span><span class="hljs-params">(event: <span class="hljs-type">ActiveGameEvent</span>)</span></span> {
        <span class="hljs-keyword">when</span> (event) {
            <span class="hljs-keyword">is</span> ActiveGameEvent.OnInput -&gt; onInput(
                event.input,
                viewModel.timerState
            )
            ActiveGameEvent.OnNewGameClicked -&gt; onNewGameClicked()
            ActiveGameEvent.OnStart -&gt; onStart()
            ActiveGameEvent.OnStop -&gt; onStop()
            <span class="hljs-keyword">is</span> ActiveGameEvent.OnTileFocused -&gt; onTileFocused(event.x, event.y)
        }
    }
    <span class="hljs-comment">//...</span>
}
</code></pre>
<p>This approach is very organized and makes it easy to test every Unit in this 3rd party library free class through a single entry point.</p>
<p>However, we are not done yet. Naturally, we need a way to get a reference to this event handler function, <code>onEvent</code>, to our Composables. We can do this using a <strong>function reference</strong>:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ActiveGameActivity</span> : <span class="hljs-type">AppCompatActivity</span></span>(), ActiveGameContainer {
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">lateinit</span> <span class="hljs-keyword">var</span> logic: ActiveGameLogic

    <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">onCreate</span><span class="hljs-params">(savedInstanceState: <span class="hljs-type">Bundle</span>?)</span></span> {
        <span class="hljs-keyword">super</span>.onCreate(savedInstanceState)

        <span class="hljs-keyword">val</span> viewModel = ActiveGameViewModel()

        setContent {
            ActiveGameScreen(
                onEventHandler = logic::onEvent,
                viewModel
            )
        }

        logic = buildActiveGameLogic(<span class="hljs-keyword">this</span>, viewModel, applicationContext)
    }

      <span class="hljs-comment">//...</span>
}
</code></pre>
<p>I am sure some of you are wondering why I am using an Activity. You can ask me during a <a target="_blank" href="https://youtu.be/-xV8k-4UW50">livestream Q&amp;A sometime for a detailed answer</a>.</p>
<p>In short, Fragments appear to be a bit pointless with Compose with my approach to architecture (I do not use Jetpack Navigation), and there is nothing wrong with using Activities as a feature specific container. <strong>Just avoid writing god activities, basically.</strong></p>
<p>To be specific, the way you make a reference to a function in Kotlin, is by providing the <strong>class/interface name</strong> (or <strong>skip that if it is a Top-Level function</strong>), followed by <strong>two colons</strong>, and the <strong>name of the function without any arguments or brackets</strong>:</p>
<pre><code class="lang-pgsql">onEventHandler = logic::onEvent
</code></pre>
<h2 id="heading-how-to-replace-onclicklistener-with-jetpack-compose-onclick-modifier">How to Replace onClickListener With Jetpack Compose onClick Modifier</h2>
<p>With that stuff ready, we can look at how this works within the composable. Naturally, your root composable will need the event handler function as a parameter:</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Composable</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">ActiveGameScreen</span><span class="hljs-params">(
    onEventHandler: (<span class="hljs-type">ActiveGameEvent</span>) -&gt; <span class="hljs-type">Unit</span>,
    viewModel: <span class="hljs-type">ActiveGameViewModel</span>
)</span></span> {
<span class="hljs-comment">//...</span>
}
</code></pre>
<p>It can be a bit tricky to get function type syntax correctly, but understand that this <strong>really is a reference to a function,</strong> which is not so different from a reference to a class.</p>
<p>Just as you should not build god objects, you should not build giant composables:</p>
<ol>
<li><p>Break your UI down into the <strong>smallest reasonable parts</strong></p>
</li>
<li><p>Wrap them in a composable function</p>
</li>
<li><p>For each composable which has a UI interaction associated with it, <strong>it must be given a reference to your event handler function</strong></p>
</li>
</ol>
<p>Here is a composable which represents the input buttons of the Sudoku app, which is given the event handler by reference:</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Composable</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">SudokuInputButton</span><span class="hljs-params">(
    onEventHandler: (<span class="hljs-type">ActiveGameEvent</span>) -&gt; <span class="hljs-type">Unit</span>,
    number: <span class="hljs-type">Int</span>
)</span></span> {
    Button(
        onClick = { onEventHandler.invoke(ActiveGameEvent.OnInput(number)) },
        modifier = Modifier
            .requiredSize(<span class="hljs-number">56</span>.dp)
            .padding(<span class="hljs-number">2</span>.dp)
    ) {
        Text(
            text = number.toString(),
            style = inputButton.copy(color = MaterialTheme.colors.onPrimary),
            modifier = Modifier.fillMaxSize()
        )
    }
}
</code></pre>
<p>To actually pass the event to the logic class, we must use the <code>invoke</code> function, which will accept arguments as per the function type definition (which accepts an <code>ActiveGameEvent</code> in this case).</p>
<p>At this point, you are ready to handle UI interaction events in Kotlin (compose or not) by taking full advantage of this beautiful and modern programming language.</p>
<p>If you liked this article, share it on social media and consider checking out the resources below to support an independent programmer and content creator.</p>
<h3 id="heading-social">Social</h3>
<p>You can find me on <a target="_blank" href="https://www.instagram.com/rkay301/">Instagram here</a> and on <a target="_blank" href="https://twitter.com/wiseAss301">Twitter here</a>.</p>
<h3 id="heading-here-are-some-of-my-tutorials-amp-courses">Here are some of my tutorials &amp; courses</h3>
<p><a target="_blank" href="https://www.youtube.com/channel/UCSwuCetC3YlO1Y7bqVW5GHg">https://youtube.com/wiseass</a> <a target="_blank" href="https://www.freecodecamp.org/news/author/ryan-michael-kay/">https://www.freecodecamp.org/news/author/ryan-michael-kay/</a> <a target="_blank" href="https://skl.sh/35IdKsj">https://skl.sh/35IdKsj</a> (introduction to Android with Android Studio)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A Jetpack Compose Tutorial for Beginners – How To Understand Composables & Recomposition ]]>
                </title>
                <description>
                    <![CDATA[ This tutorial will teach you a few fundamental concepts and terms related to the Jetpack Compose UI Library on Android. While this is a beginner's guide to Compose, it will not be a beginner's guide to Android – so you should have built at least an a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/jetpack-compose-beginner-tutorial-composables-recomposition/</link>
                <guid isPermaLink="false">66d460cdbd438296f45cd3b0</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ryan Michael Kay ]]>
                </dc:creator>
                <pubDate>Mon, 08 Mar 2021 21:19:42 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/6042c692a7946308b7682cbb.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>This tutorial will teach you a few fundamental concepts and terms related to the Jetpack Compose UI Library on Android.</p>
<p>While this is a beginner's guide to Compose, it will not be a beginner's guide to Android – so you should have built at least an application or two (though not in Compose, necessarily).</p>
<p>Before we begin, I was initially planning to write a follow up article directed towards more senior developers until I came across Leland Richardson’s <a target="_blank" href="https://medium.com/androiddevelopers/understanding-jetpack-compose-part-1-of-2-ca316fe39050">two part article series</a>. Leland is not only a Software Engineer working on the Jetpack Compose team, but I see that he is a great writer as well.</p>
<p>While I feel my article will stand on its own as an introduction to the basics of Jetpack Compose, I <strong>strongly suggest</strong> you read his articles once you have gained some practical experience with Compose (or right away if you prefer to learn that way).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/ijwBr4oeX0I" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h3 id="heading-key-termsconcepts-explained-in-this-article">Key Terms/Concepts Explained in this article:</h3>
<ul>
<li><p>A brief review of the old View System and Hierarchy</p>
</li>
<li><p>Composables and how they stand in relation to Views</p>
</li>
<li><p>Recomposition and how to avoid doing it very poorly!</p>
</li>
</ul>
<h1 id="heading-what-is-a-composable">What Is A Composable?</h1>
<p>In this section, we will discuss the most fundamental part of the Jetpack Compose library. If you are a seasoned Android developer, you may wish to skip to the sub-section titled “Are Composables Views?”</p>
<p>If you are not already familiar with the View system, you should read the next section as it is necessary to motivate and understand what a Composable is.</p>
<h2 id="heading-view-hierarchy">View Hierarchy</h2>
<p>In the context of the Android SDK (the libraries we use to make user interfaces on this platform), a View is what we use to give structure and style to our applications.</p>
<p>It is the most fundamental kind of building block or element of a given user interface (UI), and each of these building blocks will contain the following kinds of information (among other things):</p>
<ul>
<li><p>X and Y start and end positions which tell the computer where to draw the view on the device screen</p>
</li>
<li><p>Color and alpha (transparency) values</p>
</li>
<li><p>Font information, text, symbols, and images</p>
</li>
<li><p>Behaviour based on events such as user interaction (clicks) or changes in the application’s data (more on that later)</p>
</li>
</ul>
<p>It is important to understand that <strong>a View can be something like a button</strong> (commonly referred to as a “widget”), <strong>but it can also be a container of the whole screen, part of the screen, or for other child Views</strong>.</p>
<p>Such <strong>containers</strong> are commonly referred to as Layouts or Viewgroups depending on the context. And, while sharing most of the same kinds of information as a widget, they also contain information about how to arrange and display other Views which are <strong>nested</strong> within them.</p>
<p>With that in mind, we get to the important part of this review of the View system: The <strong>View Hierarchy</strong>. For Web Developers, the View Hierarchy is essentially Android’s version of the Document Object Model (DOM).</p>
<p>For Android Developers, you can think of the View Hierarchy as a virtual representation of all the Views which you defined either in XML files or programmatically in Java or Kotlin.</p>
<p>To illustrate this, let's look at such an XML file (there’s no need to study it closely, just note the names). Then, using a debugger/stepper tool, we will look at what it looks like in the memory space of the Fragment which inflates this file:</p>
<p><strong>fragment_hour_view.xml:</strong></p>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;?xml version=”1.0" encoding=”utf-8"?&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">androidx.constraintlayout.widget.ConstraintLayout</span> <span class="hljs-attr">xmlns:android</span>=<span class="hljs-string">”http://schemas.android.com/apk/res/android</span>"
<span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">”match_parent”</span>
<span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">”match_parent”</span>
<span class="hljs-attr">android:id</span>=<span class="hljs-string">”@+id/root_hour_view_fragment”</span>
<span class="hljs-attr">xmlns:app</span>=<span class="hljs-string">”http://schemas.android.com/apk/res-auto</span>"
&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">androidx.compose.ui.platform.ComposeView</span>
<span class="hljs-attr">android:id</span>=<span class="hljs-string">”@+id/tlb_hour_view”</span>
//<span class="hljs-attr">...</span>
 /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">com.wiseassblog.samsaradayplanner.ui.managehourview.HourToggleView</span>
<span class="hljs-attr">android:id</span>=<span class="hljs-string">”@+id/vqht_one”</span>
//<span class="hljs-attr">...</span>
/&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">com.wiseassblog.samsaradayplanner.ui.managehourview.HourToggleView</span>
<span class="hljs-attr">android:id</span>=<span class="hljs-string">”@+id/vqht_two”</span>
//<span class="hljs-attr">...</span>
/&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">com.wiseassblog.samsaradayplanner.ui.managehourview.HourToggleView</span>
<span class="hljs-attr">android:id</span>=<span class="hljs-string">”@+id/vqht_three”</span>
//<span class="hljs-attr">...</span>
/&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">com.wiseassblog.samsaradayplanner.ui.managehourview.HourToggleView</span>
<span class="hljs-attr">android:id</span>=<span class="hljs-string">”@+id/vqht_four”</span>
//<span class="hljs-attr">...</span>
/&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">androidx.constraintlayout.widget.ConstraintLayout</span>&gt;</span>
</code></pre>
<p><strong>Memory Space of (Fragment)HourView.kt:</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-22.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Image of a View Hierarchy</em></p>
<p>The debugger and stepper tools are some of my favourite ways to learn about what is going on under the hood of the code that I use from various libraries. Give it a try some time!</p>
<p>The purpose of showing you this XML file and what it turns into in a <strong>process</strong> (a process is <strong>simply a program that is running</strong> on a device), is to demonstrate how nested Views in an XML file translate into a nested View Hierarchy at runtime.</p>
<p>Hopefully, with a simple but concrete model of how the old system works, we can compare it with the new one.</p>
<h2 id="heading-are-composables-views">Are Composables Views?</h2>
<p>This was one of the first questions I asked when I started working with Compose, and the answer I have arrived at is both <strong>yes</strong> and <strong>no</strong>.</p>
<p><strong>Yes</strong>, in the sense that a Composable fulfills the <strong>same conceptual role as a View</strong> in the old system. A Composable can be a widget like a button, or a container such as a ConstraintLayout (it is worth noting that there is a Composable implementation of ConstraintLayout available).</p>
<p><strong>No</strong>, in the sense that the UI is no longer represented virtually in a View Hierarchy (apart from situations involving interoperability). With that being said, compose does not use magic to virtually represent and keep track of the UI. This means that it must have its own thing which is conceptually similar to a View Hierarchy.</p>
<p>Let us take a very brief look at this thing. Here, we have an Activity which uses the <code>setContent {…}</code> function to bind a Composable to itself:</p>
<p><strong>ActiveGameActivity.kt:</strong></p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ActiveGameActivity</span> : <span class="hljs-type">AppCompatActivity</span></span>(), ActiveGameContainer {
<span class="hljs-keyword">private</span> <span class="hljs-keyword">lateinit</span> <span class="hljs-keyword">var</span> logic: ActiveGameLogic
<span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">onCreate</span><span class="hljs-params">(savedInstanceState: <span class="hljs-type">Bundle</span>?)</span></span> {
    <span class="hljs-keyword">super</span>.onCreate(savedInstanceState)
    <span class="hljs-keyword">val</span> viewModel = ActiveGameViewModel()
    setContent {
        ActiveGameScreen(
            onEventHandler = {
                logic.onEvent(it)
            },
            viewModel
        )
    }
    logic = buildActiveGameLogic(<span class="hljs-keyword">this</span>, viewModel, applicationContext)
}
<span class="hljs-comment">//…</span>
}
</code></pre>
<p><strong>ActiveGameScreen.kt:</strong></p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Composable</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">ActiveGameScreen</span><span class="hljs-params">(
    onEventHandler: ((<span class="hljs-type">ActiveGameEvent</span>) -&gt; <span class="hljs-type">Unit</span>),
    viewModel: <span class="hljs-type">ActiveGameViewModel</span>
)</span></span> {
    <span class="hljs-comment">//...</span>

    GraphSudokuTheme {
        Column(
            Modifier
                .background(MaterialTheme.colors.primary)
                .fillMaxHeight()
        ) {
            ActiveGameToolbar(
                clickHandler = {
                    onEventHandler.invoke(
                        ActiveGameEvent.OnNewGameClicked
                    )
                }
            )

            Box {
              <span class="hljs-comment">//content</span>
            }
        }
    }
}
</code></pre>
<p>In Compose, the View Hierarchy is replaced with something that we can locate if we dig really deeply into the <strong>mWindow</strong> field of this Activity. Within that field is the conceptual replacement of the View Hierarchy: <strong>The</strong> <code>**Composer**</code> <strong>and its</strong> <code>**slotTable**</code><strong>.</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-26.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>At this point, if you want a detailed overview of the <code>Composer</code> and its <code>slotTable</code>, I must again suggest that you read Leland’s article (he goes into detail in <a target="_blank" href="https://medium.com/androiddevelopers/under-the-hood-of-jetpack-compose-part-2-of-2-37b2c20c6cdd">part 2</a>). There is more to the Compose Hierarchy than the Composer and its slotTable, but that should be sufficient to get us started.</p>
<p>In general terms, Jetpack Compose uses what we might call its Compose Hierarchy (which is made of, and managed by things like the Composer and its slotTable).</p>
<p>Again, this is the same conceptual idea as the View hierarchy, a bunch of objects in memory space which collectively represent the UI, but it is implemented very differently.</p>
<p>There's an important difference, though, which is tricky to understand technically, but easy to understand in principle. This is the way in which Compose handles updates to the Compose Hierarchy: <strong>Recomposition</strong>.</p>
<h1 id="heading-recomposition-how-to-update-compose-ui">Recomposition: How To Update Compose UI</h1>
<p>For my ESL friends, the word Compose comes from the latin <em>componere</em>, which roughly means “to put together.” Someone who writes music is often called a “Composer,” which can be thought of as the one who puts together the notes coming from one or more instruments into a composition (song).</p>
<p>Putting together implies that there are individual pieces. It's important to understand that almost any good software developer makes at least some effort to break their code down into the <strong>smallest reasonable parts</strong>.</p>
<p>I mention <strong>reasonable</strong>, because I think principles like DRY (Don’t Repeat Yourself) should be followed only to the extent that they solve more problems than they create.</p>
<p>There are many benefits to applying this concept, which is often called modularity, (or as I prefer, Separation of Concerns, or SOC). I am aware that some of you reading this might think I am just copying what Leland said in his article, but I have been talking about SOC as the Golden Principle Of Software Architecture for <a target="_blank" href="https://rkay301.medium.com/programming-fundamentals-part-5-separation-of-concerns-software-architecture-f04a900a7c50">many years already</a>.</p>
<p>Where this plays into Compose, is the same principle which we see in the popular Javascript library <strong>React</strong>. When done properly, Compose will only “recompose” (redraw, re-render, update, whatever) the Composables (parts/elements of the UI) which need to be recomposed.</p>
<p>This is ENORMOUSLY important when it comes to the performance of an application. This is because redrawing the UI, whether in the old View system or in Compose, is costly for system resources.</p>
<p>In case you were not aware, the entire purpose of the old RecyclerView (which was the first thing I ever made a tutorial on back in 2016!) was to employ the ViewHolder pattern to a list of data. This avoided the need to constantly inflate (make) new Views for each list item.</p>
<p>My goal in this article was to focus mostly on the theory, as I will be writing plenty of practical content over the next few months. However, I will finish the article off with a story from my direct experience, which will help you to further understand how recomposition works, and <strong>how to avoid doing it very poorly!</strong></p>
<h1 id="heading-the-stopwatch-example">The Stopwatch Example</h1>
<p>For my first full Compose application, I decided to build Sudoku. There are a number of reasons why, including the fact that I wanted a project which did not have an insanely complicated UI. I also wanted the chance to deep dive into Graph DS and Algos, which are quite suitable for Sudoku puzzles.</p>
<p>One thing I wanted was a Stopwatch which would keep track of how long it took the user to complete a puzzle:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/image-27.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Graph Sudoku puzzle</em></p>
<p>As is often the case in my profession, I expected this timer to be much easier to add than it really was. I messed around with Android’s Chronometer class as well as the Java Timer class, and both of them presented different but still application-breaking problems.</p>
<p>Eventually I took a step back and realized that I was writing in Kotlin. So I set up a Coroutine based timer in my presentation logic class (it ended up making the most sense to put it there), which would update my viewmodel each second:</p>
<pre><code class="lang-kotlin">Class ActiveGameLogic(…):…{
<span class="hljs-comment">//…</span>
<span class="hljs-keyword">inline</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">startCoroutineTimer</span><span class="hljs-params">(
    delayMillis: <span class="hljs-type">Long</span> = <span class="hljs-number">0</span>,
    repeatMillis: <span class="hljs-type">Long</span> = <span class="hljs-number">1000</span>,
    <span class="hljs-keyword">crossinline</span> action: () -&gt; <span class="hljs-type">Unit</span>
)</span></span> = launch {
    delay(delayMillis)
    <span class="hljs-keyword">if</span> (repeatMillis &gt; <span class="hljs-number">0</span>) {
        <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
            action()
            delay(repeatMillis)
        }
    } <span class="hljs-keyword">else</span> {
        action()
    }
}
<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">onStart</span><span class="hljs-params">()</span></span> =
launch {
    gameRepo.getCurrentGame(
    { puzzle, isComplete -&gt;
        viewModel.initializeBoardState(
            puzzle,
            isComplete
    )
        <span class="hljs-keyword">if</span> (!isComplete) timerTracker = startCoroutineTimer {
            viewModel.updateTimerState()
        }
    },{
        container?.onNewGameClick()
    })
}
<span class="hljs-comment">//…</span>
}
</code></pre>
<p>The ViewModel (not from AAC – I write my own VMs. But Compose already has good interoperability with AAC VMs from what I can see.) exposed references to callback functions, which is what I would use to update my Composables:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ActiveGameViewModel</span> </span>{
    <span class="hljs-comment">//…</span>
    <span class="hljs-keyword">internal</span> <span class="hljs-keyword">var</span> subTimerState: ((<span class="hljs-built_in">Long</span>) -&gt; <span class="hljs-built_in">Unit</span>)? = <span class="hljs-literal">null</span>
    <span class="hljs-keyword">internal</span> <span class="hljs-keyword">var</span> timerState: <span class="hljs-built_in">Long</span> = <span class="hljs-number">0L</span>
    <span class="hljs-comment">//…</span>
    <span class="hljs-keyword">internal</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">updateTimerState</span><span class="hljs-params">()</span></span>{
        timerState++
        subTimerState?.invoke(timerState)
    }
<span class="hljs-comment">//…</span>
}
</code></pre>
<p><strong>Now comes the important part!</strong> We can trigger recomposition of the Compose Hierarchy by using certain features of compose, such as the <code>remember</code> function:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">var</span> timerState <span class="hljs-keyword">by</span> remember {
    mutableStateOf(“”)
}
</code></pre>
<p>If you must know, these features store the state of whatever you are remembering in the <code>slotTable</code>. In short, the word state here means the current “state” of the data, which starts out being just an empty String.</p>
<p><strong>Here is where I screwed things up</strong>. I had pulled my simple timer composable into its own function (applied SOC), and I was passing in <code>timerState</code> as a parameter to that composable.</p>
<p>However, the above snippets were sitting in the parent composable of the timer, which was a container for the most complicated portion of the UI (a 9x9 Sudoku requires a large number of widgets):</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Composable</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">GameContent</span><span class="hljs-params">(
    onEventHandler: (<span class="hljs-type">ActiveGameEvent</span>) -&gt; <span class="hljs-type">Unit</span>,
    viewModel: <span class="hljs-type">ActiveGameViewModel</span>
)</span></span> {
    Surface(
        Modifier
            .wrapContentHeight()
            .fillMaxWidth()
    ) {
        BoxWithConstraints(Modifier.background(MaterialTheme.colors.primary)) {
            <span class="hljs-comment">//…</span>
            ConstraintLayout {
                <span class="hljs-keyword">val</span> (board, timer, diff, inputs) = createRefs()
                <span class="hljs-keyword">var</span> isComplete <span class="hljs-keyword">by</span> remember {
                    mutableStateOf(<span class="hljs-literal">false</span>)
                }
                <span class="hljs-keyword">var</span> timerState <span class="hljs-keyword">by</span> remember {
                    mutableStateOf(<span class="hljs-string">""</span>)
                }
                viewModel.subTimerState = {
                    timerState = it.toTime()
                }
                viewModel.subIsCompleteState = { isComplete = it }
            <span class="hljs-comment">//…Sudoku board</span>
            <span class="hljs-comment">//Timer</span>
                Box(Modifier
                    .wrapContentSize()
                    .constrainAs(timer) {
                        top.linkTo(board.bottom)
                        start.linkTo(parent.start)
                    }
                    .padding(start = <span class="hljs-number">16</span>.dp))
                {
                    TimerText(timerState)
                }
            <span class="hljs-comment">//…difficulty display</span>
            <span class="hljs-comment">//…Input buttons</span>
            }
        }
    }
}
<span class="hljs-meta">@Composable</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">TimerText</span><span class="hljs-params">(timerState: <span class="hljs-type">String</span>)</span></span> {
    Text(
        text = timerState,
        style = activeGameSubtitle.copy(color = MaterialTheme.colors.secondary)
    )
}
</code></pre>
<p>This was causing some considerable lag and unresponsiveness. By making heavy usage of the debugger, I was able to find out why. Because my <code>timerState</code> variable was created and updated inside the parent Composable, it was triggering a recomposition of that entire portion of the UI. <strong>Every. Single. Tick.</strong></p>
<p>After moving the appropriate code into the <code>TimerText</code> composable, things worked very smoothly:</p>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Composable</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">TimerText</span><span class="hljs-params">(viewModel: <span class="hljs-type">ActiveGameViewModel</span>)</span></span> {
    <span class="hljs-keyword">var</span> timerState <span class="hljs-keyword">by</span> remember {
        mutableStateOf(<span class="hljs-string">""</span>)
    }

    viewModel.subTimerState = {
        timerState = it.toTime()
    }

    Text(
        text = timerState,
        style = activeGameSubtitle.copy(color = MaterialTheme.colors.secondary)
    )
}
</code></pre>
<p>Hopefully I have given you a working understanding of recomposition and one of the biggest ways to do it incorrectly.</p>
<p>Avoiding unnecessary recompositions is incredibly important for performance. And so far it seems that applying SOC rigorously, even to the point of keeping remember state in separate composables, should become standard practice.</p>
<h1 id="heading-resources-amp-support">Resources &amp; Support</h1>
<p>If you liked this article, please share it on social media and check out my other articles on <a target="_blank" href="https://www.freecodecamp.org/news/author/ryan-michael-kay/">freeCodeCamp here</a>. I also have a <a target="_blank" href="https://youtube.com/wiseass">YouTube channel</a> with hundreds of tutorials, and am an active writer on various platforms.</p>
<h3 id="heading-connect-with-me-on-social-media">Connect with me on social media</h3>
<p>You can find me on <a target="_blank" href="https://www.instagram.com/rkay301/">Instagram here</a> and on <a target="_blank" href="https://twitter.com/wiseAss301">Twitter here</a>.</p>
<p>Also, I want to point out the single resource I used to get started with Jetpack Compose: <a target="_blank" href="https://github.com/android/compose-samples">Working code samples from good developers</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ ADB Android Install Guide: Drivers and Commands ]]>
                </title>
                <description>
                    <![CDATA[ In this article, we will explore how you can use the ADB to gain some fine-grained control when you're installing, testing, diagnosing, and managing one or more devices and emulators. For my first few years as a software developer, primarily working ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/adb-android-install-guide-drivers-and-commands/</link>
                <guid isPermaLink="false">66d460c5a326133d12440a5b</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ android app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Android Studio ]]>
                    </category>
                
                    <category>
                        <![CDATA[ command line ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ryan Michael Kay ]]>
                </dc:creator>
                <pubDate>Thu, 18 Feb 2021 16:48:06 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/60297d780a2838549dcc57f3.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, we will explore how you can use the ADB to gain some fine-grained control when you're installing, testing, diagnosing, and managing one or more devices and emulators.</p>
<p>For my first few years as a software developer, primarily working with the Android SDK, I had no idea of what the Android Debug Bridge (ADB/adb) was, what it did, or when to use it.</p>
<p>Amusingly, it was not some professional goal which motivated me to learn about it initially. Rather it was my boot looping Nexus 6 which I desperately wanted to resurrect. For a problem like that, Android Studio and Gradle are about as useful as a waterproof tea bag.</p>
<p>I would also like to mention that this article has been written with <strong>two kinds of individuals in mind</strong>:</p>
<ul>
<li><p>Those who are familiar with CLI, Shell, Processes, and the Client-Server Model</p>
</li>
<li><p>Those who are not familiar with CLI, Shell, Processes, and the Client-Server Model</p>
</li>
</ul>
<p>For those in the first category, you may wish to skip the section titled: "<strong>How to Work With The ADB</strong>."</p>
<p>For those in the second category, I will assume you were like me as a Junior developer and know very little about CLIs, Shells, and the ADB. The first section is a soft introduction and glossary for some basic terms and ideas, explained in the simplest way I can manage.</p>
<h2 id="heading-preliminaries">Preliminaries</h2>
<p>Here, we will learn about some topics which are important if you want to understand how the ADB works and is used.</p>
<p>Some of you may have been scared away from learning command line tools in the past by sneering Vim enthusiasts or judgmental Unix System Administrators. As you will see, I freely admit that CLI is not ideal for how my brain works, so I think you might enjoy my take on the subject.</p>
<h3 id="heading-command-line">Command Line</h3>
<p>Simply put, a command line is an interface (way of sending/receiving information) to a computer which <strong>only uses lines of text</strong>.</p>
<p>It is important to understand that a command line interface (CLI) is not itself a program, but rather some programs will provide a CLI (and perhaps other interfaces such as a GUI as well).</p>
<p>At some point, you may have typed something into Windows Command Prompt (or MS-DOS if you are a 90s kid like me), Mac Terminal, or something like GNOME Terminal common on many Linux distributions. All of these are primarily used via a CLI.</p>
<p>The benefits and deficits of using a CLI depend largely on the individual using it, and what kind of problem they are trying to solve. <strong>I personally do not like using a CLI unless it is for something that I do almost every day</strong>.</p>
<p>My brain is simply not suited for memorizing obscure shorthand text commands (I had trouble learning to read as a kid for the same reason), so I must rely on a great deal of repetition-based implicit memory (muscle memory) and cheat sheets.</p>
<p>For those who are willing to put the time in even if it is a struggle (like I do), or those who are really quite good at remembering such things, <strong>you will likely learn to appreciate how much more efficient you can be within a CLI versus a GUI</strong>.</p>
<p>Many operations can be carried out in a fraction of the time it takes to point and click your way through various menus and screens. It is also possible to write scripts, which are files containing a series of text commands, that can increase your efficiency even further.</p>
<h3 id="heading-how-to-use-the-abd-shell">How to use the ABD Shell</h3>
<p>I will have to assume that you are familiar with the term Operating System (OS), which includes Android, iOS, Windows, Mac, Linux, and any other Unix-like system.</p>
<p>Why is this term relevant to the ADB? To give an explanation which prioritizes clarity over precision, the Android OS is based on Linux, and Linux is based on Unix.</p>
<p>As a result of this, we can use the ADB to get a hold of the Unix Shell for the device or emulator we are working with. This allows us a great deal of flexibility, capabilities, and control over the device or emulator by directly interacting with its shell.</p>
<p>A shell is a general term for the program which you use to interact with an OS. Just as a turtle shell provides protection and access to a turtle (and is the outermost layer), the shell of an OS both protects and provides access to the inner workings of the OS. Personally, I was quite surprised to learn that "Shell" was not some esoteric acronym.</p>
<p>Do not feel the need to overthink this term. If you are reading this on a computer of some kind, you used a shell to help you get here.</p>
<p>A shell can provide either or both a CLI or GUI. In either case you will use it to create/update/delete/move files, start other programs, and access the various services of the OS which are made available through the shell.</p>
<h3 id="heading-how-to-use-the-abd-client-and-abd-server">How to use the ABD Client and ABD Server</h3>
<p>Again, let us start with a slightly imprecise explanation which is hopefully easier to understand. I will correct this definition shortly, though.</p>
<p>Clients and Servers are both computers. The reason why we differentiate them in this way is based on their <strong>role</strong>. For example, your computer (whether it is a desktop, laptop, phone, or whatever else) is a Client of a freeCodeCamp Server, which <strong>serves</strong> you this HTML page.</p>
<p>In general, a client is <strong>something which uses something else</strong>, whereas a server is <strong>that which is being used</strong>. Do not overthink this term, as a Client-Server Model can describe a very large number of things both inside and outside of computing.</p>
<p>Now, when I said that Clients and Servers are both “computers”, that is not really true in the context that we will use these terms later on.</p>
<p>As programmers and engineers, we typically ought to think of Clients and Servers as being processes (<strong>a process is simply a running program</strong>).</p>
<p>This means that while a Client process and a Server process often do run on separate computers, it is also fine if they run on the same computer.</p>
<p>They will occupy distinct locations in the memory space of said computer, so effectively the only difference is that they will communicate using IPC (inter-process communication) as opposed to sending messages to each other through a network connection.</p>
<p>As we will see shortly, the ADB makes use of a Server process, which allows multiple developers (multiple clients) to manage multiple Android devices and/or emulators.</p>
<p>In an enterprise setting, this Server process would likely sit on a remote (communicated to through a network connection) computer, but we will set up a Server which is local to our Client. Doing that will be much simpler than you probably think it will be.</p>
<h3 id="heading-what-is-an-abd-daemon">What is an ABD Daemon?</h3>
<p>In case you skipped ahead, I already explained that a process is simply a running program. A Daemon is a process which runs in the background, which is to say that the user does not directly interact with it.</p>
<p>For example, if you open a web browser, then chances are that the actual work of managing the network connections required to connect to the Internet will be carried out by something like a NetworkManager Daemon (as opposed to the browser process itself).</p>
<p>Each Android device (physical or emulated), assuming it is configured properly, will have an ADB Daemon (adbd) which executes commands given to it by a Server process.</p>
<p>In short, when our Client issues a command to the Server, the Server will forward that command to the ADBD, which will execute it on the device.</p>
<h2 id="heading-how-to-use-adb-for-android-development">How to Use ADB for Android Development</h2>
<p>For the remainder of this article, we will explore the following topics:</p>
<ul>
<li><p>Drivers and configuration necessary to use the ADB on your system</p>
</li>
<li><p>Using the ADB with physical devices and emulators</p>
</li>
<li><p>Basic commands using the ADB’s CLI</p>
</li>
<li><p>A glance at more complicated usage using an Android device’s Shell via the ADB</p>
</li>
</ul>
<p>Before proceeding, you will want to establish what CLI tool you will be using to interact with the ADB. On Windows, I prefer using PowerShell, but Command Prompt would work too. For Linux and Mac, the default Terminal should work.</p>
<p>Feel free to use whatever gets the job done.</p>
<p>This article contains a very detailed explanation of the whole process, but I have prepared a video tutorial which covers it succintly here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/g___gGA9jn8" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h3 id="heading-how-to-understand-the-cli-examples">How To Understand The CLI Examples</h3>
<p>This article contains many commands to be inputted to your preferred CLI tool. Any part of a given command which changes situationally will be written within angle brackets.</p>
<p><strong>Do not include the angle brackets in the CLI command you write.</strong></p>
<p>For example, if I wrote...:</p>
<p><code>adb pair &lt;ip-address&gt;:&lt;port&gt;</code></p>
<p>...you would substitute the angle brackets and name for the actual value, such as:</p>
<p><code>adb pair 192.168.0.1:5554</code></p>
<h3 id="heading-abd-drivers-amp-configuration">ABD Drivers &amp; Configuration</h3>
<p>Firstly, ensure that you have the latest (or at least a recent) version of the <a target="_blank" href="https://developer.android.com/studio/releases/platform-tools">Android SDK Platform-Tools</a>. If for some reason you do not use Android Studio (AS), click that link and download the standalone package for your respective OS.</p>
<p>If you have Android Studio, you can download or update this package using the SDK Manager.</p>
<p>There is typically a toolbar icon in AS to open the SDK Manager, but they like to change what it looks like practically every hotfix.</p>
<p>If you do not have luck finding it, go to <strong>File -&gt; Settings</strong> and in the search bar, type “SDK”, and search for the “Android SDK” menu item.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/as_sdk_manager.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Systems setting showing that Android SDK Platform Tools are installed</em></p>
<p>The next step changes depending on a number of variables. As discussed in the <strong>Preliminaries</strong> section, the ADB uses a Client-Server Model which allows a lot of flexibility in how you use the tool.</p>
<p>To be more specific, you may have:</p>
<ul>
<li><p>Multiple Clients interacting with a remote Server</p>
</li>
<li><p>A Server which is local (same computer) to one Client</p>
</li>
<li><p>A variety of physical devices and emulators hooked up to the same server</p>
</li>
</ul>
<p>Advanced configuration with multiple Clients and an exceedingly large number of devices is possible with the ADB, but outside of the scope of this article.</p>
<p>One Server can manage up to 16 emulators and as many physical devices as you would like (within reason), without requiring advanced configuration.</p>
<p>For the remainder of this article, the most we will work with is one physical device and one emulator for a single ADB server process.</p>
<h4 id="heading-how-to-configure-an-abd-emulator">How to Configure An ABD Emulator</h4>
<p>Most likely you do not need to make any further configurations, but it is possible you may need to enable <strong>Developer Options</strong> on your emulator. You will know very shortly if it is working properly when we get to our first few ADB commands.</p>
<p>If you do wish to enable this feature on your emulator, you will need to <a target="_blank" href="https://developer.android.com/studio/debug/dev-options">research</a> how to do that for your particular version of Android.</p>
<h3 id="heading-usb-debugging-how-to-configure-a-physical-device">USB Debugging – How to Configure a Physical Device</h3>
<p>If you are not planning to use a physical Android device, you can skip this section. However, it is worth noting that you may still need to enable Developer Options</p>
<p>In order to proceed, you will need to configure either USB Debugging or WiFi Debugging on your Android device and development machine.</p>
<p>In either case, start by enabling <strong>Developer Options</strong> on your device. You will need to <a target="_blank" href="https://developer.android.com/studio/debug/dev-options">research</a> how to do that for your particular version of Android.</p>
<h4 id="heading-usb-debugging">USB Debugging</h4>
<p>Ensure that you have enabled USB Debugging on the Android device via Developer Options. The link I shared above will describe that process, which tends to change somewhat across different versions of the Android OS.</p>
<p>Before proceeding, Windows users will need to <a target="_blank" href="https://developer.android.com/studio/run/oem-usb">download a USB Driver</a>. Ubuntu users also <a target="_blank" href="https://developer.android.com/studio/run/device">require some extra steps</a>. For Mac and Chrome OS, you should be good to go.</p>
<p>Once USB Debugging is enabled via Developer Options, connect your Android device via a USB cable.</p>
<h4 id="heading-wifi-debugging">WiFi Debugging</h4>
<p>If you happen to have multiple physical devices or a shortage of USB cables, then you may want to opt for WiFi Debugging.</p>
<p>Again, visit Developer Options on your Android device and enable Wireless debugging. It should prompt you about Allowing debugging on the network which the device is currently connected to, which you should allow (assuming that is the appropriate network).</p>
<p><strong>Time to start working with your CLI</strong>. First, you will need to locate the platform-tools directory (or folder – same thing) within your Android SDK installation directory.</p>
<p>Assuming you have Android Studio installed, a quick way to locate it via the app is to again go to File -&gt; Settings, then type “SDK” in the search bar. The “Android SDK” menu will show you where your SDK is installed, which will be the directory that should contain platform-tools.</p>
<p>In the example below, <strong>I copied the path to my Android SDK directory</strong>, and then opened an instance of Windows PowerShell. I then typed the following commands:</p>
<p><strong>Change Directory:</strong></p>
<pre><code class="lang-pgsql">cd &lt;<span class="hljs-type">path</span>-<span class="hljs-keyword">to</span>-SDK-directory&gt;
</code></pre>
<p><strong>List Files and Directories:</strong></p>
<pre><code class="lang-pgsql">ls
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/power_shell_cd_ls.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Next, I typed <code>cd platform-tools</code> to navigate to that directory. Note that the following steps assume you are using a device which is running Android OS 11 or higher.</p>
<p>If you are working with a device running Android 10 or lower, detailed instructions for that situation can be <a target="_blank" href="https://developer.android.com/studio/command-line/adb#wireless">found here</a>.</p>
<p>Once you are within the platform-tools directory, you are ready to pair an Android device to a development machine using the following steps:</p>
<ol>
<li><p>Within the Wireless debugging submenu in Settings -&gt; System -&gt; Developer options, select <strong>Pair device with pairing code</strong>.</p>
</li>
<li><p>Within your CLI tool which should be set to the platform-tools directory, enter the following command:</p>
</li>
</ol>
<p><code>adb pair &lt;IP address&gt;:&lt;Port&gt;</code></p>
<p>where both the IP address and the Port come from the dialogue on your Android device which popped up after selecting <strong>Pair device with pairing code</strong> (do not include the angle brackets).</p>
<p><strong>Note: You may need to prepend your call to adb with some other symbols or commands depending on which CLI tool you are using, your OS, and your access controls.</strong> For example, I had to type .\adb pair : using PowerShell on Windows.</p>
<ol start="3">
<li><p>Assuming things went well with your CLI, you will be prompted to enter the pairing code which was made visible in the same dialog on the Android device which gave you the IP address and Port number.</p>
</li>
<li><p>After entering the pairing code, you will know this operation was successful if you receive a message stating:</p>
</li>
</ol>
<p><code>Successfully paired to &lt;IP Address&gt;:&lt;Port&gt; [guid=&lt;Some GUID&gt;]</code></p>
<ol start="5">
<li>If you are using Windows or Linux, you will also need to run the following command using the IP Address &amp; Port which is visible from within the Wireless debugging preferences menu (not the dialogue which pops up after selecting Pair device with pairing code):</li>
</ol>
<p><code>adb connect &lt;IP Address&gt;:&lt;Port&gt;</code></p>
<p>after which you should receive a notification on the phone to indicate that you are connected.</p>
<h3 id="heading-how-to-use-the-adb-commands">How to Use The ADB: Commands</h3>
<p>Assuming you managed to properly configure your Android device and your development machine, you can now use the ADB tool.</p>
<p>Before proceeding, navigate to the directory which contains adb using a CLI tool (unless you just followed the steps in the previous section for setting up WiFi debugging).</p>
<p>Otherwise do so now, or check out that section for instructions on how to locate that folder.</p>
<h4 id="heading-how-to-see-which-devices-are-currently-connected-to-the-server">How to See Which Devices Are Currently Connected To The Server</h4>
<p>You can now start up an adb server by calling just about any command on the ADB except <code>adb kill-server</code>. Whether or not your server process is running, type in the following command:</p>
<p><code>adb devices</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/pwershell_devices-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In the above screenshot, I first called <code>adb devices</code> when my Android phone was connected to the server. After killing the server via the <code>adb kill-server</code> command, I once again called devices which restarted the server.</p>
<p>Again, if an ADB server is not currently running, <strong>calling more or less any ADB command will start the server back up</strong> (except <code>adb kill-server</code>, of course). There is an explicit <code>adb start-server</code> command, but in practice I have never needed to use it.</p>
<p>Since the server was reset, devices did not return any items. Therefore, before moving to the next example I had to once again use the <code>adb pair</code> and <code>adb connect</code> (if on Windows or Linux) commands described in the previous section.</p>
<p>I have now fired up an emulator using PowerShell and the emulator program which is also located in a subdirectory of platform-tools called "emulator."</p>
<p>You may of course use the AVD Manager or Android Studio to start up an emulator to follow along with the example if you would like to.</p>
<p>If you have many connected devices, a useful option for the <code>adb devices</code> command is <code>-l</code>, which gives you more information about the devices.</p>
<p>Below you will see several entries which refer to my physical Android device, as well as an emulator which has been attached to a specific port:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/powershell_devices_list-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h4 id="heading-how-to-send-commands-to-a-specific-device">How to Send Commands To A Specific Device</h4>
<p>To avoid accidentally bricking my phone, I want to send commands to the emulator instead. To do this, I must prepend the <code>-s</code> option, followed by the serial number of the target device, before typing the command.</p>
<p>The serial number is the first set of characters which describes a connected device after using the devices command.</p>
<p>For example, the emulator’s serial number in this case is just the word emulator followed by the port which the emulator is currently attached to.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/powershell_devices_serial-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The other red arrow points to the serial number for my phone (blocked out for obvious reasons).</p>
<p>Naturally, if you only have one device connected (whatever kind it is), you do not need to use the <code>-s</code> option.</p>
<h4 id="heading-install-an-apk-app-on-a-device">Install An APK (App) On A Device</h4>
<p>I am now going to install a test APK on the running emulator using the <code>adb install</code> command.</p>
<p>This is basically equivalent to having Android Studio and Gradle install a debug APK. As you will see, test APKs require the <code>-t</code> option after the install command:</p>
<p><code>adb -s &lt;device-serial-number&gt; install -t &lt;path-to-APK&gt;</code></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/powershell_install_test_apk.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Note: The Android OS requires that any APK must be signed before it can be installed</strong> (even if it is just a test/debug APK).</p>
<p>One solution is to build and run the app to be installed in Android Studio, which will sign it with a generated debug certificate. There are several other ways to sign such an APK which you can explore by visiting this <a target="_blank" href="https://developer.android.com/studio/publish/app-signing#debug-mode">link</a>.</p>
<h4 id="heading-what-else-can-adb-do">What Else Can ADB Do?</h4>
<p>Before we take a look at some more advanced usage of the ADB, I strongly encourage you to try the <code>adb --help</code> command. As is customary for most CLI based programs, the help command will print out documentation which describes the various commands and options of the tool.</p>
<p>I am happy to say that the documentation for the ADB is quite legible and useful, which is not always the case in CLI programs.</p>
<h2 id="heading-advanced-adb-usage-tips">Advanced ADB Usage Tips</h2>
<p>It would be a waste of time for both of us to cover every usage and command of the ADB in this article.</p>
<p>In case there is any confusion, using the ADB to install APKs and do many of the things which Android Studio and Gradle do for you is not something that I would recommend (unless you have a good reason to do so).</p>
<p>With that being said, there are plenty of things that the ADB can do which are either difficult or impossible to do without it.</p>
<p>In the preliminaries section, I mentioned that the ADB can be used to get a hook to the shell of the device. To finish this article off, we will look at how to use shell commands and where to find more information about them.</p>
<p>If you do not know what a shell is, you probably skipped the section above where I explained that.</p>
<h3 id="heading-how-to-use-the-abd-shell-1">How to Use the ABD Shell</h3>
<p>Sending a command to the device’s shell using the ADB is fairly simple. Remember that if you have multiple devices connected, follow it with <code>-s &lt;device-serial-number&gt;</code> to direct the command to a specific device.</p>
<p>To make a single shell command, we must use the <code>adb shell</code> command (big surprise, eh?), followed by the actual command we want to make on the device's shell:</p>
<p><code>adb shell ls</code></p>
<p>Output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/powershell_shell_ls.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>As mentioned previously, the <code>ls</code> command displays a list of files and directories at the CLI's current directory. This happens to be the Android device's root directory until we move to a different one.</p>
<p>If you plan to be making many commands via the Shell, you can also start an interactive Shell session. This can be done via the simple command:</p>
<p><code>adb shell</code></p>
<p>While in an interactive Shell session, you can type Shell commands directly without further use of <code>adb shell &lt;command&gt;</code>.</p>
<p>Note that when you want to quit the interactive Shell session, you can do so by typing <code>exit</code> or hitting Ctrl + D.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/powershell_start_interactive_shell.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>There are a variety of different commands and utilities you can work with via the Shell. The ActivityManager (<code>am</code>) of an Android device can be particularly useful for testing different components (Activities, Services, BroadcastReceivers, to name a few) of an Android app under different circumstances.</p>
<p>Suppose we want to launch straight into a particular Activity, but this Activity is not designated as the launcher Activity in the manifest.</p>
<p>You will still need to add the <code>android:exported=”true”</code> attribute to each <code>&lt;activity/&gt;</code> entry in the manifest which you want to launch (assuming it is not already the launcher Activity).</p>
<p>After that you can use the following command to go straight to it:</p>
<p><code>am start -n &lt;app-package-id&gt;/&lt;activity-name&gt;</code></p>
<p>Note that the <code>&lt;activity-name&gt;</code> must include whichever packages, relative to the package-id, within which it is located. See the output below for an example of launching an Activity which sits within several packages.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/powershell_shell_start.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-further-reading">Further Reading</h3>
<p>My goal in this article was to do my best to introduce, explain, and guide you through the usage of the ABD in my own words (insofar as that is possible).</p>
<p>At this point I would need to start making some very contrived examples or to simply carbon copy the documentation, neither of which are things that I am interested in doing.</p>
<p>Instead, I would like to encourage you to visit the <a target="_blank" href="https://developer.android.com/studio/command-line/adb#shellcommands">documentation</a>, and to have a brief look at some of the cool things you can do using tools like the Activity Manager, Package Manager, Policy Manager, and others.</p>
<h4 id="heading-you-can-get-in-touch-with-me-on-social-media-here"><strong>You can get in touch with me on social media here:</strong></h4>
<p><a target="_blank" href="https://www.instagram.com/wiseassbrand/">https://www.instagram.com/rkay301/</a><br><a target="_blank" href="https://www.facebook.com/wiseassblog/">https://www.facebook.com/wiseassblog/</a><br><a target="_blank" href="https://twitter.com/wiseass301">https://twitter.com/wiseass301</a><br><a target="_blank" href="http://wiseassblog.com/">http://wiseassblog.com/</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Model-View-ViewModel on Android Like a Pro ]]>
                </title>
                <description>
                    <![CDATA[ My goal in this article is to explain why the Model-View-ViewModel architectural pattern presents a very awkward separation of concerns in some situations with regard to the presentation logic of a GUI architecture. We will explore two variants of MV... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/model-view-viewmodel-android-tutorial/</link>
                <guid isPermaLink="false">66d460d1787a2a3b05af43fc</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ android app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mvp ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software architecture ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ryan Michael Kay ]]>
                </dc:creator>
                <pubDate>Mon, 28 Dec 2020 15:21:14 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5fe0dcbae6787e098394168f.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>My goal in this article is to explain why the Model-View-ViewModel architectural pattern presents a very awkward separation of concerns in some situations with regard to the presentation logic of a GUI architecture.</p>
<p>We will explore two variants of MVVM (there is <strong>not</strong> just one way to do it), and the reasons why you may prefer one variant over another, based on project requirements.</p>
<h2 id="heading-mvvm-vs-mvpmvc">MVVM vs MVP/MVC?</h2>
<p>It is quite likely that the most common question I am asked during my live Sunday Q&amp;A sessions, is something like:</p>
<blockquote>
<p>MVVM vs MVP/MVC?</p>
</blockquote>
<p>Whenever I am asked this question, I am quick emphasize the idea that no single GUI architecture works great in all situations.</p>
<p>Why, you may ask? The best architecture (or at least a good choice) for a given application depends strongly on the requirements at hand.</p>
<p>Let us briefly think about what this word <strong>requirements</strong> actually means:</p>
<ul>
<li><p><strong>How complex is your UI?</strong> A simple UI does not generally require complex logic to coordinate it, whereas a complex UI may require extensive logic and fine-grained control to work smoothly.</p>
</li>
<li><p><strong>How much do you care about testing?</strong> Generally speaking, classes which are tightly coupled to frameworks and the OS (especially the <strong>user interface</strong>) require extra work to test.</p>
</li>
<li><p><strong>How much re-usability and abstraction do you wish to promote?</strong> What if you want to share the back end, domain, and even presentation logic of your application across different platforms?</p>
</li>
<li><p>Are you by nature <strong>pragmatic</strong>, <strong>perfectionist</strong>, <strong>lazy</strong>, or all of the above at different times, in different situations?</p>
</li>
</ul>
<p>I would love to write an article where I discuss in fine detail how MVVM works with respect to the requirements and concerns listed above. Unfortunately, some of you have likely been mislead into thinking that there is only one way to do MVVM.</p>
<p>Instead, I will discuss two different approaches to the general idea of MVVM which present very distinct benefits and disadvantages. But first, let us start with the general idea.</p>
<h2 id="heading-thou-shalt-not-reference-thy-view-classes">Thou Shalt Not Reference Thy View Classes</h2>
<p><em>For my friends who cannot read old English:</em> “<strong>You may not reference view classes</strong>."</p>
<p>Apart from using the name ViewModel (which itself is confusing if the class is full of <strong>logic</strong>), the one iron-clad rule of MVVM architecture is that you may never reference a View, from ViewModel.</p>
<p>Now, the first area of confusion can arise from this word “reference,” which I will restate using several different levels of jargon:</p>
<ul>
<li><p>Your ViewModels may not possess any references (member variables, properties, mutable/immutable fields) to any Views</p>
</li>
<li><p>Your ViewModels may not depend on any Views</p>
</li>
<li><p>Your ViewModels may not talk directly to your Views</p>
</li>
</ul>
<p>Now, on the Android platform, the reason for this rule is not simply that breaking it is bad because someone who seems to know about software architecture told you it is bad.</p>
<p>When using the <a target="_blank" href="https://developer.android.com/topic/libraries/architecture/viewmodel">ViewModel</a> class from Architecture Components (which is designed to have its instance <strong>persist</strong> longer than the Fragment/Activity lifecycle <strong>when appropriate</strong>), referencing a View is asking for <strong>SERIOUS MEMORY LEAKS</strong>.</p>
<p>As for why MVVM in general does not allow such references, the goal is <strong>hypothetically</strong> to make both the View and the ViewModel easier to test and write.</p>
<p>Others may also point out that it promotes reusability of ViewModels, but this is <strong>exactly where things break down with this pattern</strong>.</p>
<p>Before we look at the code, please note that <strong>I personally do not use LiveData</strong> in my own production code. I prefer to write my own Publisher-Subscriber Pattern these days, but what I say below applies to any library which allows for the PubSub/Observer Pattern link from the ViewModel to the View.</p>
<p>This article is accompanied by a video tutorial covering many of the same ideas here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/j47CSoJ_Hc4" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-viewlogic-viewmodel-or-view-viewmodelcontroller">ViewLogic + ViewModel or View + ViewModelController?</h2>
<p>When I said “break down” in the previous section, I do not mean to say that the pattern literally breaks. I mean that it breaks down into (at least) two different approaches which have very distinct appearances, benefits, and consequences.</p>
<p>Let us consider these two approaches, and when you may wish to prefer one over the other.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/1_TfbPt5-CcYCjDu2hapFXNg.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Boromir explains that MVVM is not a magic wand that makes your application's presentation logic disappear.</em></p>
<h3 id="heading-first-approach-prioritize-reusable-viewmodels">First Approach: Prioritize Reusable ViewModels</h3>
<p>As far as I can tell, most people who implement MVVM make it a goal to promote re-usability of ViewModels, so that they may be reused for <em>n</em> number of different Views (many-to-one ratio).</p>
<p>In simple terms, there are two ways you can achieve this re-usability:</p>
<ul>
<li><p>By not referencing a specific View. Hopefully this is not news to you at this point.</p>
</li>
<li><p>By <strong>knowing</strong> as little as possible about the details of the <strong>UI</strong> in general</p>
</li>
</ul>
<p>The second point may sound vague or counter-intuitive (how can it know anything about something which it does not reference?), so I think it is time to look at some code:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NoteViewModel</span></span>(<span class="hljs-keyword">val</span> repo: NoteRepo): ViewModel(){
    <span class="hljs-comment">//Note: you may also publish data to the View via Databinding, RxJava Observables, and other approaches. Although I do not like to use LiveData in back end classes, it works great with Android front end with AAC</span>
    <span class="hljs-keyword">val</span> noteState: MutableLiveData&lt;Note&gt;()
    <span class="hljs-comment">//...</span>
    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">handleEvent</span><span class="hljs-params">(event: <span class="hljs-type">NoteEvent</span>)</span></span> {
        <span class="hljs-keyword">when</span> (event) {
            <span class="hljs-keyword">is</span> NoteEvent.OnStart -&gt; getNote(event.noteId)
            <span class="hljs-comment">//...</span>
        }
    }
    <span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getNote</span><span class="hljs-params">(noteId: <span class="hljs-type">String</span>)</span></span>{
        noteState.value = repo.getNote(noteId)
    }
}
</code></pre>
<p>While this is a very simplified example, the point is that the only thing which this particular ViewModel exposes publicly (other than the handleEvent function), is a simple Note object:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Note</span></span>(<span class="hljs-keyword">val</span> creationDate:String,
                <span class="hljs-keyword">val</span> contents:String,
                <span class="hljs-keyword">val</span> imageUrl: String,
                <span class="hljs-keyword">val</span> creator: User?)
</code></pre>
<p>With this particular approach, the ViewModel is well and truly decoupled from not just a particular View, but also the details, and by extension, <strong>presentation logic</strong> of any particular View.</p>
<p>If what I am saying still seems vague, I promise it will be clear once I describe the other approach.</p>
<p>Although my earlier heading, “<strong>ViewLogic + ViewModel…</strong>” is not meant to be used or taken seriously, I mean that by having very decoupled and re-usable ViewModels, we are now depending on the View itself to do the work of figuring out how to render/bind this Note object on screen.</p>
<p><strong>Some of us do not like filling View classes with Logic.</strong></p>
<p>This is where things get very muddy and dependent on project <strong>requirements</strong>. I am not saying that filling View classes with logic such as…:</p>
<pre><code class="lang-pgsql">private fun observeViewModel() {
    viewModel.notes.observe(
        viewLifecycleOwner,
        Observer { notes: List&lt;Note&gt; -&gt;
            <span class="hljs-keyword">if</span> (notes.isEmpty()) showEmptyState()
            <span class="hljs-keyword">else</span> showNoteList(notes)
        }
    )
   //..
}
</code></pre>
<p>…is <strong>always</strong> a bad thing, but classes which are tightly coupled to the platform (like Fragments) are difficult to test, and classes with logic in them are the most important classes to test!</p>
<p>In a word, it is a failure to apply what I consider to be the golden principle of any good architecture: <strong>Separation of concerns</strong>**.**</p>
<p>My personal opinion is that it is worth it to apply separation of concerns to a very high degree. But make no mistake that plenty of cash cow applications have been written by people who do not have the faintest clue about what that means.</p>
<p>In any case, the approach we will discuss next, while <strong>having its own side effects</strong>, once again removes the presentation logic from the View.</p>
<p>Well, most of it anyways.</p>
<h3 id="heading-second-approach-humble-view-control-freak-viewmodel">Second Approach: Humble View, Control-Freak ViewModel</h3>
<p>Sometimes not having fine-grained control over your Views (which is a consequence of prioritizing re-usability of ViewModels), actually kind of sucks.</p>
<p>To make me even less enthusiastic about applying the previous approach indiscriminately, I find that I <strong>often</strong> <strong>do not</strong> <strong>need to reuse a ViewModel</strong>.</p>
<blockquote>
<p><em>Ironically, “too much abstraction” is a common critique of MVP over MVVM.</em></p>
</blockquote>
<p>With that being said, one cannot simply add a reference back in to the ViewModel in order to regain this fine-grained control over the View. That would basically just be MVP + memory leaks (assuming you are still using ViewModel from AAC).</p>
<p>The alternative then, is to build your ViewModels such that they contain almost all of the <strong>behaviour</strong>, <strong>state</strong>, and <strong>presentation logic</strong> of a given View. The View must still bind to the ViewModel of course, but enough details about the View are present in the ViewModel that the View’s functions are reduced to one liners (with small exceptions).</p>
<p>In Martin Fowler’s naming conventions, this is known as <a target="_blank" href="https://martinfowler.com/eaaDev/PassiveScreen.html">Passive View/Screen</a>. A more generally applicable name for this approach is the <strong>Humble Object Pattern</strong>.</p>
<p>In order to achieve this, you must essentially have your ViewModel possess an observable field (however you achieve that – data binding, Rx, LiveData, whatever) for every control or widget present in the View:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserViewModel</span></span>(
    <span class="hljs-keyword">val</span> repo: IUserRepository,
){

    <span class="hljs-comment">//The actual data model is kept private to avoid unwanted tampering</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">val</span> userState = MutableLiveData&lt;User&gt;()

    <span class="hljs-comment">//Control Logic</span>
    <span class="hljs-keyword">internal</span> <span class="hljs-keyword">val</span> authAttemptState = MutableLiveData&lt;<span class="hljs-built_in">Unit</span>&gt;()
    <span class="hljs-keyword">internal</span> <span class="hljs-keyword">val</span> startAnimation = MutableLiveData&lt;<span class="hljs-built_in">Unit</span>&gt;()

    <span class="hljs-comment">//UI Binding</span>
    <span class="hljs-keyword">internal</span> <span class="hljs-keyword">val</span> signInStatusText = MutableLiveData&lt;String&gt;()
    <span class="hljs-keyword">internal</span> <span class="hljs-keyword">val</span> authButtonText = MutableLiveData&lt;String&gt;()
    <span class="hljs-keyword">internal</span> <span class="hljs-keyword">val</span> satelliteDrawable = MutableLiveData&lt;String&gt;()

    <span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">showErrorState</span><span class="hljs-params">()</span></span> {
        signInStatusText.value = LOGIN_ERROR
        authButtonText.value = SIGN_IN
        satelliteDrawable.value = ANTENNA_EMPTY
    }
    <span class="hljs-comment">//...</span>
}
</code></pre>
<p>Subsequently, the View will still need to wire itself up to the ViewModel, but the functions required to do so become trivially simple to write:</p>
<pre><code class="lang-kotlin"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LoginView</span> : <span class="hljs-type">Fragment</span></span>() {

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">lateinit</span> <span class="hljs-keyword">var</span> viewModel: UserViewModel
    <span class="hljs-comment">//...</span>

    <span class="hljs-comment">//Create and bind to ViewModel</span>
    <span class="hljs-keyword">override</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">onStart</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">super</span>.onStart()
        viewModel = ViewModelProviders.of(
        <span class="hljs-comment">//...   </span>
        ).<span class="hljs-keyword">get</span>(UserViewModel::<span class="hljs-keyword">class</span>.java)

        //start background anim
        (root_fragment_login.background <span class="hljs-keyword">as</span> AnimationDrawable).startWithFade()

        setUpClickListeners()
        observeViewModel()

        viewModel.handleEvent(LoginEvent.OnStart)
    }

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">fun</span> setUpClickListeners() {
      //...
    }

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">fun</span> observeViewModel() {
        viewModel.signInStatusText.observe(
            viewLifecycleOwner,
            Observer {
                //<span class="hljs-string">"it"</span> <span class="hljs-keyword">is</span> the value of the MutableLiveData <span class="hljs-keyword">object</span>, which <span class="hljs-keyword">is</span> inferred to be a String automatically
                lbl_login_status_display.text = it
            }
        )

        viewModel.authButtonText.observe(
            viewLifecycleOwner,
            Observer {
                btn_auth_attempt.text = it
            }
        )

        viewModel.startAnimation.observe(
            viewLifecycleOwner,
            Observer {
                imv_antenna_animation.setImageResource(
                    resources.getIdentifier(ANTENNA_LOOP, <span class="hljs-string">"drawable"</span>, activity?.packageName)
                )
                (imv_antenna_animation.drawable <span class="hljs-keyword">as</span> AnimationDrawable).start()
            }
        )

        viewModel.authAttemptState.observe(
            viewLifecycleOwner,
            Observer { startSignInFlow() }
        )

        viewModel.satelliteDrawable.observe(
            viewLifecycleOwner,
            Observer {
                imv_antenna_animation.setImageResource(
                    resources.getIdentifier(it, <span class="hljs-string">"drawable"</span>, activity?.packageName)
                )
            }
        )
    }
</code></pre>
<p>You can find the full code for this example <a target="_blank" href="https://github.com/BracketCove/JetpackNotesMvvmKotlin/tree/master/app/src/main/java/com/wiseassblog/jetpacknotesmvvmkotlin/login">here</a>.</p>
<p>As you have probably noticed, we are probably not going to be re-using this ViewModel <strong>anywhere else</strong>. Also, our View has become sufficiently humble (depending on your standards and preferences for code coverage), and very easy to write.</p>
<p>Sometimes you will run in to situations where you must find some kind of half-measure between the distribution of <strong>presentation logic</strong> between Views and ViewModels, which does not strictly follow either of these approaches.</p>
<p>I am not advocating one approach over another, but rather encouraging you to be flexible in your approach, based on the requirements at hand.</p>
<h2 id="heading-choose-your-architecture-based-on-preferences-and-requirements">Choose Your Architecture Based on Preferences And Requirements</h2>
<p>The point of this article was to look at two different approaches which a developer can take in terms of constructing a MVVM style GUI architecture on the Android Platform (with some carry over to other platforms).</p>
<p>In truth, we could get more specific about small differences even within these two approaches.</p>
<ul>
<li><p>Should the View observe a field for every individual widget/control it possesses, or should it observe one field which publishes a single <strong>model</strong> to render the entire View anew each time?</p>
</li>
<li><p>Maybe we could avoid having to make our ViewModels one-to-one, while keeping our Views as Humble Objects, simply by adding something like a Presenter or Controller to the mix?</p>
</li>
</ul>
<p>Talk is cheap, and I strongly advise you to try and learn these things <strong>in the code</strong> so that you do not need to rely on people like me to tell you what to do.</p>
<p>Ultimately, I think the two elements which make for a great architecture come down to the following considerations:</p>
<p>Firstly, play with several approaches until you find one which you <strong>prefer</strong>. This is best done by actually building an application (it can be simple) in each style, and seeing what <strong>feels right</strong>.</p>
<p>Secondly, understand that preferences aside, different styles will tend to emphasize different benefits in exchange for different deficits. Eventually, you will be able to pick good choices based on your understanding of the project requirements rather than <strong>blind faith</strong>.</p>
<h3 id="heading-learn-more-about-software-architecture">Learn More About Software Architecture:</h3>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/B_C41SF0KbI" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h4 id="heading-social">Social</h4>
<p><a target="_blank" href="https://www.instagram.com/wiseassbrand/">https://www.instagram.com/rkay301/</a><br><a target="_blank" href="https://www.facebook.com/wiseassblog/">https://www.facebook.com/wiseassblog/</a><br><a target="_blank" href="https://twitter.com/wiseass301">https://twitter.com/wiseass301</a><br><a target="_blank" href="http://wiseassblog.com/">http://wiseassblog.com/</a></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
