mobile it



Kotlin Multiplatform Training: Building Native Mobile Apps Multiplatform Training: Building Native Mobile Apps<p>October is not only marked by multiplatform development but also by threes: 3 consecutive Wednesdays in a row, featuring 3 hours of intensive training, utilizing 3 (or more) programming languages & platforms.</p><p>Check out each day of training and contact Mariia (<a href=""></a>) if you have any questions or sign up directly on the <a href="">registration form</a>.</p><h2>Training Program</h2><h2>4.10.2023 - Day 1</h2><h3>Building Kotlin Multiplatform applications</h3><ul><li>Brief history of Kotlin project</li><li>Introduction to Kotlin Multiplatform & its current development status</li><li>Comparison of KMP to other cross-platform solutions</li><li>How KMP fits into Kotlin Ecosystem</li><li>Typical structure of KMP Gradle module</li><li>Communication between shared & platform code</li><li>Setup of shared & platform code in version control system repository</li><li>Integration of shared code into an Android & iOS applications<br></li></ul><h3>What does it get to you?</h3><p>You will understand how the Kotlin Multiplatform (KMP) works and how to use it appropriately.</p><p>You will learn how to run a simple application and understand the logic behind the coding.</p><p>You will get a comprehensive overview of the advantages and disadvantages of KMP compared to other multiplatform solutions.</p><h2>11.10.2023 - Day 2</h2><h3>Kotlin Interoperability in Multiplatform World</h3><ul><li>Levels of language interoperability</li><li>Kotlin/JVM and JVM bytecode</li><li>Kotlin/Native and LLVM bitcode</li><li>Design of Kotlin shared APIs</li><li>Architecture of KMP apps<br></li> <li>​Testing of shared code</li></ul><h3>What does it get to you?</h3><p>You will be able to develop shared code that can be easily used on native platforms.</p><p>You will get a feel for using technical details and code design effectively hide the boundaries of where multiplatform begins and ends.</p><h2>18.10.2023 - Day 3</h2><h3>Efficient development for Kotlin Multiplatform teams</h3><ul><li>Building a KMP team</li><li>Onboarding of Android & iOS platform developers</li><li>Collaboration between Android & iOS teams</li><li>Development process of mobile apps using KMP</li><li>What should you share</li><li>Ecosystem of 3rd party KMP libraries</li><li>Unexpected perks</li></ul><h3>What does it get to you?</h3><p>You will learn what is a key for effective development, how to build a team and work together.</p><p>You will learn how to set up development processes, code review or set up a repo.</p><p>You will get a sense of which parts of the project are suitable to be shared and which are not.</p>​<br>#kotlin;#multiplatform;#kmp;#android;#iOS
The role of continuous feedback in software development role of continuous feedback in software development<p>Just like a boomerang coming back to you, feedback in software development and product management helps you improve. In this article, we're going to explore feedback mechanisms and purpose in its broader sense. Not just person-to-person feedback, but also product, market, and development practices. We'll back up our points with evidence from psychological research, so buckle up for a fact-based feedback adventure!</p><h2></h2><p>Several kinds of research have been performed to analyze the relationship between feedback and improvement. In this post, I've picked two well fitting to the world of software development.</p><p>By understanding Kahneman's and Melton's researches, we can see why immediate feedback is so crucial to our software development and product management success.</p><h2>1. The Kahneman study on immediate vs. delayed feedback</h2><p>In his study, psychologist Daniel Kahneman compares the experiences of anesthesiologists and radiologists to illustrate the difference between immediate and delayed feedback. He analyzed their job's inherent feedback nature. He then assessed the effect of such an environment on an individual's development.</p><p>A radiologist is a type of doctor who specializes in medical imaging. Radiologists analyze images, such as X-rays, to help diagnose, monitor, and treat various conditions or injuries. An anesthesiologist is a doctor who gives a patient medication so they do not feel pain when undergoing surgery.</p><p>There is one key difference when it comes to the feedback loop.</p><p>Anesthesiologists work alongside the patient and get feedback straight away, such as whether the patient is unconscious with stable vital signs. On the other hand, radiologists don't get rapid feedback on their diagnoses, if they get it at all. They often have to wait for weeks or even months to find out whether their diagnosis was correct.</p><p>The immediate feedback helps anesthesiologists learn the regularities of their environment and adjust their actions accordingly. As a result, anesthesiologists tend to have a higher success rate in administering anesthesia and managing patients throughout the procedure.</p><p>The delay in feedback for radiologists makes it much harder to improve their skills and recognize patterns. Consequently, radiologists typically correctly diagnose breast cancer from X-rays just 70% of the time.</p><h2>2. The Melton study on predicting freshman success</h2><p>Richard Melton's study aimed to predict the grades of freshmen at the end of their first year of college. A set of 14 counselors interviewed each student for about an hour and had access to high school grades, several aptitude tests, and a four-page personal statement. Based on this information, the counselors made predictions about the students' first-year college performance.</p><p>In comparison, Melton created an algorithm that used only high school grades and one aptitude test as input. Despite the limited information, the formula was more accurate than 11 of the 14 counselors, outperforming them by a significant margin. Melton's study was reported alongside over a dozen similar results across various domains, such as predicting parole violations and success in pilot training.</p><p>The key finding of this study is that, in many cases, simple algorithms using limited data can outperform human judgment. This insight can be applied to various decision-making processes where data is available, emphasizing the importance of relying on (simplified) data and patterns rather than solely on subjective assessments of complex factors.</p><h2>Benefits of continuous feedback in software development</h2><p>Imagine your software development team as a well-oiled machine. With continuous feedback, the gears are in sync, communication is smooth, and everyone's on the same page. Like Kahneman's anesthesiologists, the immediate feedback loop helps your team adapt quickly to change, keeping them nimble and responsive. Plus, it boosts team morale and motivation, as everyone knows they work together towards a common goal. It's like a software development symphony!</p><p>Agile development methods employ short iterations. Those are tools that transform findings from feedback loops into high business value and relevance when performed correctly.</p><p>Many teams adopting Agile development approach miss this aspect. It is not sufficient to develop in small chunks and short cycles on its own. If a relevant feedback loop mechanism isn't employed, the whole point of agile development can be missed because the ecosystem does not improve itself.</p><h2>Techniques for effective continuous feedback in software development</h2><p>According to Kahneman's concept of deliberate practice, a guitarist can't become an expert by playing the same songs for 25 years. If we apply this logic to our software development team, it needs to be pushed beyond their comfort zone to grow. </p><p>Immediate feedback creates a productive learning environment, helping your team members become experts in their craft. Not only can it help your team collaborate and improve individual skills, but it can also give valuable insights into your product's market relevancy, usability, and development practices.</p><p>In software development and product management, this translates to the effective employment of metrics, analytics, and user feedback. Developers and managers can make more informed decisions about the product's direction, team performance, and areas for improvement.</p><p>Furthermore, implementing continuous integration, automated testing, and regular code reviews can provide developers with a very short feedback cycle, enabling them to learn quickly and avoid making the same mistakes, ultimately leading to a higher-quality product and a more efficient development process.</p><p>So let's now be more particular about how to incorporate findings from the mentioned studies in practice. I'll break down typical best practices corresponding to the feedback studies I mentioned earlier.</p><h2>Applying the Kahneman and Meloton studies to software development</h2><p>There are several typical ways to foster immediate feedback mechanisms in software development.</p><h3>Continuous integration</h3><p>Continuous integration (CI) can be implemented to provide immediate feedback on code changes. As developers commit code to the shared repository, CI tools automatically build and test the application, providing rapid feedback on whether the changes pass or fail the tests. This immediate feedback allows developers to quickly fix any issues, reducing the risk of accumulating technical debt and ensuring the product remains stable.</p><p>Code reviews by peers are often an integral part of the continuous integration process.</p><h3>Testing in minimum increments</h3><p>By testing in minimum increments the team takes every chance it gets to test a newly written code - even multiple times per day. The smaller the change is, the shorter the feedback loop is. That is why it is so important to have automated processes set up to make this a pain-free process.</p><h3>Frequent reviews with stakeholders</h3><p>Another way to incorporate immediate feedback in Agile development is by conducting regular sprint reviews and surveys with stakeholders and end-users. These reviews provide an opportunity for the team to demonstrate the functionality they have completed and gather feedback from stakeholders. </p><p>Qualitative or quantitative surveys provide in-depth feedback and sanity checks. The team can then use this feedback to prioritize work for the next sprint, ensuring that the most important features and improvements are addressed promptly.</p><h3>Retrospectives</h3><p>An analogy of reviews, which are outward-oriented, are retrospectives. While it is more inward-focused, it is a great tool to provide access and obtain immediate feedback from within the team. There is no need to keep rigorous and employ complex or sophisticated mechanisms, keeping it as a simple and to-the-point discussion is often sufficient.</p><h2>Leveraging the Melton study in software development</h2><p>The Melton study demonstrates that simple algorithms using limited data can outperform human judgment. In software development, this insight highlights the importance of relying on data and patterns to inform decision-making, rather than solely on subjective assessments.</p><h3>Using metrics to inform backlog prioritization</h3><p>One way to apply data-driven decision-making in Agile development is by using metrics to inform backlog prioritization. For example, a product manager could analyze user engagement data, customer feedback, and bug reports to determine which features or improvements should be prioritized in the backlog. By using data to inform these decisions, the development team can focus on the most impactful work, ultimately leading to a better product that meets the needs of its users.</p><p>The takeaway here is that the statistics don't necessarily need to be extremely complex and sophisticated. Quite the contrary - a simple but highly relevant metric helps tremendously. Such simple metrics can be user story completion rates, velocity measurement, net promoter score, time to restore a service etc. Metrics that are really trivial in principle.</p><p>Managers can identify trends and patterns that indicate strengths and weaknesses by collecting data on the team's velocity, code quality, and other relevant metrics. People sometimes evaluate snapshots of situations without seeing the trends.</p><p>This data-driven approach can lead to more effective and efficient development teams.</p><h2>Tips for making the continuous feedback work</h2><p>Now that we've explored the what, why, and how of continuous feedback, let's talk about making it work in real life. First, create a feedback-friendly culture where team members feel safe to share their thoughts and ideas. Encourage open communication and make feedback sessions a regular part of your team's routine. This is paramount, without a culture valuing honesty, feedback receptiveness is greatly hindered.</p><p>A side note for managers: this culture of human-to-human feedback goes both ways—be receptive to the feedback you receive and use it to sharpen your own skills and processes. </p><p>But wait, there's more! We must broaden our understanding of feedback by extending it beyond the individual level. Design the entire development system to generate and be responsive to feedback, encompassing aspects such as development practices, product quality, financial efficiency, and any other aspect crucial to the product being developed.</p><p>A strong emphasis on feedback loops is a crucial factor that distinguishes traditional waterfall development methods from Agile development. Simply adopting short iterations and frequent planning cycles isn't enough to fully embrace the Agile philosophy if feedback reception mechanisms don't exist. Establishing a system that generates and processes feedback is absolutely essential. Being able to gather feedback and react to it is Agile's primary objective. </p><h2>Conclusion</h2><p>Just as a chef needs to taste his dish while cooking to ensure the flavors are on point, continuous feedback is an essential ingredient in the recipe for successful software development and product management.</p><p>By embracing feedback in various forms - from human-to-human interactions to product metrics and beyond - you'll create an environment where learning, growth, and improvement thrive. So go on, add a dash of continuous feedback to your development process and watch the magic happen!</p>​<br>#agile;#development;#productivity;#project-management;#team-collaboration
The Myth of Bigger Teams: Why Smaller Can Be Better Myth of Bigger Teams: Why Smaller Can Be Better<p>​​​​In an effort to counter inefficiency and increase productivity, organizations often turn to increasing team size. The logic seems sound: more people means more hands on deck to tackle tasks and solve problems. However, this approach can often lead to growing overhead and inefficiencies.</p><p>Research has shown that small teams can often be more effective than larger ones. A study published in Harvard Business Review found that while large teams do advance and develop science, small teams are critical for disrupting it. Another study published in Forbes found that there is an ideal team size at which the benefits of putting more heads together are maximized and the drawbacks minimized.</p><p>So why do smaller teams often outperform larger ones? One reason is that large teams are more likely to have coordination and communication issues. Getting everyone on board for an unconventional hypothesis or method, or changing direction to follow a new lead can prove challenging with a larger group.</p><p>In contrast, smaller teams can be more nimble and adaptable. With fewer people involved, decision-making can be faster and communication more streamlined. This allows small teams to quickly pivot when needed and respond rapidly to changing circumstances.</p><p>This phenomenon is not limited to software development or business settings. In fact, examples can be found across different fields including military operations where smaller units are often able to operate with greater efficiency than larger ones.</p><p>Thus bigger isn’t always better when it comes to team size. Sometimes a highly productive team of 8 senior people can achieve better results than a mixed group of 60. Organizations would do well to consider this when trying to counter inefficiency.</p><h2>Effects of team size on performance</h2><p>But how exactly does this play out in practice? Let’s take a closer look at some real-world examples.</p><p>As more people are brought in to accelerate progress, it’​s not unusual for software development projects to expand in size, a phenomenon known as ballooning. However, this approach can often backfire as communication becomes more difficult and coordination issues arise.</p><p>For example, imagine a project with 60 developers working on different parts of the codebase. With so many people involved, it becomes increasingly difficult for everyone to stay on the same page. Code conflicts become more common as developers unknowingly overwrite each other’s work. Meetings become longer as everyone tries to get up-to-speed on what everyone else is doing.</p><p>Now imagine the same project with just 8 highly skilled developers working together closely. Communication is easier because there are fewer people involved. Coordination issues are less likely because everyone has a clear understanding of what their colleagues are working on.</p><p>In the military, for example, special forces units like Navy SEALs or Army Rangers typically operate in small teams of around 8-10 members. These elite soldiers are highly trained and capable of operating independently from larger units.</p><p>In contrast, traditional infantry units may have hundreds or even thousands of soldiers operating together in large formations. While these units have their own strengths such as overwhelming firepower or logistical support capabilities they may lack the agility and adaptability of smaller special forces units.</p><h2>Automation as an integral part of an organization</h2><p>As companies grow and evolve, it’s important to consider the impact of organizational change on teams and processes. One key area to focus on is automation. By automating tasks and processes, companies can improve efficiency and reduce the need for manual labor. Let’s take a closer look at how automation can affect teams and collaboration.</p><p>Automation can have a significant impact on organizational change. By automating tasks and processes, teams can minimize manual effort and errors, and enhance feedback loops throughout the software development lifecycle. This can lead to smaller chunks of better-quality code releases in less time. Automation can also reduce the need for basic data-input and -processing skills which will be particularly affected by automation.</p><p>The adoption of automation technologies will transform the workplace. Deliberately automating aspects of testing, code styling, integrating, and deploying should aim to reduce the time and human labor needed to develop, deploy and verify the product increment. DevOps automation is applied across the entire lifecycle, including design, development, software deployment, and release, as well as monitoring.</p><p>The primary objective of DevOps automation is to streamline the DevOps lifecycle by reducing manual workload. This automation results in several key improvements: it lessens the need for large teams, drastically reduces human errors, increases team productivity, and creates a fast-moving DevOps lifecycle.</p><h2>Why avoiding larger teams may be beneficial</h2><p>Some common antipatterns may arise when trying to involve more people rather than keeping a small team. As organizations grow in size they may implement measures such as code freezes or external approvals for deployment in an attempt to manage complexity. While these measures may provide some benefits they can also hinder agile development by slowing down decision-making processes.</p><p>They might as well include authoritative behaviors where senior members impose their will on others or create an environment where team members form informal silos within the team based on common interests. This all leads to a lack of trust where team members don’t trust each other’s abilities; this in turn keeps them from delegating tasks effectively. The whole environment just becomes much harder to work in.</p><p>In actuality, the bulk value or result created by a smaller team might be even bigger (let alone cheaper) than the result yielded by a larger yet rigid group. Smaller teams have fewer coordination issues, this allows them to make quicker decisions and deliver faster results.</p><p>When undergoing an agile transformation, companies should consider carefully how they scale agile development across multiple teams in order to avoid unnecessarily large teams. One way companies can achieve this is by creating cross-functional teams which helps reduce the need for scaling agile by merging various departments together.</p><p>Sometimes, however, having large teams becomes a necessity when the product is large and complex. In spite of this, there are frequent cases of software development where teams that could have stayed small if transformation had been done right. In such cases product size is still manageable by a small team, but a large group is now working on it. In such situations companies should aim at creating cross-functional teams, this reduces the need for scaling agile by merging various departments together.</p><h2>Conclusion</h2><p>To wrap up, here are a few basic areas for consideration:</p><ul><li>Conduct a thorough analysis: Before scaling up, teams should conduct a thorough analysis of their current processes and workflows to identify areas that may benefit from additional resources. This can help teams avoid adding unnecessary team members and instead focus on areas where additional resources will have the greatest impact.</li><li>Consider alternative approaches: Teams should also consider alternative approaches to scaling such as implementing new technologies or processes that can help improve efficiency without necessarily adding more team members.</li><li>Automate everything possible: Teams should automate everything necessary to minimize manual effort and errors, enhance feedback loops throughout the software development lifecycle. An effective continuous integration/continuous delivery (CI/CD) pipeline integrates automation tools and workflows an organization needs to build, compile, test and release its applications. Remote development teams cannot rely on end-users to perform robust user acceptance testing. They will need to automate platform, API, functionality, performance, and security testing.</li><li>Develop a clear plan: Teams should develop a clear scale-up plan that should include timelines, milestones and metrics. This can help ensure that everyone is on the same page and working towards a common goal.</li><li>Involve all stakeholders: When considering scaling up, it#39;s essential for teams to involve all stakeholders in the decision-making process to ensure their inclusion. This includes not only team members but also customers, suppliers and other partners who may be impacted by the decision.</li></ul><p>The key takeaway here is that organizations should carefully consider team size when trying to counter inefficiency or improve productivity. While adding more people may seem like an obvious solution it may actually lead to growing overhead and inefficiencies. While there may be instances where expansion is inevitable, disregarding the potential benefits of remaining small can prove to be expensive.</p>​<br>#agile;#development;#productivity;#project-management;#team-collaboration
How Management Buy-In Affects Agile Transformation Management Buy-In Affects Agile Transformation<h2><br></h2><p>Agile transformation can be a powerful tool for businesses looking to improve efficiency, productivity, and flexibility. However, the success of an agile transformation is often tied to management buy-in. As I've written in my previous post, in many cases, the motivation for an agile transformation comes from believing that the current organizational structure is misaligned and that agile will be a cure-all solution. Management may also have unrealistic expectations of the transformation process.</p><p>In reality, management must play an active role in the transformation process, working collaboratively with teams to identify and solve problems. This requires a willingness to hear bad news, make difficult decisions, and address structural and systematic issues that may be inhibiting agility, such as overly complex organizational hierarchies, rigid technologies, and inflexible approval processes. Without this buy-in and active participation, agile transformations can become nothing more than a superficial change with little real impact on efficiency or productivity.</p><h2>Definition of management and leadership</h2><p>There are multiple definitions of what management actually is. Let me cite the two classical ones:</p><p>Harold Koontz: <q>Management is an art of getting things done through and with the people in formally organized groups. It is an art of creating an environment in which people can perform and individuals and can co-operate towards attainment of group goals</q>.</p><p>F.W. Taylor: <q>Management is an art of knowing what to do, when to do and see that it is done in the best and cheapest way</q>.</p><p>So basically, when it comes to transitioning to an agile approach, there are two key takeaways managers need to keep in mind: first, they're responsible for creating an environment where people can be productive, and second, they need to figure out what to do when others are uncertain.</p><p>In addition, it is worth mentioning that although there is an overlap between the skills and qualities of a manager and a leader, they are not the same. A manager oversees and directs a team or organization to achieve its goals and objectives, while a leader inspires and motivates people to work towards a shared vision or goal. Although it is ideal for a manager to also possess strong leadership skills, it is not always necessary for a manager to be a leader as they can still effectively manage a team without necessarily inspiring or motivating them. However, in many cases, having strong leadership skills can enhance a manager's ability to manage their team effectively.</p><p>How does this apply in the context of an agile transformation?</p><h2>Top-down approach to agile transition</h2><p>From what I've seen, a few key attributes are critical for a successful top-down approach to agile transition. Managers must be willing to hear "bad news" and make active decisions in the business's best interests. The <q>average employee</q> in the company needs to be encouraged by managers to identify obstacles and suggest both workarounds and proper solutions.</p><p>To ensure smooth and effective work, managers must make their visions and expectations clear to team members. Although structural changes may hinder progress, it's important to recognize that some changes take time. A shared vision can motivate team members to find workarounds in the interim, while also fostering the belief that higher-level management is actively working towards a long-term solution.</p><p>Having clear orientation, vision, and understanding of context on a higher level can greatly improve motivation, productivity, and the relevance of solutions during an agile transformation. It can lead to more efficient and effective solutions as they are developed with the bigger picture in mind. A sense of direction and a clear vision can be a powerful motivator for people to persevere through challenging times. Like seeing the horizon during turbulent waters, it provides a sense of stability and purpose that can help individuals stay focused and productive. It's the leader's responsibility to ensure such a vision exists and is understood by others.</p><h2>Don't take it personally</h2><p>Managers who resist hearing strategic-level criticisms can hinder the progress of agile transformation. It's important not to take it personally. The broader the problem, the more difficult it is to resolve. Attempting to fix it carries both risk and reward, which is why the agile transformation was initiated in the first place.</p><p>When managers view criticism or obstacles as a cover for employee incompetence or failures, it can create a lack of trust that hinders effective management. This can lead to a tendency to micromanage and excessively monitor employees, which can ultimately undermine all the transformation efforts. Eventually, a lack of trust can lead employees to keep their ideas to themselves to avoid potential conflicts or arguments with their managers. This can hinder creativity and innovation and create a toxic work environment where open communication and collaboration are discouraged.</p><p>It's crucial for managers to actively participate and collaborate with their teams, facilitating problem-solving and decision-making instead of expecting the teams to sort everything out themselves. Some obstacles are outside the control of individual teams and require higher-level interventions or support from the organization.</p><h2>Make decisions - that's what leaders are supposed to do</h2><p>Decision-making in a business context involves a shared responsibility between managers and lower-level colleagues. Effective managers take responsibility for their decisions, even in the face of uncertainty. They actively seek out the information they need to make informed decisions and recognize that some situations may not have enough information, yet still require a decision. In contrast, some managers may try to shift responsibility elsewhere rather than taking ownership and accepting accountability for their decisions in such situations out of fear of failure. It is essential for managers to understand that managing uncertainty is a critical part of decision-making and to accept this responsibility. Lower-level colleagues play a crucial role in facilitating decisions by providing valid, precise, complete, and most importantly honest information.</p><p>To handle critical decisions, organizations can foster a culture of experimentation and testing or establish a structured approach to collect and analyze data for making informed decisions. By exploring various scenarios of potential outcomes, measuring their impacts, and proactively engaging with such models, organizations can break free from this pattern.</p><p>Effective managers approach decision-making with a healthy dose of skepticism, validating and cross-checking data before making any commitments. This also applies to creating plans and commitments during the sales process. It's important to note that the criticism and ideas for improvement from individual teams may not just involve structural and technical aspects but also target plans. A common pitfall is when experts are not involved in the sales and planning process, resulting in unrealistic plans. In such cases, the team should not be held accountable for being unable to adhere to an unrealistic plan. Creating such a plan is a decision that involves risk, which managers are responsible for evaluating, managing, and accepting. Agile transition might painfully expose such naive plans.</p><p>Delegating competence and responsibility is an essential aspect of effective management. However, it's important to note that managers should also be willing to accept the consequences of delegation.</p><h2>Overcoming fear and lack of trust</h2><p>The fear of change can often hinder the agile transformation process, and many managers may be hesitant to make changes due to various fears that are common to any human being. These fears include fear of failure, fear of the unknown, fear of losing control, fear of job security, fear of being exposed as incompetent, fear of losing status or power, fear of conflict or opposition, and fear of the extensive changes required by the agile transformation process. However, effective managers and organizations are able to recognize and manage these fears, while still moving forward with the necessary changes to improve outcomes. It is important not to take these fears personally, but instead to approach them with a solution-focused mindset - because paralysis may be the other option.</p><p>Fear and lack of trust can be significant barriers to organizational success, particularly during a transformation toward an agile culture. Although these feelings are valid and may have justifiable reasons, they can ultimately hinder progress. For an organization to move forward and become more effective, it is essential to foster trust, delegate competencies and responsibilities, and empower employees to make decisions. Most individuals are naturally motivated by changes that save time and effort, and a culture of trust and collaboration can facilitate this motivation toward achieving organizational goals.</p><p>By fostering a culture of trust and collaboration, organizations can overcome fears and barriers to agile transformation and empower employees to take actions that save time and effort.</p>​<br>#agile;#project-management;#team-collaboration;#scrum
Truly embrace asynchronous work embrace asynchronous work<p>​​In 2020 we experienced the most significant office exodus that forced people to work at home. Many of them found enough strength to resist the temptation of PlayStation and figured out ways to reclaim their time, focus, and get a massive load of work done. Isolation has one great advantage as it provides an opportunity for <b>uninterrupted productivity</b>. No manager can barge into your home office to schedule an impromptu status meeting. The time you spend working is genuinely yours. </p><p>The forced isolation is now over and we can choose our workplace. Some have remained at home while others return to the office for various reasons, such as having kids at home or their spouse being a manager. Having part of the team work on-site and part working remotely comes with its own challenges, but more on this hybrid scenario later.</p><h2>The return to the office</h2><p>Forcing people back to the office may backfire. They have gotten used to controlling their schedules and are reluctant to go back to the old days. Remote work has become popular and opened borders, so looking for a new job, even abroad, is easier than ever. The same applies the other way around: you can hire talent everywhere, not just in your office's physical location.</p><p>One argument for returning to the office is that people have better working discipline there than at home. It's up to anyone to decide which place has more disruptions and choose accordingly. Looking at a typical modern office with table footballs, drum hero sets, and four dogs chasing each other in a gigantic shared open space where people without noise-canceling headphones are doomed is debatable, at the very least. But it all boils down to trust. Do you trust your employees to work productively without a manager behind their backs? If not, you should be more considerate about hiring decisions rather than where people choose to work.</p><p>Adapting and allowing office and remote worlds to coexist makes a lot of sense: let people work from where they feel the most productive, and they will reward you with doing exactly that. It's OK that it still might be the office for some. You can benefit from the advantages of remote practices with part of the crew on-site and part remote. Some refer to it as a hybrid approach, but that’s not entirely on point.</p><h2>Asynchronous practices</h2><p>Let's rip the band-aid off quickly. There's no hybrid approach! Only an environment where applied asynchronous practices enable cooperation between on-site and remote people. Nothing else in between makes sense, as it only leads to the neglect of one group or the other. The same conditions and rules must apply to everyone, regardless of location. Asynchronous practices not only help connect the two worlds but also significantly improve productivity for office work. Here are a few tips.</p><p><b>Create and maintain a calm environment</b> so people can focus and not be disturbed for as long as they wish, regardless of the physical location. At home, we often set rules for when we don't distract each other. Why can't we do something similar in the office, the place set up for work in the first place?</p><p>Set boundaries and don't tap on people's shoulders if you need something. Imagine the person next to you is working from a different country and you can't contact them physically. Approach them asynchronously. If they don't reply, chances are they are focusing on something and the last thing they'd want to do is pause everything and talk to you in person. Don't rip people away from their thoughts because of your fantasy of urgency. It might not be as pressing as you perceive it to be.</p><p>The same rules apply to online space: don't go around your messaging app and expect people to react instantly. Some managers abuse those tools as an utterly unnecessary control mechanism to check if people are working. The chat app is not where the work gets done. Feel free to turn it off if you need to focus on something more substantial. </p><p><b>​Knowledge must be shared</b>. It's far from enough that it's been said in a meeting room. Verbal knowledge sharing is a no-go; remote people will be clueless and office people will forget. You must define and learn to use a well-known single source of truth. If you fail to do so, you only create space for assumptions and friction.</p><p>Plenty of project management software is here to help but choose wisely. If you don't, you will end up with three different messaging apps and another three for documentation, design, and progress tracking. That makes the single source of truth, well, not that much single. It also further invites an opportunity for focus disruptions.</p><p> <b>Knowledge must be comprehensive</b>. It doesn't suffice that it's written. Not only do others have to understand what you meant, but also your future self. Try to put yourself in your reader's shoes and re-read your writing. Does it answer questions, or does it raise more than it's necessary? </p><p>Some people, often those responsible for technical analysis (or writing horoscopes), think adding an obfuscation layer to the natural language is a great idea, making them sound more professional. What ends up happening later is that some poor soul has to decipher the gibberish leading them to a quest to find the original scroll with the ancient knowledge. This is work, not a role-playing game. If you expect a human to read what you wrote, write like a human.</p><p> <b>Leave people alone to do their work and share well-written knowledge. </b></p><p>The practice imposes extra discipline on a team, but you won't want to return once you start seeing the benefits. I'd go to great lengths to argue that you should opt for those rules even if your whole team works on-site. Let's now address the two remaining elephants in the room.</p><h2>Meetings and managers</h2><p>Meetings and their human equivalent, managers, are the two most influential relics of the old age and arch-nemesis of uninterrupted productivity. There is still a place for both, but the sooner we forsake the established office routine, the smoother the transition to an asynchronous and productive world will be.</p><p>Programmers work by organizing the thoughts they later output in the source code form. They often do that independently of each other and commit work additions asynchronously, so remote practices feel closer to them and accepting them is more straightforward. Managers, on the other hand, might feel out of their element in this asynchronous world.</p><p>Managers do not directly create value. Their most significant addition is removing barriers for the workers that do. A good manager shields others from the irrelevant to allow them to spend as much time as possible doing what they do best. Let designers design and programmers program. There's no value in keeping people verbally hostage in a meeting, but there is great value in doing the opposite.</p><p>This requires a mind shift, but there's a silver lining once you realize you employ self-organized people who don't need micromanaging and can work without much oversight. This shift frees managers and allows them to focus on the topics where they might contribute to the process meaningfully. There is no room for ego and certainly not for the illusions of authority—forget the management manuals of the 1990s. </p><p>People don't go around wondering who, for instance, van Gogh's project manager was. On the contrary, some jokingly speculate the famous painter cut off his ear when he received a letter with yet another meeting invite. But little did he know that meetings might also make sense in an asynchronous work environment.</p><p>There's just a different approach to organizing them. Instead of summoning a group of 15 people into an hour meeting, it can go like this:</p><ol><li>Write an agenda and briefly summarize the reason for the meeting.</li><li>Then write questions asking for answers that can solve some specifics.</li><li>Send out these questions. </li><li>Wait for answers.</li><li>Don't have the meeting.</li><li>Repeat.</li></ol><p>Organizing your thoughts using the written word helps you understand the issue and alleviates the fear of the unknown. It creates newly found insight that you can easily share as a valuable contribution. Writing down a problem forces you to understand it comprehensively. This process can sometimes be done independently without wasting the time of others.</p><p>In some cases, however, a synchronous meeting can be more productive. A quick pair programming session or a chat with a designer is practical now and then. But limiting the number of participants to those concerned with the topic is as essential as avoiding full-team calls where three-quarters are just muted passive spectators doing their laundry in the next room.</p><p>Could it really have been just an email? It might not be in some cases, and that's fine too. But be honest about your intentions and don't take other people's time off their hands lightly. Think twice if conducting numerous meetings isn't just a way to give the impression of being occupied. Time spent in a meeting is the time not doing the actual work.</p><h2>Writing</h2><p>The backbone of remote work is writing. The ability to express your thoughts is essential regardless of your position. It's a craft that gets better and easier the more you do it, and opportunities to practice are plenty: toots, tweets, daily standups, project READMEs, and even chat messages.</p><p> <b>You can also write a blog post for your company!</b></p><p>Writing is also a transferable skill. You can change a team role, a company, or even an industry and still benefit from writing well. No one can take that away from you.</p> <br>#productivity;#team-collaboration
How flawed motivations can derail Agile transformations flawed motivations can derail Agile transformations<p>Agile transformation has become a buzzword in the business world. Companies are eager to jump on the bandwagon and adopt Agile methodologies. The belief is that Agile transformation will increase productivity, efficiency, and speed, simplifying everything and making it faster. While this can be the case when done right, if the sole motivation for Agile transformation is focused on these outcomes and the company has a delusional idea about how difficult it will be to achieve them, things will go south. It's always a lot bumpier than anticipated.</p><p>This post is part of a series about the most common Agile transformation pains, as I've witnessed them in the organizations around me. This series focuses on the top-down hindrances. </p><h2>Speed, efficiency, transparency</h2><p>What's incorrect about the motivation mentioned above? Don't efficiency, effectiveness, transparency, flexibility, and speed embody the characteristics that the Agile culture promises?</p><p>In my view, the reason it falls short is that it lacks a crucial and integral aspect of Agile methodology, which is the concept of <q>failing fast</q> and promptly identifying and showcasing obstacles and challenges impeding progress. A true willingness to find problems sooner and improve collaboration must also be an integral and true part of the motivation.</p><p>The misconception I mentioned is problematic because it creates unrealistic expectations for what agile can achieve. Agile is not a quick fix for organizational problems. It's rather a fundamental shift in the way a company operates. It is a way of working that requires collaboration and a willingness to adapt. Everyone, including the senior management, must be willing to collaborate with teams to improve the environment for Agile work. The whole motivation stems from the belief that problems are caused by the disorganization of teams and wrong organizational structures.</p><h2>Transformation project - its end is just the beginning</h2><p>Regrettably, Agile transformation is often viewed by management teams as a silver bullet solution to a company's organizational issues. They mistakenly perceive it as a short, one-time investment that will provide immediate and long-lasting benefits. This misconception can lead to an overly simplified approach to Agile transformation, which does not consider the ongoing effort required to sustain it. Agile transformation requires continuous effort and commitment from both management and the teams involved.</p><p>Many managers mistakenly believe that adopting Agile is as simple as calling it a transformation project, allocating a budget, giving the project a fancy name, hiring consultants, and conducting a bunch of trainings. They think that these actions alone will suffice to achieve the transformation and their job is done. People just pat themselves on the back for renaming project managers as scrum masters and officially closing the transformation project. And then they sit back while the teams <q>self-organize</q> and Scrum Masters magically remove all obstacles. But that's not how it works. </p><p>Organizations often face structural and systematic problems that impede their agility. Every company has some - just their depth varies. These issues can manifest in various ways, including overly complicated organizational and decision-making hierarchies, dependence on inflexible technologies, convoluted deployment procedures, and rigid approval processes, just to name a few typical ones. </p><p>For example, a company that releases software updates twice a year with numerous dependencies, code freezes, centralized testing, and lengthy development-testing-acceptance loops will likely encounter significant obstacles when adopting Agile methodologies. The legacy processes and technology stack may be quite incompatible with Agile workflows, making it a challenge to achieve the desired level of flexibility and speed.</p><p>These inherent problems won't magically vanish during an Agile transformation - they'll just become painfully obvious and urgent. The good news is that teams will finally feel comfortable talking about them and trying to tackle them head-on. Problems will be found everywhere.</p><h2>Beware of creating a Potemkin village</h2><p>The flipside is that if this is not expected to happen, the whole transformation won't work. One must be willing to hear the <q>bad news</q> and be ready to make proactive decisions.</p><p>After years of simply accepting the problems, teams will suddenly start shouting from the rooftops about these issues, and senior management needs to step up and work with them to make the workplace more agile-friendly. If they don't, teams will remain stuck in a rigid environment. Everyone will just call himself with a new title, such as product owner or Agile coach. This reorganization is likely to be seen as <q>another waste of money</q> and a failure, with many concluding that <q>Agile doesn't work</q>. A Potemkin village.</p><p>All levels of an organization need to be ready to face these challenges and work together to find solutions. A decision to adopt Agile is just the first step. Even the managers must be ready to roll up their sleeves and get involved in identifying and solving problems that arise during the transformation. It's a team effort, and everyone needs to play an active role. The more complex the business structure is, the longer the whole transformation will likely take. This is an ongoing process that is unlikely to ever come to a complete end. But the deciding factor is if there's actually a will to start and keep undergoing an uncomfortable change.</p><p>One surprising fact about Agile transformation is that it might lead to more bureaucracy if not implemented correctly. For example, suppose a company adopts Agile without addressing underlying issues such as convoluted decision-making processes or rigid approval procedures. In that case, it may inadvertently create more bureaucracy by adding more layers to the process. This is because Agile requires constant communication and collaboration, and if these processes are not streamlined, it can result in even more delays and inefficiencies.</p><h2>True motivation: A sense of security</h2><p>In my experience, failed attempts at agile transformation often stem from a common underlying issue: a lack of trust. This can manifest in various ways, such as a tendency to monitor and control teams closely. After one such transformation I've seen teams being required to share their sprint commitments, burn-down charts, and velocities, and then having to explain themselves when they don't meet those metrics. This happened at the senior management level.</p><p>Such reporting activity created a false sense of security by prioritizing the appearance of stunning charts and numbers on paper rather than the actual value of the work being done. The focus was on keeping commitments rather than questioning the sense of those commitments and the overall plans. Needless to say, what was missing was a critical examination of the actual business value of the effort invested and the value of the things developed. So it was quite obvious what the true initial motivation for Agile adoption had been.</p><h2>Do you really want to go Agile?</h2><p>In conclusion, Agile transformation can be a powerful tool for organizations looking to improve their productivity, efficiency, and speed. However, it is essential to approach it with realistic expectations and a willingness to address underlying structural and cultural issues. Agile transformation is not a quick fix or a one-time investment but requires continuous effort and commitment from all levels of the organization. Managers must be ready to roll up their sleeves and work with their teams to identify and solve problems that arise during the transformation. </p><p>Furthermore, it is crucial to approach the transformation focusing on business value and not just metrics and appearance. So, before embarking on the journey of Agile transformation, think twice and ensure you are willing to fully commit to the process. Going Agile is about being able to react more fluidly to changing business circumstances, isn't it? If there's little willingness to address the underlying issues that hinder progress, what's the point of identifying them in the first place? That by definition hinders the fluidity from happening.</p><p>If fundamentally changing an organization, including its core cultural, technical, and process aspects for the better, isn't the honest motivation, then maybe it will be more comfortable to maintain the status quo and save the embarrassment that an attempt to perform an Agile transition would inevitably bring.</p>#agile;#productivity;#project-management;#release-management;#scrum;#team-collaboration
Challenges of Agile Development with Fixed Contracts of Agile Development with Fixed Contracts<p>In today's fast-paced business world, clients are constantly seeking the best of both worlds: the flexibility and speed of agile development, as well as the perceived safety of fixed-time fixed-price contracts. This trend of blending agile delivery with fixed contracts is becoming more and more prevalent as clients aim to find a balance between agile freedom and contractual security.</p><p>One potential reason behind this trend is that clients may be hesitant to enter into a lease agreement with a development team and instead opt for a fixed-time contract. This uncertainty may stem out of the unknown, a belief that a fixed contract offers more security for the scope of work, doubts about the supplier's ability to deliver on the agreed scope, or the client's own internal processes that prevent them from entering into such agreements.</p><p>This post covers such a hybrid model from the supplier's perspective.</p><h2>Uncovering the pitfalls</h2><p>When implementing an agile approach with a fixed-time fixed-price contract, a common structure involves a product owner from the client company. This dynamic can bring its own unique challenges as the supplier company is bound by the scope and price outlined in the contract, with the product owner significantly impacting the return on investment. In this scenario, trust is of the utmost importance as the supplier must rely on the product owner to make well-informed decisions regarding the project's direction and priorities.</p><p>One of the main risks for the supplier associated with this approach is the potential to deviate from the contract scope. Suppliers may want to do so to accommodate the client's requests and be more agile. However, as the contract is legally binding, the client may take advantage of this deviation and exert pressure on the supplier team. This poses a significant threat to the project's financial success as the supplier team may have already allocated budget towards items requested and discovered during the course of the project, leaving the client in a position of power and potentially exploiting the supplier team to the detriment of the project's outcome.</p><p>Furthermore, the typical behavior of a product owner in this situation is to focus on completing one feature area (epic) before moving on to the next rather than maintaining constant prioritization. This can lead to the desire of perfecting everything before progressing, causing further delays to the project and potentially damaging the supplier's budget. On the other hand, suppliers may have to fit the project budget at all costs, resulting in a loss of quality. The combination of both phenomena can be deadly.</p><h2>Balancing Flexibility and Control</h2><p>Balancing the complexities of agile development within the constraints of a fixed-time, fixed-price contract can be a challenging task. From a supplier's perspective, effectively balancing the benefits of agile delivery with the security of a fixed contract requires a strategic mindset from the very beginning. One common trap is for the supplier to overestimate the control of the product owner over the project scope without involving the development team in the process. To avoid this, it is essential to engage in ongoing negotiations about how newly prioritized items will affect the original scope and what to deprioritize. </p><p>The main motivation of the business relationship described is to deal more effectively with unplanned and unexpected work. Maintaining transparency about unplanned scope items that have been delivered and what needs to be exchanged is crucial. By implementing these practices from the beginning, the mindset of "trading" one item for another can become ingrained in the team's nature and working style.</p><p>It's also vital that the client understands from the outset that while an agile approach brings added flexibility in making the product more relevant and potentially better, it does not equate to a wildcard for obtaining more for less. The responsibility for decision-making goes hand in hand with this approach and must be made clear by the supplier's team. Furthermore, involving the development team in the process is crucial to ensure that the project stays on track. The team should be responsible for providing rough estimates of newly discovered items, allowing the product owner to make more informed decisions about prioritization.</p><p>Ultimately, managing scope in fixed-time fixed-price contracts relies heavily on a mutual understanding between the client and supplier. Therefore, honesty and transparency are crucial for the success of this approach. The supplier must provide realistic and accurate estimates for newly discovered items and be transparent about any obstacles or issues that arise during the project. Tracking development velocity may also be beneficial. In return, the client must be honest about their expectations and priorities and be willing to make trade-offs to keep the project on track.</p><p>Building trust through honesty and transparency is key to the success of this approach. Furthermore, having a solid understanding of the client's business and goals can help the supplier team to better align the project's scope and priorities with the client's needs and anticipate any potential roadblocks or challenges that may arise during the project.</p><h2>Make the contract work in favor</h2><p>Navigating the choppy waters of agile development with fixed contracts may seem like a breeze at first, but in reality, it takes a steady hand and discipline to steer the ship toward success. Creating a successful contract for agile development with fixed-time fixed-price contracts requires a balance of flexibility and control. As a supplier, it's important to approach the contract with a defensive mindset, taking into account that clients may not always be upfront about their expectations or try to expand the scope. Here are some key points to keep in mind:</p><ul><li>Be cautious when crafting the scope and contract, being aware of scope items that are prone to inflation, and carefully formulating them in the contract. Clearly state that anything outside of the scope is considered a change request, and anything not explicitly mentioned is out of scope.</li><li>Use the difficulty of defining a comprehensive scope in an initial contract to your advantage by stating that nothing not explicitly mentioned in the contract is included, which can level the playing field and motivate the client to be fair when trading new items for the original scope.</li><li>Create flexible payment milestones that can accommodate changes in the scope and maintain cash flow. For instance, the milestones can be triggered once a scope worth X gets finished.</li><li>Describe the roles and responsibilities of key stakeholders from the client, such as the product owner, key users, and testers, to ensure smooth and efficient communication and decision-making throughout the project. This includes specifying that decisions and feedback must be provided quickly to avoid delays and blockages on the supplier's end.</li><li>Such definition should include the process for acceptance and sign-off of scope items throughout the duration of the contract, rather than waiting until the end of the project to ensure efficient progress and increase transparency.</li><li>Clearly define general acceptance criteria for scope items and require a continuous client testing and acceptance process throughout the project.</li><li>Keep in mind that the client company may try to enforce delivery of the entire defined scope while diminishing the value of the items developed extra, and make sure the contract reflects that.</li></ul><p>In conclusion, while combining agile development with fixed-time fixed-price contracts can be tricky, it can also offer benefits for both parties. The contract should be viewed as a framework, keeping the development team working within a certain timeframe. The supplier should be mindful in formulating the scope items, making it specific enough for the client to have an idea of the product but not so strict that it limits the supplier's flexibility. Furthermore, trust and open communication between the client and supplier are vital in ensuring the project's success. It's important to be prepared for the fact that the client may try to enforce the original scope and to write the contract with that in mind. It's important to remember that the contract should serve as a backup plan in case things don't go as planned. But from experience when a contract gets pulled out and evaluated along the project, it is a telltale sign that the project is already in severe trouble. Thus the primary focus should be on building mutual trust through transparency and honesty. This approach is the most effective for successful long-term project outcome for both parties.</p><p>Still, there is no doubt that using a traditional agile delivery contract by hiring a team of experts is usually more beneficial for all stakeholders than adopting a hybrid approach when the situation allows.</p> ​<br>#agile;#project-management;#release-management;#scrum;#team-collaboration
Architectural missteps in view, presentation, and navigation missteps in view, presentation, and navigation<p>​​Every system and architecture tackles the test of time. It's an unfair battle, almost impossible to win. That doesn't mean we should surrender and hack unsustainable components without the ambition of longevity. We must develop them to deal with this challenge gracefully and try to defer the inevitable as long as possible.</p><p>Nothing lasts forever, though, especially in a fast-moving industry like mobile app development, and some missteps are bound to bubble up along the way. Let's define the most common and explain possible ways to avoid them.</p><h2>Overly logical view</h2><p>Let's start with an obvious one, an arch-enemy to any solid architecture<span style="color:#000000;"><span style="font-size:11pt;font-family:roboto, sans-serif;color:#0e101a;vertical-align:baseline;white-space:pre-wrap;">—</span></span>a view that does way too much.</p><p>The view is an excellent, self-describing name for a software component. Its purpose is <i>to view</i> what's happening inside the system in a user-comprehensive, preferably friendly way. It renders to the screen, listens for content updates, and delegates events to someone else to handle.<br></p><p>When there's a need for an extensive user-interface redesign, it's the view's role to step up, take all the heat, and keep all the vital bits of the application unchanged. It's a straightforward process, as no important presentation or business logic gets in the way.</p><p>That's an example from an optimal world where the view is a thin layer that does just the minimal job it should. Yet some programmers complicate the layer with additional logic, like persistence, state management, or navigation. Those should have their foundation elsewhere, and it's no surprise that dealing with all this extra complexity might prolong redesign estimates from a few days to a couple of months.</p><p>As system and platform designers, Google or Apple aren't leading by example either. On the contrary, they encourage programmers to place too much weight on their views' shoulders by providing them with components that require such an approach. One example for all: the FetchRequest property wrapper, defined in SwiftUI, fetches entities straight from the Core Data store. To quote usage from docs: "<i>Use a FetchRequest property wrapper to declare a FetchedResults property that provides a collection of Core Data managed objects to a SwiftUI view.</i>" Ironic slow clap for encouraging programmers to couple views with data storage.</p><p>There are plenty of wolves in sheep's clothing, so keep your guard up and remember<span style="color:#000000;"><span style="font-size:11pt;font-family:roboto, sans-serif;color:#0e101a;vertical-align:baseline;white-space:pre-wrap;">—</span></span>just because you can doesn't mean you should. Your view should preferably not do much. The thinner the view layer is, the better. UI tends to change quite often, and keeping the view layer lean is a good practice for making swift and safe changes.</p><h2>Almighty view models</h2><p>As part of the presentation layer, view models are responsible for formatting content for the view and handling its events. It should be a comprehensive component, a little helper for the view, listening for changes, and handling presentation logic that lightens the load for the view.</p><p>Usage varies per project, but typically, it observes an application's state, transforms it into user-presentable data, and notifies the view. Unlike views, they are independent of UI frameworks, which makes them easily testable. That's not just icing on the cake but a massive step towards robustness.</p><p>However, they are often misunderstood and create a cesspool for what didn't fit elsewhere. So it happens that they handle business logic, navigation, and all other bits that don't have an official place elsewhere. Some scoundrels even compose requests and deal with networking! That's wrong on many levels; it defies the separation of concerns and tries to fit multiple components into one. This misplaced logic is not reusable and complicates further development on top of that. Such view models span hundreds of lines and compel us to recall massive view controllers from the Objective-C era.</p><p>Overly bloated view models are often present in architectures designed by proponents of MVVM who, in naive pursuit of simplicity, argue that three-layered architectures should easily cover all needs. Simplicity is, without a doubt, one of the goals, but the multi-hundred-line view model is anything but simple.</p><p><b>MVVM is not an architecture.</b> It's a pattern describing how to structure the application’s presentation layer. It would be unwise to build a complete application around any pattern. Why should MVVM be an exception?</p><p>Should you find yourself struggling with where to put something in codebases where the MVVM pattern serves as an architecture of the whole system, you might be on the right track. Navigation, networking, business logic, and many others don't have a well-defined place in incomplete architectures. You can lift the burden from view models with proper <a href="/Blog/Pages/application-domain-modeling.aspx">domain modeling</a>, define a spot for all those other concepts, name them, and be one step closer to a clear and comprehensive design.</p><h2>Lost in navigation</h2><p>In the early days of mobile application development, we didn't emphasize navigation much. Widely adopted architectural patterns such as MVC or MVP didn't have a letter in their name designated just for navigation, so we solely used system components such as UINavigationController, Activity, and Fragment, respectively, Storyboard segues. But these are massive system frameworks mainly “designed” for UI presentation. Their basic use complicates the view and further couples with the interface builder (used for scene designing) in the worst case.</p><p>Fortunately, things have gotten a lot better in the last few years, and with architectural enlightenment have come plenty of new designs. Some have even had their opinion or designated components on how to handle navigation. That's how coordinators, wireframes, flow controllers, and so on came to be. However, extracting the navigation into its place has revealed issues hidden in plain sight, such as sharing data between the screens. Some architectures do address this, but it is often neglected or misunderstood, so state propagation becomes another navigation responsibility.</p><p>The state dramatically complicates the situation for everyone involved in navigation. It must be obtained from the call site and passed to the next scene, which decides where to store such an incoming state. And it doesn't just end there. Once you wish to return to the previous scene, you need to take the state back with you and decide whether or not to replace the last one. That doesn't sound very easy, even for small-scale apps; imagine making sense of this in an app with hundreds of screens.</p><p>When you take a step back, however, you will notice that it is not so much a question of navigation. The problem is in state propagation and its coupling with navigation.​ <a href="/Blog/Pages/swift-ui-and-architecture-state.aspx">Decoupling state to its place​</a> significantly improves usability, testability, and simplifies navigation. It also makes it clear as to who owns the state and where the source of truth is.</p><h2>Architecture-agnostic</h2><p>The post might seem to focus more on a separation of concerns than architecture, but those two go hand in hand. Once you realize the bloated multipurpose components are too hard to tolerate, you start to look for something more cultivated than three-word patterns dressed as architectures. More layers do not equal more complexity. They bring order, and clarity, and leave no place for presumptions (which lead to unwelcome pull-request surprises and heated discussions).</p><p>The resulting product is not the only and most important value we produce. By making the software genuinely soft, we can deliver continuously, with the same effort, and in the long run. That's an essential feature valued in any field by any business.</p> ​<br>#architecture;#view;#presentation;#navigation
Application domain modeling domain modeling<p>Software projects are about telling computers what people want to do. Programmers are the ones who speak the computer language, but ordinary people aren't predestined to think and communicate the way a computer does. They are usually good at telling what they want to achieve and what is the purpose. Then it's the programmer's task to translate the purpose into computer language.</p><p>This arrangement leads to an unintended limitation. When a person needs to tell something to a computer, they need a programmer. When people need information about computer behavior, they need to ask a programmer. Programmers are a bottleneck in this process.</p><p>But what if we can design the project so the code is understandable even for ordinary people?</p><h2>Enter the domain</h2><p>A domain is a part of every project that does the important things. The business logic resides there together with industry rules and policies. The domain must be articulated unambiguously for everyone.</p><p>The domain shouldn't be too technical. There should not be transactions, exceptions, wrappers, or gateways. Ordinary people do not understand these terms but need to understand the domain. Although programmers understand these technicalities, they are ambiguous, and two programmers may imagine a different mechanism under these terms.</p><p>The domain should be full of real-world objects. We should see purchase orders, money amounts, other people, or actual goods. These objects can be virtual, like card transactions, but need to be recognizable to everyone.</p><p>Kotlin exhorts for readable code. This is one of its main characteristics. And we can use it to model our domain.</p><p>The real-world objects are usually modeled as <span class="pre-inline">data class</span> with read-only properties. Any modification needs to be done by a generated <span class="pre-inline">copy()</span> function that prevents unintended state updates or inconsistencies.</p><p>Some objects or data items like Social Security Numbers are so simple that one may tend to represent them as a primitive type like <span class="pre-inline">String</span> or <span class="pre-inline">Int</span>. This is good for program efficiency, but a person may unintentionally swap it with some other information of the same primitive type and introduce a severe error. To overcome this, we may introduce a <span class="pre-inline">data class</span> to wrap the information and give it a unique type. This will work, but its overhead may consume an unacceptable amount of resources when used at a larger scale. Kotlin <span class="pre-inline">value class</span> is a great fit for such use cases. It assigns a unique type to a simple data item while still keeping its memory footprint small.</p><h2>Domain actions</h2><p>Domain objects are important, but they are useless unless we can take action with them. A purchase order is to be placed or canceled. A parcel with a new pair of shoes is to be shipped or claimed. And we need to model these actions as well.</p><p>The first thing is the name. <span class="pre-inline">Action</span> in programming is quite an overused, and generic term and it does not work well for us. Some teams name them <span class="pre-inline">Interactor</span> others use the term <span class="pre-inline">UseCase</span>, or <span class="pre-inline">Actor</span>. We will use the term <span class="pre-inline">UseCase</span> for the rest of this post.</p><p>A use case is defined as a single function with explicit input and output. Use cases have no state and can be called multiple times. Let's try to define them in Kotlin. </p><p>It would be nice if a <span class="pre-inline">UseCase</span> may have a single input and single output so we can define a base type for all use cases with inputs and outputs defined as generics. But in the real world there are actions that may have more inputs, so this is not feasible, is it?</p><pre><code class="kotlin hljs">class FindDriverUseCase { fun execute(position: Coordinates, destination: Coordinates) } </code></pre><p>This approach will work technically, but it does not tell the whole story for people unfamiliar to the context.</p><p>Introducing a specific type for use case input will actually help to understand the context and works as an extension point for further feature evolution.</p><pre><code class="kotlin hljs">class FindDriverUseCase { fun execute(input: PotentialRide) } </code></pre><p>Great, after using this approach for a while, you'll realize that some use cases have their input and output optional. That's fine, Kotlin has built-in nullability in the type system, doesn't it?</p><pre><code class="kotlin hljs">class FindStoresUseCase { fun execute(input: Country?): List<Store>? } </code></pre><p>The use case finds all our company stores. We may want to get a list of all of them or to filter them by a given <span class="pre-inline">Country</span>.</p><p>The definition of input as <span class="pre-inline">null</span> on the use-site is not very understandable in this case. Also, it is hard to guess what <span class="pre-inline">null</span> as returned result actually means. A little bit more modeling will fix this:</p><pre><code class="kotlin hljs">sealed interface For { object AllCountries: For data class SingleCountry(val country: Country): For } sealed interface StoresResult { object NotAvailable: StoresResult object OutOfSync: StoresResult data class Available(val stores: List<Store>): StoresResult } class FindStoresUseCase { fun execute(input: For): StoresResult } </code></pre><p>It seems to be a good idea to deny the value <span class="pre-inline">null</span> as use case input or output at all. Let's introduce a base type and force the generics to be based on <span class="pre-inline">Any</span> that effectively forbids <span class="pre-inline">null</span>: </p><pre><code class="kotlin hljs">interface UseCase<in Input: Any, out Output: Any> { fun execute(input: Input): Output } </code></pre><h2>Actions namespace</h2><p>Quite often, we have a few use cases working with similar objects:</p><p><span class="pre-inline">SubmitPurchaseOrderUseCase</span>, <span class="pre-inline">CancelPurchaseOrderUseCase</span>, …</p><p>These class types may quickly pollute the project's namespace and make it hard to navigate.</p><p>We should try to group them somehow under a shared namespace. Kotlin doesn't have support for namespaces (<a href="">yet</a>). We can supersede it by grouping the use cases under a single <span class="pre-inline">sealed interface</span> for this purpose. You can use <span class="pre-inline">sealed class</span> or <span class="pre-inline">object</span> as an alternative, but the memory footprint would be slightly bigger.</p><pre><code class="kotlin hljs">sealed interface PurchaseOrderUseCase { class Submit { … } class Cancel { … } } </code></pre><h2>Kotlin call site</h2><p>Now let's look at the call site:</p><pre><code class="kotlin hljs">val purchaseOrder = PurchaseOrder(...) val submitPurchaseOrderUseCase = PurchaseOrderUseCase.Submit() val result = submitPurchaseOrderUseCase.execute(purchaseOrder) </code></pre><p>We can polish it with a little trick called Invoke operator. When a Kotlin function named <span class="pre-inline">invoke()</span> is marked as <span class="pre-inline">operator</span>, its invocation may be replaced by the use of <span class="pre-inline">()</span> operator.</p><p>When applied to our base type</p><pre><code class="kotlin hljs">interface UseCase<in Input: Any, out Output: Any> { operator fun invoke(input: Input): Output } </code></pre><p>the call site can be simplified to</p><pre><code class="kotlin hljs">val purchaseOrder = PurchaseOrder(...) val submitPurchaseOrder = PurchaseOrderUseCase.Submit() val result = submitPurchaseOrder(purchaseOrder) </code></pre><p>Notice the use case instance name change, where the <span class="pre-inline">UseCase</span> suffix has been omitted, and its invocation now looks like a standard function call. If it is used in an obvious context, we may shorten the use case instance variable name even more and call it simply <span class="pre-inline">submit(purchaseOrder)</span>.</p><h2>Swift call site</h2><p>Until now, we were only calling our use cases from Kotlin code. On Kotlin Multiplatform projects, it is common to share the domain logic between all targeted platforms. Let's check how a use case may be used in another language. We will take the example of a mobile application implemented both for Android in Kotlin and iOS in Swift.</p><p>First, let's try to call it the same way we do in Kotlin.</p><pre><code class="kotlin hljs">val submitPurchaseOrder = PurchaseOrderUseCase.Submit() val result: SubmitResult = submitPurchaseOrder(purchaseOrder) </code></pre><p>This code has two major problems. The invocation operator is unavailable, and the result is not of type <span class="pre-inline">SubmitResult</span>. Let's start with the latter one.</p><h3>Swift generics</h3><p>Generics in swift are available only for <span class="pre-inline">class</span>, <span class="pre-inline">struct</span> and <span class="pre-inline">enum</span>. A very similar thing for <span class="pre-inline">interface</span> is called associated types, but its characteristic is incompatible with Kotlin generics.</p><p>This is why Kotlin Multiplatform has Swift generics support only for classes. To fix this in our project we need to define our base type as an <span class="pre-inline">abstract class</span> instead of an <span class="pre-inline">interface</span>. This is actually not an issue as its implementations are classes anyway:</p><pre><code class="kotlin hljs">abstract class UseCase<in Input: Any, out Output: Any> { abstract operator fun invoke(input: Input): Output } </code></pre><h3>Swift function invocation</h3><p>Now let's fix the former problem with use case invocation. Swift language doesn't have an invoke operator like Kotlin. Instead, it has methods with special names, and one of them is <span class="pre-inline">callAsFunction()</span> that can be called with the use of <span class="pre-inline">()</span> symbol.</p><p>We may introduce this function to our use case base type but that may be confusing for use from Kotlin common code or Android code.</p><p>To make it available for iOS code only, we will provide different implementations of use case base type for Android and iOS using Kotlin's <span class="pre-inline">expect</span>/<span class="pre-inline">actual</span> feature. Its implementation just delegates the call to our standard <span class="pre-inline">invoke()</span> function.</p><pre><code class="kotlin hljs">// Kotlin Common expect abstract class UseCase<in Input : Any, out Output : Any> constructor() { abstract operator fun invoke(input: Input): Output } // Kotlin Android actual abstract class UseCase<in Input : Any, out Output : Any> { actual abstract operator fun invoke(input: Input): Output } // Kotlin iOS actual abstract class UseCase<in Input : Any, out Output : Any> { actual abstract operator fun invoke(input: Input): Output fun callAsFunction(input: Input): Output = invoke(input) } </code></pre><h2>Living documentation</h2><p>The domain is a part of every project that actually does the important things. When modeled properly, it suits so-called living documentation. It is understandable for any reader; anytime a logic is changed, the documentation also changes. </p><p>Anytime you find a piece of domain code that is not understandable, let's take a moment and polish it. Your future will be grateful to you.</p><p><br></p><p>Pavel Švéda<br></p><p>Twitter: <a href="">@xsveda</a><br><br></p>​<br>#domain;#architecture;#kotlin;#swift;#multiplatform