Animation plugins in Figma | | https://www.cleverlance.com/en/blog/Pages/animation-plugins-figma.aspx | Animation plugins in Figma | <p><em>Disclaimer: all tools mentioned in this article are under active development with frequent releases, so the version used when writing this article may already be older than yours. All animations referenced in the article can be found in this </em><a href="https://www.figma.com/file/rtjSqflfNWeaMPAjrQzhoM/Figma-Animations-overview-article---resources?node-id=0:1" target="_blank"><em>Figma file</em></a><em>.</em><br></p><p>When one says "animation tool", most people in the industry immediately think of Adobe Animate or After Effects. No wonder, it's the "industry standard" after all. But when you only animate every once in a while, need to make a nice loading screen, and you already have all the assets made in Figma, you don't want to deal with other tools. As you will see, there is no need to resort to such overkill solutions!<br></p><p>At an opportune moment, Figma plugins enter the scene, enriching its native shape compositing and prototyping functionality with exportable animation capabilities. In this article I will present a selection of the best ones. But first, a bit of terminology.<br></p><h3>Keyframe<br></h3><p>Represents the state of an attribute of a given layer at a given time.<em><img src="/de/blog/PublishingImages/Articles/CreateIt/position_and_color_shift-2.gif" data-themekey="#" class="ms-rtePosition-4" alt="" style="margin:5px 200px;width:190px;height:190px;" /></em></p><p><em>The keyframe for attribute X at 0 seconds into the animation sets the switch position to the left, the next keyframe to the right. Two more keyframes change the color of the switch, the remaining two change the background color</em> (created with Motion).</p><h3>Ease<br></h3><p>Defines the acceleration and deceleration of the transition in time, whether it is faster at the beginning, at the end, or in the middle. This adds a sense of life to the animation - after all, few things in the world move uniformly (linearly), except perhaps gears.<em><img src="/de/blog/PublishingImages/Articles/CreateIt/Ease-2.gif" data-themekey="#" alt="" style="margin:5px 200px;width:190px;" /></em></p><p><em>The light square moves with a linear ease setting, while the dark one moves with "Ease in and out" - it speeds up at the beginning and slows down at the end </em>(created with Motion).<br></p><h3>Object anchor </h3><p>A point that defines the position and anchor of the layer in space. The layer rotates around the <span style="color:#232323;font-size:16px;">anchor; it is used for all motion calculations.</span><br></p><br><p><img src="/de/blog/PublishingImages/Articles/CreateIt/Anchor_center-2.gif" data-themekey="#" alt="" style="color:#696158;font-size:14px;margin:5px;width:190px;" /><img src="/de/blog/PublishingImages/Articles/CreateIt/Anchor_top_left-2.gif" data-themekey="#" alt="" style="margin:5px;width:190px;" /><img src="/de/blog/PublishingImages/Articles/CreateIt/Anchor_offcenter-2.gif" data-themekey="#" alt="" style="margin:5px;width:190px;height:190px;" /><br></p><p><em>Anchor in the center, top left corner, and at 50% of the X dimension and 75% of the Y dimension </em>(created via Motion).</p><h3>Formats<br></h3><p>in which motion graphics are commonly found on the web:<br></p><p><strong>MP4 and WEBM</strong></p><ul><li>Video formats<br></li><li>do not preserve quality when scaling<br></li></ul><p><strong>GIF</strong></p><ul><li>sequence of raster images<br></li><li>does not preserve quality when scaling<br></li><li>large volume<br></li></ul><p><strong>SVG</strong></p><ul><li>XML containing Javascript, CSS or SMIL code that defines individual shapes and their movement<br></li><li>scalable, easy to edit (if you can write the code)<br></li></ul><p>Bonus: <strong>Lottie</strong></p><ul><li>a new minimalist format based on JSON<br></li><li>shapes and their movement are defined using a maximum of two-letter attribute abbreviations<br></li></ul><p>Now let's get into the details of the individual animation plugins.</p><h3>Motion<br></h3><p><img src="/de/blog/PublishingImages/Articles/CreateIt/motion.png" data-themekey="#" alt="" style="margin:5px;width:658px;height:336px;" /><br></p><p><a href="https://motionplugin.com/#" target="_blank">Motion</a> is a plugin with wide animation possibilities, based on keyframes. It allows animating a wide range of attributes, changing anchors with great granularity and copying keyframes between layers with X and Y value recalculation for a simplified workflow. A rich library of preset animations, effects and motions is available so we don't have to set everything up manually.<br></p><p><img src="/de/blog/PublishingImages/Articles/CreateIt/link_and_vector_path_shadow-2.gif" data-themekey="#" alt="" style="margin:5px;width:648px;height:402px;" /><br></p><p><em>A paper plane moves according to the drawn vector and the shadow follows it thanks to the dependency provided by the handy link function.</em><br></p><p>The finished animation can be exported in many formats, including GIF, MP4/WEBM and SVG in beta. GIF and SVG also support layer transparency.<br></p><p><img src="/de/blog/PublishingImages/Articles/CreateIt/figma1.png" data-themekey="#" alt="" style="margin:5px 230px;width:190px;height:411px;" /><br></p><p>Motion has four different licenses, with the free version limited to two-second animations and 30 FPS. The Professional license for 8 days per month is convenient for users who don't animate for a living.<br></p><p><img src="/de/blog/PublishingImages/Articles/CreateIt/figma6.png" data-themekey="#" alt="" style="margin:5px;width:658px;" /><br></p><p><em>The 8-day Motion license costs $6.39 per month.</em></p><p>Overall, the Motion plugin is very pleasant to use, although I would appreciate the option of a separate window for multi-screen work.<br></p><h3>Figmotion<br></h3><p><a href="https://www.figma.com/community/plugin/733025261168520714/Figmotion" target="_blank">Figmotion</a> is a free plugin with a web interface that makes it ideal for multi-screen work. It is also based on the use of keyframes. Compared to Motion, it supports animation of individual rounded corners and stroke widths, on the other hand, copying keyframes is done without recalculation, which in combination with the need to click Save every time, considerably slows down the workflow.<br></p><p><img src="/de/blog/PublishingImages/Articles/CreateIt/figmotion_corners-2.gif" data-themekey="#" alt="" style="margin:5px 200px;width:190px;height:190px;" /> </p><p><em>Rounding of individual corners and stroke width.</em><br></p><p>Figmotion implements the dependency between layers using expressions, i.e. calculating values based on variables (time in milliseconds or progress as a decimal value between 0 and 1), or attributes of other layers. However, this functionality is not well documented and you need to know Javascript.<br></p><p>The plugin has only four basic preset ease options and completely lacks a motion library, which means the users have to do everything manually. The anchor can be set to one of nine preselected positions. It supports export to MP4, WEBM and GIF up to 60 FPS, but without the option of transparent layers. Lottie format export was also recently launched in beta, and front-end developers will be interested in the new export for React's Framer Motion.<br></p><p><img src="/de/blog/PublishingImages/Articles/CreateIt/figma2.png" data-themekey="#" alt="" style="margin:5px 230px;width:190px;height:325px;" /><br></p><p><em>Anchor settings are on top, keyframe settings in the center, and transition options on the bottom.</em></p><p>Figmotion has a huge number of features, but many of them are unfinished, and frequent bugs and a cumbersome workflow take away from its usability. On the other hand, it has unlimited animation length, is free, and has the largest number of users in the Figma community.<br></p><h3>Bonus: Jitter.video<br></h3><p><img src="/de/blog/PublishingImages/Articles/CreateIt/figma3.png" data-themekey="#" alt="" style="margin:5px;width:658px;height:399px;" /><br></p><p><a href="https://jitter.video/" target="_blank">Jitter</a> is a web tool for creating animations from vector shapes which doesn't work directly in Figma, but you can import assets from Figma in a single click using their plugin. While it doesn't yet support all attributes (for example, individually rounded corners), it solves this relatively elegantly - it imports the unsupported layer as a PNG. Rather than keyframes, it focuses on the transition process. It provides a decent library of preset animations and a simplified view of individual attributes.<br></p><p><img src="/de/blog/PublishingImages/Articles/CreateIt/figma4.png" data-themekey="#" alt="" style="margin:5px 230px;width:190px;height:460px;" /><br></p><p><em>The user is shileded from individual attributes by user-friendly verbs.</em></p><p>Jitter in the free version does not allow transparent backgrounds and export to higher resolutions. In the case of the beta Lottie export, this limitation is quite easy to work around - you just need to know a bit about the Lottie format and set the transparency manually. The paid version costs $12/month.<br></p><h3>Conclusion<br></h3><p>As you can see, there are several ways to get otherwise static assets moving in Figma, it just depends on what one expects from the tool and whether one is willing to pay something for the extended possibilities to implement one's ideas. The fact that they compete with each other encourages dynamic development, which of course is not without bugs, but the developers of these tools are quick to respond and appreciate every bug reported (I've written about ten of them myself).</p><p>Would you like to learn how to use one of the plugins? You can look forward to a sequel in the form of a tutorial on Motion.<br></p> | | | | |
Unexpected bad practices | | https://www.cleverlance.com/en/blog/Pages/unexpected-bad-practices.aspx | Unexpected bad practices | <p>Some programming practices are so familiar to us that we use them automatically without much thought. Sometimes these techniques become obsolete; sometimes they are applied in the wrong context. Addressing such poorly experienced habits is often met with revolt. Especially by those who use them and perceive the topic as useful, so let's do exactly that!</p><h3>Marks<br></h3><p>Programming IDEs often recognize specific types of comments to help navigate across the codebase. Xcode’s <em>FIXME</em> lets other developers know that a piece of code deserves more attention. <em>TODO</em> is helpful when something is, well, to be done. <em>MARK</em> differs from the previous cases; it serves a documentation purpose. The same feature in IntelliJ IDEA/Android Studio is called region.<br></p><p>Marks divide the source code into multiple parts using headings. That can make the code appear broken into logical units. If you are a reader familiar with the former Objective-C era of iOS development, know that this is just an updated <em>#pragma mark</em> directive.<br></p><p>Typical usage is in files with a large number of lines. <em>Marks</em> create the illusion of clarity by breaking them into pieces that supposedly belong together.<br></p><p>The usage of marks in such cases is a bad practice. Developers often abuse them to justify a file being too big. One should not depend on Xcode to make the code comprehensive and readable. Small and well-decomposed classes are more straightforward to reason about and navigate without IDE features. Especially for pull request reviewers using the web interface where those features are absent.<br></p><h3>Extensions</h3><p>Modern programming languages such as Kotlin or Swift allow you to extend classes, interfaces/protocols, structs, or enums to provide an additional implementation. You can divide your code into multiple pieces using extensions to outline what belongs closer together. Another usage is to make a convenience extension around another type you might not even own to make its use more intuitive. The possibilities are almost limitless. This isn't always a good thing, but first, a peek into history.<br></p><p>Extensions existed way back in Objective-C as well. If you're not blessed with experience with programming in such a language and had to guess the name for extensions, you'd likely be surprised. It's Categories! Another surprise is that Extensions are a thing in Objective-C too, but serve different purposes. What's interesting is the difference between both languages. Categories in Objective-C forced the developer to come up with the name. That's why files named in style <em>Class+CategoryName.swift</em> are often used even for Swift extensions. And more importantly, to use Categories, you had to import them explicitly.<br></p><p>Extensions in Swift are an unnamed piece of code. Such code may be more complicated for the reader to grasp. If multiple extensions of the same type exist, adding a name to the code and wrapping it in a type might help readability immensely.<br></p><p>Improper extension of widely used types causes namespace pollution. It's critical, before creating extensions, to ask whether all instances of the type should have such an ability. Should all UIViews have access to a blinking method? Does one specific subclass of UIView make more sense?<br></p><p>Some developers use extensions to break down the implementation of multiple protocols: which might also be a warning sign. If a class implements many protocols, it may be time to consider splitting it into smaller classes.<br></p><p>For trolls out there: you can make your co-workers mad by extending <em>UIView</em> with <em>translatesAutoresizingMasksIntoConstraints and watch them compare it with translatesAutoresizingMaskIntoConstraints.</em><br></p><p>But don't.</p><h3>Comments<br></h3><p>The ability to write comments might lead undisciplined programmers to create code of poor quality. Unfortunately, it's easier to neglect to name a variable and describe what's going on in my head with a complicated but not-so-clear comment. Easy should not be our goal. Brevity and clarity should.<br></p><p>Great comment for poorly written code is still a code smell. Don't just take my word for it. Robert Martin states: "A comment is a failure to express yourself in code. If you fail, then write a comment; but try not to fail."<br></p><p>Another reason is as the code lives in the repository and is modified and refactored, its behavior might change, and its name can express it everywhere it is called. But its comment is rarely updated and may become more confusing than helpful.<br></p><p>Documentation comments serve their purpose very well when you're designing an API for others to use. Remember that the API needs to stand by itself, and clarity is the priority. Don't use the documentation comments as an excuse for a lousy design.<br></p><h3>Structure</h3><p>The structure of a project is one of the first things you see when you check out a codebase, and it should outline the app's purpose at first sight. However, it is not an exception that some projects have folder structures inspired by the layers of architecture, e.g., View, ViewModel, Model.</p><p>Project structure based on architecture layers is a bad practice. It makes reusability effectively impossible. Navigating through such a structure is unnecessarily complicated and becomes harder to maintain as the scope increases. It doesn't scale. Folders inspired by the architecture might have their place, not just at the top level. It should not be the first thing you see.<br></p><p><img src="/de/blog/PublishingImages/Articles/MobileIt/unexpected-bad-practices-01-01.png" data-themekey="#" alt="" style="margin:5px;" /><br></p><p>See for yourself, what structure tells you more about the application?<br></p><h3>Dependencies</h3><p>Open source offers many libraries to simplify life, from UI components through networking to dependency injection solutions. It can often save a great deal of time and effort. On the other hand, this carries various dangers and limitations; using third-party libraries requires discipline, order, and balance.<br></p><p>Randomly scattered third-party dependencies significantly reduce robustness. Shielding the core of the application and using the libraries from the outer parts of the architecture helps mitigate the risk. Abstraction eases the process of replacing one library with another.<br></p><p>It's OK to utilize 3rd party dependencies, but with caution. Ask yourselves: How much time will it save me? How much effort will it take to replace? Can I install enough defense mechanisms to protect the application?<br></p><p>The silver bullet to protect your app, though sometimes tricky or impractical, is to have the import of the dependency in only one place.</p><p>We've had the pleasure of taking over multiple apps that were impossible to maintain anymore due to this problem. Without abstraction, no longer supported (or closed sourced) libraries disintegrated the codebase. External dependencies should never hold your product hostage.<br></p><h3>Tests</h3><p>Test-driven development is a programmer's good manners, a discipline overflowing with benefits. Technical impacts are a blog post by itself, if not a series. Non-technical impacts such as easy onboarding of new team members and executable documentation that cannot become obsolete speak for themselves.<br></p><p>Yet they are often neglected. A complete absence of tests is the apparent first and most common violation, followed by writing tests after the production code, which mitigates all the benefits and introduces other obstacles.<br></p><p>You must write unit tests first - before production code. Testing first will prevent you from creating code that's too complex. It will guide you through building components of the right size. The big classes are challenging to test, and the tests will direct you to decompose them into smaller ones.<br></p><p>Tests written after production code are inherently lower quality and can even be misleading. Unless you write the production code as proof of the first failing test, it is impossible to say whether the tests assert what they declare. It is then questionable how well such tests protect the system under test.<br></p><p>If you write tests after implementation, you may find a component challenging to test, which is impossible with a test-first approach. You can't create untestable code!<br></p><h3>The devil's in the detail</h3><p>Even the mundane can be harmful if we do something too automatically and with less attention. Challenge the ordinary and seek bad practices that you wouldn't expect.<br></p> | | | | |
Apple thinks about the security of its users | | https://www.cleverlance.com/en/blog/Pages/apple-account-deletion.aspx | Apple thinks about the security of its users | <p>Mobile apps are becoming increasingly popular among users. Thousands of them are downloaded every day from <strong>Google Play</strong> and the<strong> Apple App Store</strong>. However, not all apps are completely secure for their users and not all manage the personal data of their users correctly. The above-mentioned companies try to make sure that only apps which “play fair” with users get into their stores.<br></p><p>In order to protect the privacy of iOS app users, Apple has issued a <a href="https://developer.apple.com/support/offering-account-deletion-in-your-app" target="_blank">regulationstating</a> that: “Starting June 30, 2022, apps submitted to the App Store that support account creation must also let users initiate deletion of their account within the app.”</p><p>Originally, this guideline was supposed to apply from the end of January 2022, but the deadline was postponed by 5 months due to pressure from developers and app companies. This is due to the fact that updating apps is not always a simple procedure. Apple has clear rules for deletion of an account: </p><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px;"><p>• The process of deleting the account must be clear, intuitive and transparent, easy to find in the application (e.g. a button to take you to the user profile or account management).</p><p>• We must offer complete deletion of the entire account record, including associated personal data. Merely offering to deactivate (temporarily disable) the account is not enough. </p><p>• If users have visit the website to complete deletion of their account, we should add a direct link to the page on the website where they can complete the process. </p><p>• Users must be well informed. If the deletion request is going to take longer to complete, we need to let users know. </p><p>• If the app supports in-app purchases, we need to clearly explain to people how subsequent billing and account cancellation will take place. </p><p>• All apps must include an easily accessible link to the privacy policy in the description on App Store Connect within the app. </p><p>• Last but not least, it is necessary to comply with the applicable legal requirements for the processing and storage of the client’s personal data. And also its deletion. This includes compliance with local laws - in our case, the applicable GDPR directive.</p></blockquote><p><a href="/en/" target="_blank">Cleverlance</a> in its capacity as a technology company, helps its customers address these requirements. As a supplier of mobile applications, we have successfully resolved this issue, for example in the mobile application for <a href="https://apps.apple.com/cz/app/my%C5%A1koda/id1161648654?l=cs" target="_blank">MyŠkoda</a> ŠKODA AUTO a.s. Exactly according to the GDPR directive, here customers can completely delete their account in their profile, including their personal data. However, they must first disconnect their cars, which they control via the app. </p><p>In banking, the situation is slightly different. Although users can delete their accounts and access to the mobile app, their products remain untouched in the bank. Just like their personal data which must remain in the systems because of the legitimate interest of processing personal data and fulfilling a legal obligation. Users can cancel their account in the app and in doing so stop using the app. But they remain full-fledged customers of the bank.</p><h3>What does Google say?</h3><p>And how does another giant, Google, feel about this? The rules for displaying apps in Google Play state that the app must be transparent and inform the user how it processes their personal data. They prohibit outright fraudulent or dishonest conduct. However, Google has not yet taken the step of dictating that every app, if it creates a user account, must also allow the deletion of that account. </p><p>This move by Apple will certainly improve the transparency and fairness of apps as regards their users. It is a good step in the right direction towards a more honest electronic world. </p><h3>Recommendations for developers </h3><p>For the implementation of the new account deletion functionality, I recommend scheduling a separate release after the specified date. This is to say that Apple is likely to be rigorously testing the functionality and this may lead to a delay in release of the new version. This could have a detrimental effect on other important new functionality of the app if released alongside this release. And users don’t like to wait.<br></p> | | | | |
Development of multi-platform mobile and web apps | | https://www.cleverlance.com/en/blog/Pages/Multiplatform.aspx | Development of multi-platform mobile and web apps | <p>Do you want your own mobile app? Nowadays it’s a given that one needs to do one for Android as well as for iOS; one is not enough. And more often than not, one also wants a web interface. However, essentially right from the introduction of mobile devices to the market, we’ve heard it said again and again that developing things separately for individual platforms is expensive. That is why various companies tried to introduce alternatives in the form of multi-platform solutions, however none of these really managed to become widely adopted. They had their shortcomings, were unnecessarily complex and held companies which wanted to develop their mobile apps flexibly in a kind of “cage” with limited possibilities. That is why for B2C apps it is often preferred to develop natively; there are no limitations as far as UX, animations and other details are concerned, and these things can be very important for the target group.<br></p><p>However, in the past years we see corporate mobile apps for which a perfect user interface and design is no longer a priority; emphasis is placed on functionality, utility, expedited delivery and flexible adjustments. And that’s where we can make use of selected technologies that can be used in a multi-platform setting. Of course, assuming we adhere to certain rules.<br></p><p>At Cleverlance, we found success with three approaches to implementation. To put it in really simple terms, right from the very beginning we need to decide whether there’s a robust back-end with a MOA (<a href="https://en.wikipedia.org/wiki/Microservices">Microservice Oriented Architecture</a>) is available or whether we’d need to create one, and then whether the app will need a lot of business logic or rather will be just a presentation layer. In this case, it is good to use <a href="https://flutter.dev/">Flutter</a>. If we need the app to include synchronization queues, business logic and we’re implementing some kind of complexity and not just forms, we had good experiences with <a href="https://kotlinlang.org/docs/multiplatform.html">Kotlin Multiplatform</a>. And then there’s a third option = PWA (<a href="https://en.wikipedia.org/wiki/Progressive_web_application">Progressive Web Applications</a>), which makes use of the strong foundation provided by modern browsers.<br></p><h2>Flutter<br></h2><p>We consider Flutter to really be a multi-channel display layer which allows us to create not just mobile but also web and desktop apps. It’s a flexible solution that allows us to efficiently design B2B, and under certain conditions even B2C apps. One example here is the mobile app for BMW. But if we don’t want to deal with problems, it’s better to rely on the back-end and push all the “thinking” there.<br></p><h2>Kotlin Multiplatform</h2><p>Kotlin Multiplatform is another option. Its advantage is that it allows you program a native app for Android, and then use a part of it for iOS. This usually applies to business logics and the integration layer, which leads to significant time savings in the QA phase later. The visualization layer is programmed natively for iOS and Android, meaning that one can have the “look & feel” of the platform while making use of just one code base for the part of the application that is not visible for users. For some projects, this allows up to 70-80% of the code to be reused.<br></p><h2>PWA</h2><p>Progressive Web Applications is one of the latest trends in the area of web application development. To a certain extent, these shatter the boundaries between web and native mobile apps thanks to the ability to work offline, access a device’s hardware and even handle push notifications. They represent a combination of the best of both worlds; we are only limited by the capabilities of web browsers. This opens up a wide range of functionalities; for instance, the use of a phone’s camera or fingerprint reader are among the most basic ones. A request for using deeper device functions can be efficiently handled via a native “envelope” that can make them available. PWA apps can be distributed via all major app stores (Google Play, Apple Store, Huawei AppGallery as well as Microsoft Store) and can run on all Android, iOS and Windows devices.<br></p><h2>Where was this used?</h2><p>As a supplier, we of course want to offer not just standard technologies but also the “new” ones, and that was another reason we were happy to see customers approach us who right from the very beginning wanted a solution based on Kotlin Multiplatform. As an example, we can mention the U.S. based Globstar for which we, as part of the Aricoma Group, deliver mobile apps used to configure and manage modems for satellite internet connections. The use of Kotlin Multiplatform really paid off in this case, because the app was highly demanding as far as data transmission and integration were concerned. Integration additionally takes place via a BLE (Bluetooth Low Energy) interface, which can service dozens of devices simultaneously to, e.g., update their firmware. The technology was not only convincing for the customer, but also for us as the supplier; when developing the app we established a well-working business partnership.<br></p><p>We made successful use of PWA technology for instance in the online self-service app for SAZKAmobile customers. Its main advantage is an extremely short Time-To-Market (i.e., the time required to introduce new functions to the market) and a wide range of developers who already know the technology. In addition, PWA is best applied in areas without a large emphasis on using the device’s components, for instance in internal company apps for employees in the field or in production.<br></p><div><p>If you’re interested in the technical details, feel free to read <a href="https://www.mobileit.cz/Blog/Pages/kotlin-multiplatform-first-year.aspx">this article</a> on our mobile it blog; it’ll <a href="https://www.mobileit.cz/Blog/Pages/choosing-mobile-app-technology.aspx">tell you </a>what to pay attention to when choosing the right technology for developing a mobile app.<br></p></div> | | | | |
Development rules for better productivity | | https://www.cleverlance.com/en/blog/Pages/development_rules_for_better_productivity.aspx | Development rules for better productivity | <p>Each project has its own rules for development. Most often, these rules describe development practices and work with a version control system (VCS) that outlines how to test and deploy the product, the structure, the architecture of the project, and the code style, but the rules can also include the basics of secure development and more.<br></p><p>These rules can be unwritten but are usually defined and recorded in a shared space where everyone has access to them. Yet more important is how these rules are applied and enforced in practice.<br></p><h3>Wise men know it best</h3><p>Some people believe that pair programming or code review is an appropriate platform for rules revision. Participants can agree on the application of the rules or change them based on context. When developers approach this conscientiously, the result can be a project that may not be consistent, but its individual parts will be in the best possible shape.<br></p><p>This approach may lead to better results for a short period of time at the start of a project, but its shortcomings will start to become apparent over time. Even experienced developers and technical leads are just people. They can occasionally get tired or simply overlook something. Thus, minor deviations from the agreed-upon rules pile up and begin to form so-called technical debt.<br></p><h3>Time trial</h3><p>The next aspect that reflects in time is the expansion of the project, and this is on two levels.<br></p><p>The first is the expansion of the product itself. As the product becomes successful, it receives new and more sophisticated features that begin to connect previously simpler and independent features. This is where the small deviations and inconsistencies that at first seemed good for the functionality start to show up. The problem is that now more of these functions need to be compatible with each other, but they are not ready for it.<br></p><p>This is not just a problem of incompatibility of features. Often, well-intentioned developers try to reuse existing components as much as possible to avoid code duplication. They forget the rule that we can reuse a component when we expect the same behavior but also have the same reasons to change. If this condition is not met, the Single Responsibility Principle is violated and the project has low flexibility for future development.<br></p><p>The second level of project expansion is the development team itself. Once the product becomes successful, sooner or later it leads to the expansion of the development team. The new team members do not know the whole genesis of the project and thus do not have the same understanding of the rules as the older members who set the rules themselves. This leads to misunderstandings and yet another minor deviation from the agreed rules, which again increases the technical debt. A side effect is an increased need for communication during pair programming and code review, which reduces the overall productivity of the team.<br></p><p>These problems in project expansion are not limited to large development teams, but also happen to smaller ones. For example, when a two-person team introduces two new developers, the productivity of the team may hardly change. And all this is due to the circumstances described above. Without knowing the cause of the problem, it can lead to further blind "strengthening" of the team and make it even worse.<br></p><h3>Tripping comes before a fall</h3><p>When a development team repeatedly fails to finish agreed features or is unable to release a new version of a product for technical reasons, one of the critical scenarios occurs. At this point, people outside the standard development team get involved in discovering the cause and solving the problem. Together, they all work under stress and with a lot of human effort to get the development back under control. It is only at this point that a retrospective analysis takes place to uncover the true causes of the problems.<br></p><p>Yet the accompanying symptoms and spring of these problems have been manifesting themselves for a long time in advance. A few subtle situations as examples:</p><ul><li>A developer repeatedly receives feedback on misnaming during code review.<br></li><li>A ticket in the project issue tracker does not contain a reference to the implementation due to a typo in the project source code.<br></li><li>A feature that is still under development is enabled in the test version of the application.<br></li></ul><p>Often they just look like minor ambiguities, individual mistakes, or accidents that sometimes happen during development. When these situations recur, their negative impact on team productivity and the project's error rate quickly increases. But if we look closely at them, we can see blank spaces in the way we work that are actually easy to fill and solve the problem once and for all.<br></p><h3>Live rules</h3><p>To avoid the problems mentioned above, we need to have clearly specified development rules. Their content should reflect the individual needs of each project. For some projects, it will be critical to clearly define collaboration with the QA team and describe the release management of the product, while other teams will focus more on collaboration between developers within the development itself.<br></p><p>The more detailed and specific the rules are, the better their effect on the team's work will be. Therefore, it is not possible to start from a general template, but each team must define these rules themselves.<br></p><p>Sometimes we see cases where a team defines a few basic rules of a more general nature at the start of a project but does not develop them over time. Thus, the rules never accurately represent how the team works, and even the little they contain becomes meaningless over time.<br></p><p>Nothing is set in stone, and even an established team changes the tools it uses or discovers new ways of working over time. All these natural changes have an impact on the team rules. They remain alive and valid.<br></p><h3>Automate everything</h3><p>In the introduction, we briefly discussed the form the rules can take and the possible ways of applying them. To be most effective, rules must be applied automatically without the need for manual control. Likewise, we must think about the productivity of the team, which can be reduced by the influence of a large number of repressive rules. Therefore, tools that help team members automate certain steps are an integral part of this process. These tools save time and their output is naturally in line with the defined rules.<br></p><p>In practice, it is so common that Code Style or Project Architecture is enforced by automated rules, but at the same time, there are code templates and formatting tools that do most of the work for the developers without them being aware of it.<br></p><p>Most issue tracking tools provide a programmatic interface so that it is easy to automate the creation of a new development branch in VCS so that the new code is linked to a specific issue. Similarly, it is possible to create a VCS hook that checks that a corresponding issue exists for a given branch or commit for cases when the developer has created the new development branch manually.<br></p><p>Release management is a completely separate chapter. When releasing a new version of a product, there are generally routine and clearly defined steps that need to be performed. Here, automation not only gives us the assurance that the release of a new version will be done in an orderly and error-free manner but it also speeds up the process and allows for easy knowledge sharing between team members. A bonus is an easy automation of generating release notes, even if only for internal testers.<br></p><p>Testers will also appreciate the ability to configure the product for internal testing. They can toggle a feature flag, configure the environment the application runs against, or have the ability to simulate scenarios that are difficult to do manually. Besides the undeniable benefit of these test tools for testers, it has benefits for the developers themselves. They don't have to maintain more versions of the product than strictly necessary, which saves them time by fundamentally simplifying the build logic.<br></p><p>This is just a small sample of the rules we commonly encounter on projects. However, it is far from exhaustive of the options, whether they are related to quantity, depth, or sophistication.<br></p><h3>How far to go?</h3><p>Some rules may seem strict enough to restrict your freedom to work. Others may seem so vague that they will not have the desired effect. That's all right. Every team and every member has different needs and different perceptions of risk. All of this has a bearing on the form of the rules.<br></p><p>In our projects, we try to define the rules strictly by default. Over time, when we find that they limit us too much, it's easy to make the rule more generalized or turn it into a recommendation or warning. The opposite approach is considerably more complicated, because the team and its operation have already become accustomed to the more general rule, so it may not be possible to make a change overnight.<br></p><h3>Project sustainability</h3><p>When developing a product, in addition to the short-term goals of making the necessary features, we always consider the idea of long-term sustainability and viability of the project. Especially in mobile development, it is not an exception to the opinion that a project should be discarded once every 2-3 years and developed completely from scratch. This is a real disaster in terms of productivity.<br></p><p>In our portfolio, we have apps that are more than 7 years old and have gone through several major changes during their lifetime. On a business level, there has been a change in targeting a different sector of users and aligned with changes in branding and design. On a technical level I would mention the switch from Java programming language to Kotlin, or the transition of asynchronous work from a custom imperative solution to a reactive approach via RxJava and later Kotlin Coroutines. Even so, the development team is still only two people (while they are altering throughout) and at the same pace, it delivers new functionalities according to the business needs.<br></p><p>Clearly defined development rules and the consistency enforced by them have a major impact on the quality of the final product in every way.<br></p><div><p>Next time we will take a closer look at how some rules can be implemented and what tools we have for this.<br></p></div> | | | | |