<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Attila Fejér</title>
    <description>The latest articles on DEV Community by Attila Fejér (@fanatixan).</description>
    <link>https://dev.to/fanatixan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F138924%2Fca8d26d5-6059-4f8d-b123-51331caae1ba.jpg</url>
      <title>DEV Community: Attila Fejér</title>
      <link>https://dev.to/fanatixan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fanatixan"/>
    <language>en</language>
    <item>
      <title>Engineering vs Craftsmanship</title>
      <dc:creator>Attila Fejér</dc:creator>
      <pubDate>Tue, 25 Jun 2024 19:25:00 +0000</pubDate>
      <link>https://dev.to/fanatixan/engineering-vs-craftsmanship-4c67</link>
      <guid>https://dev.to/fanatixan/engineering-vs-craftsmanship-4c67</guid>
      <description>&lt;p&gt;In the world of software development, two terms often arise when discussing the qualities of experienced professionals: engineering and craftsmanship. While we sometimes use these terms interchangeably, they represent distinct skill sets and mindsets.&lt;/p&gt;

&lt;p&gt;Emily Bache and Dave Farley published the video &lt;a href="https://www.youtube.com/watch?v=yHCds5IbKa4" rel="noopener noreferrer"&gt;What Is A Software Engineer? | Craftsmanship Movement Was A "Step Backwards"&lt;/a&gt;. It inspired me to write this post with a different opinion: combining the two approaches leads to superior software development.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Engineer's Mindset
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs41iy9fuaeqwodstrx1k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs41iy9fuaeqwodstrx1k.jpg" alt="Engineer" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Software engineers have a systematic problem-solving approach, emphasizing &lt;strong&gt;precision, efficiency, and scalability&lt;/strong&gt;. The following are some essential qualities of a software engineer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Systematic Thinking:&lt;/strong&gt; Engineers approach problems with a structured mindset, breaking down complex issues into manageable components&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measurements and Metrics:&lt;/strong&gt; They make decisions based on quantitative data gathered from the system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency and Optimization:&lt;/strong&gt; They strive to create efficient algorithms and optimize code to ensure optimal performance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; Engineers design systems that can handle growth, ensuring that software can smoothly scale as user demands increase&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability:&lt;/strong&gt; They prioritize building robust and reliable systems, often employing rigorous testing and validation techniques to minimize bugs and errors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation and Standards:&lt;/strong&gt; Engineers follow industry standards and best practices, maintaining comprehensive documentation for future reference and collaboration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In other words, engineers focus on building systems that satisfy functional and non-functional requirements. They achieve this by heavily relying on theoretical knowledge.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, this mindset doesn't consider a crucial human element: the developer who'll maintain or understand the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Craftsman's Touch
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhl21elutf30zptepc7u2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhl21elutf30zptepc7u2.jpg" alt="Craftsman" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The software craftsmanship movement emerged as a response to the perceived decline in software quality and the industrialization of software development. It emphasizes the &lt;strong&gt;importance of quality, professionalism, and pride in one's work&lt;/strong&gt;. Key principles of software craftsmanship include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Continuous Learning:&lt;/strong&gt; Craftsmen commit to continuous learning and improvement, staying updated with the latest practices and technologies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Professionalism:&lt;/strong&gt; The movement advocates for a professional attitude towards software development, where developers take pride in their work and strive for excellence. It also includes communication with clients and teammates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration and Mentorship:&lt;/strong&gt; Experienced craftsmen mentor less experienced developers, fostering a culture of knowledge sharing and collective growth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quality Focus:&lt;/strong&gt; They emphasize delivering high-quality software that meets user needs and is maintainable in the long term. Their toolkit includes maintaining code quality, refactoring, and TDD.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community Engagement:&lt;/strong&gt; Active participation in the software development community through conferences, meetups, and online forums is encouraged to promote best practices and innovation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In summary, craftsmen focus on pragmatism and the human element in software development.&lt;/strong&gt; But even the most beautifully written code won't satisfy the clients if it doesn't perform well in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Orthogonal Skillsets: A Symbiotic Relationship
&lt;/h2&gt;

&lt;p&gt;While engineering and craftsmanship represent different aspects of software development, they are not mutually exclusive. In fact, they complement and strengthen each other, creating a holistic approach to software development. Here’s why combining the theoretical knowledge of an engineer and the pragmatism of a craftsman is essential:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Balanced Approach:&lt;/strong&gt; Integrating the engineer’s systematic thinking with the craftsman’s attention to detail results in well-rounded solutions that are both efficient and maintainable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Collaboration:&lt;/strong&gt; Engineers and craftsmen bring unique perspectives to the table, fostering a collaborative environment where diverse ideas lead to innovative solutions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Professional Growth:&lt;/strong&gt; Developing skills in both areas allows professionals to grow more comprehensively, enhancing their ability to tackle a wide range of challenges&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product Success:&lt;/strong&gt; Combining the strengths of engineering and craftsmanship leads to higher-quality software that meets user needs while being reliable, scalable, and maintainable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuous Improvement:&lt;/strong&gt; Combining measurements with the strive for quality is a powerful combination that enables keeping a codebase healthy and maintainable&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How To Grow
&lt;/h2&gt;

&lt;p&gt;Education (including universities and bootcamps) worldwide has traditionally focused on the engineering aspects of software development. Computer science programs often emphasize the theoretical and technical foundations for engineering robust and scalable systems. Here are some reasons for this focus:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rigorous Curriculum:&lt;/strong&gt; University programs are designed to provide a solid grounding in computer science theory, algorithms, data structures, and systems design&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Industry Demand:&lt;/strong&gt; There is a high demand in the industry for engineers who can build scalable, efficient, and reliable systems, driving universities to prioritize these skills&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Research and Innovation:&lt;/strong&gt; Academic research often focuses on pushing the boundaries of what is technically possible, fostering a mindset of innovation and engineering excellence&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standardization and Accreditation:&lt;/strong&gt; University curricula are often standardized and accredited by professional bodies, emphasizing engineering competencies to ensure graduates meet industry standards&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lack of Legacy Experience:&lt;/strong&gt; During education, students often work on green-field projects that won't teach them the importance of maintainability or prepare them for the challenges of legacy codebases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While engineering focus is essential, it sometimes leaves gaps in the practical, hands-on skills cultivated through craftsmanship. Bridging this gap requires incorporating craftsmanship principles into the educational experience.&lt;/p&gt;

&lt;p&gt;This is easier said than done. Luckier developers work for companies with a healthy culture that fosters the necessary skills. Alternatively, they involve external coaches to evolve their employees, for example, by onboarding the &lt;a href="https://swcraftsmanshipdojo.com/" rel="noopener noreferrer"&gt;SW Craftsmanship Dojo®&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Unfortunately, most craftsmen aren't that lucky. They gain their knowledge by learning from colleagues, reading, and personal experience. A non-comprehensive list of recommended books:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship-ebook/dp/B001GSTOAM/" rel="noopener noreferrer"&gt;Clean Code: A Handbook of Agile Software Craftsmanship&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Clean-Coder-Conduct-Professional-Programmers-ebook/dp/B0050JLC9Y/" rel="noopener noreferrer"&gt;The Clean Coder: A Code of Conduct for Professional Programmers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Pragmatic-Programmer-journey-mastery-Anniversary-ebook/dp/B07VRS84D1/" rel="noopener noreferrer"&gt;The Pragmatic Programmer: Your journey to mastery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Refactoring-Improving-Existing-Addison-Wesley-Signature/dp/0134757599/" rel="noopener noreferrer"&gt;Refactoring: Improving the Design of Existing Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Tidy-First-Kent-Beck-ebook/dp/B0CL7ZMLWH/" rel="noopener noreferrer"&gt;Tidy First?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164" rel="noopener noreferrer"&gt;Clean Architecture: A Craftsman's Guide to Software Structure and Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Code-That-Fits-Your-Head/dp/0137464401" rel="noopener noreferrer"&gt;Code That Fits in Your Head: Heuristics for Software Engineering&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Despite every difficulty and failure, we value every drop of sweat because each is a lesson learned and a step toward becoming a better professional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Craftsmanship isn't a step backward. By embracing both the structured, efficient mindset of an engineer and the artistic, detail-oriented approach of a craftsman, we can achieve a balanced skill set that enhances our work and contributes to the success of our products. We should strive to integrate both qualities into our professional development to build better software and become more versatile, effective, and happy professionals.&lt;/p&gt;

</description>
      <category>opinion</category>
      <category>engineering</category>
      <category>craftsmanship</category>
    </item>
    <item>
      <title>Sustainable Refactoring</title>
      <dc:creator>Attila Fejér</dc:creator>
      <pubDate>Wed, 15 May 2024 16:49:00 +0000</pubDate>
      <link>https://dev.to/fanatixan/sustainable-refactoring-116d</link>
      <guid>https://dev.to/fanatixan/sustainable-refactoring-116d</guid>
      <description>&lt;p&gt;In the fast-paced world of software development, maintaining code health while delivering new features is a constant challenge. One strategy that has emerged as a crucial practice is refactoring. However, the traditional approach to refactoring can often clash with the demands of project timelines and stakeholder expectations.&lt;/p&gt;

&lt;p&gt;In this post, we'll explore how sustainable refactoring techniques can help strike a balance between code health and feature delivery.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Refactoring
&lt;/h2&gt;

&lt;p&gt;Refactoring is the process of restructuring existing code without altering its external behavior. It offers numerous advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Improved Code Quality:&lt;/strong&gt; Refactoring eliminates code smells, improves design patterns, and enhances readability, making the codebase easier to understand&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced Technical Debt:&lt;/strong&gt; By addressing legacy issues, refactoring helps reduce technical debt, leading to long-term cost savings and improved project sustainability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Maintainability:&lt;/strong&gt; Refactored code is easier to maintain and extend, reducing the time and effort required for future updates and modifications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Increased Developer Productivity:&lt;/strong&gt; Developers can work more efficiently on clean, well-structured code, leading to faster development cycles, fewer bugs, and higher-quality software&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enables Further Changes:&lt;/strong&gt; Refactoring isn't just about improving existing code quality; it also enables future changes and feature additions by restructuring the code to be more modular, flexible, and extensible&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Challenges: Time Concerns for Managers and Customers
&lt;/h2&gt;

&lt;p&gt;Despite its benefits, refactoring can be perceived as time-consuming by managers and customers. The notion of developers spending significant time refactoring without delivering new features can raise concerns about project timelines and return on investment. This mindset often leads to resistance towards dedicating resources to refactoring efforts.&lt;/p&gt;

&lt;p&gt;While we could try to persuade stakeholders with arguments about long-term benefits and reduced technical debt, a more practical approach exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution: Parallel Refactoring with Feature Development
&lt;/h2&gt;

&lt;p&gt;A more sustainable way to refactor is to parallelize it with feature development to address the challenge of time concerns. Instead of treating refactoring as a separate, standalone task, it can be integrated into the development workflow in small, incremental steps.&lt;/p&gt;

&lt;p&gt;Consider how single-core processors handle multitasking through time-division multiplexing. Despite having only one core, these processors can execute multiple tasks concurrently by switching between them rapidly. Similarly, developers can integrate refactoring tasks into their regular feature development process, allocating small chunks of time to refactor existing code alongside implementing new features.&lt;/p&gt;

&lt;p&gt;We don't necessarily have to do large-scale restructuring. It's a good start if we apply the Boy Scout Rule: leave the code better than we found it. Using this principle, we can ensure that each code modification includes a small refactor to improve the quality of the surrounding code. Over time, these incremental improvements accumulate, leading to a healthier and more maintainable codebase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F143qraaqi00vm0vzok1t.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F143qraaqi00vm0vzok1t.jpg" alt="Boy Scout" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Will this impact development speed? Certainly. But not the way we think. By keeping the code in a healthier state, future changes will be much faster to make. In other words, we slow down to go faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Sustainable refactoring is not about sacrificing feature delivery for code health or vice versa. Instead, it's about finding a balance that allows continuous improvement while meeting project requirements. Teams can effectively achieve code health and feature delivery goals by integrating refactoring into the development process and adopting parallelization strategies.&lt;/p&gt;

&lt;p&gt;Embracing sustainable refactoring practices is vital to building software systems that are functional, resilient, and adaptable to future changes.&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>codequality</category>
      <category>deliveryspeed</category>
    </item>
    <item>
      <title>Will Customers Ever Speak Our Language?</title>
      <dc:creator>Attila Fejér</dc:creator>
      <pubDate>Thu, 09 May 2024 07:51:00 +0000</pubDate>
      <link>https://dev.to/fanatixan/will-customers-ever-speak-our-language-2k2j</link>
      <guid>https://dev.to/fanatixan/will-customers-ever-speak-our-language-2k2j</guid>
      <description>&lt;p&gt;Software developers face a constant challenge: the communication gap between them and customers. TLDR: customers will never speak the developers' language. While both parties strive for the same goal—creating valuable, functional software—their perspectives, priorities, and vocabularies often differ. In this post, we'll dive into the reasons for this difference, explore the implications, and discuss strategies for bridging the gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Customers Don't Know the Jargon
&lt;/h2&gt;

&lt;p&gt;Consider this scenario: a customer approaches a development team requesting website enhancements. However, their language lacks the technical jargon familiar to developers. The customer's focus is on outcomes rather than implementation details. For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Customer (Business Owner):&lt;/strong&gt; "We need the website to be more engaging and interactive. Can you add some dynamic elements to the homepage?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developer:&lt;/strong&gt; "Sure, we can implement interactive features using JavaScript libraries like React or Vue.js. Would you like to include sliders, animations, or interactive forms?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Customer:&lt;/strong&gt; "Um, I'm not familiar with those technologies. I want the homepage to grab visitors' attention and make them stay longer on our site."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While people understand technology to some extent today, we can't expect everyone to be proficient. That's the reason why we have different professions. For example, we could quickly flip the table. When we go to a doctor, do we understand everything they say? If not, is it our responsibility to learn the medical language or the doctor's to simplify their message?&lt;/p&gt;

&lt;h2&gt;
  
  
  They Bring a Problem to Us to Solve
&lt;/h2&gt;

&lt;p&gt;Customers often challenge developers, seeking solutions without delving into technical intricacies. They already have enough to manage various aspects of their business or project. For them, it's about achieving desired outcomes rather than understanding the underlying technology. For instance:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Customer (Project Manager):&lt;/strong&gt; "We're anticipating a massive surge in traffic for Black Friday. Can we handle it?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developer:&lt;/strong&gt; "We've optimized the website for performance but might need to scale our servers. Do you have an estimate of how many visitors we're expecting?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Customer:&lt;/strong&gt; "Our marketing team predicts a 200% increase in traffic compared to last year. We need to ensure the website stays up and running smoothly."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developer:&lt;/strong&gt; "Understood. Let's run some stress tests to see how the current infrastructure handles the load. We can then scale up if needed."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Customer:&lt;/strong&gt; "Sounds good. Let's prioritize stability over new features for the next few days."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this example, the project manager brings up a problem: the anticipated visitor surge on Black Friday. They don't delve into technical details but express their concerns about website performance. The developer proposes a solution-oriented approach, focusing on stress testing and server scalability. By understanding the problem and proposing a practical solution, the developer ensures alignment with the customer's needs and priorities.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's Not Their Job
&lt;/h2&gt;

&lt;p&gt;Just as a car mechanic doesn't expect customers to understand the intricacies of vehicle mechanics, customers don't necessarily grasp the technical nuances of software development. They rely on developers to translate their requirements into actionable solutions.&lt;/p&gt;

&lt;p&gt;One of my professors at the university contributed to the development of the first defibrillator. The electrical engineering team met the doctors to understand the requirements. They had the following conversation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Doctor:&lt;/strong&gt; "Our task is easy. We need to drive some electrical current through the patient's heart to restart it."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Engineer:&lt;/strong&gt; "Understood. How much current are we talking about?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Doctor:&lt;/strong&gt; "Big."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Engineer:&lt;/strong&gt; "But if we drive a big current through a human body, it will burn."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Doctor:&lt;/strong&gt; "Not that big."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From this discussion, we can see that every party has different areas of expertise. Therefore, other jobs. To understand each other, they need to close the communication gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiple Customer Personas
&lt;/h2&gt;

&lt;p&gt;In software development, various customer personas interact with developers, each with unique perspectives and priorities. These personas include end-users, clients who order development, product owners, business analysts, and project managers. Each persona brings different perspectives and requirements to the table.&lt;/p&gt;

&lt;p&gt;Different personas have different levels of technical understanding. But at the end of the day, their role doesn't matter. Because developers are the technical people. Developers need to solve the problems. And as we saw above, we can't expect any of the customer personas to describe their problems with accurate technicality.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Importance of Speaking the Same Language
&lt;/h2&gt;

&lt;p&gt;Despite the inherent challenges, developers and customers must speak the same language to ensure successful collaboration and project outcomes. This concept aligns with &lt;a href="https://en.wikipedia.org/wiki/Domain-driven_design" rel="noopener noreferrer"&gt;Domain-Driven Design (DDD)&lt;/a&gt; principles, emphasizing the importance of a &lt;a href="https://martinfowler.com/bliki/UbiquitousLanguage.html" rel="noopener noreferrer"&gt;ubiquitous language&lt;/a&gt;—a shared vocabulary that fosters clear communication and understanding within a domain.&lt;/p&gt;

&lt;p&gt;To understand why it is crucial, let's think about what happened to the &lt;a href="https://en.wikipedia.org/wiki/Mars_Climate_Orbiter" rel="noopener noreferrer"&gt;Mars Climate Orbiter&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mars Climate Orbiter began the planned orbital insertion maneuver on September 23, 1999, at 09:00:46 UTC. Mars Climate Orbiter went out of radio contact when the spacecraft passed behind Mars at 09:04:52 UTC, 49 seconds earlier than expected, and communication was never reestablished. Due to complications arising from human error, the spacecraft encountered Mars at a lower-than-anticipated altitude and it was either destroyed in the atmosphere or re-entered heliocentric space after leaving Mars' atmosphere.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The orbiter had two measurement units: one developed by NASA and the other by Lockheed Martin. The problem was a measurement mismatch between these two units. NASA's solution used SI (metric) units, while the other US customary units. In other words, one system measured altitude in feet, and the other measured altitude in meters. No wonder that it didn't work as expected.&lt;/p&gt;

&lt;p&gt;The "beauty" of this situation is that both teams consisted of engineers. Yet, they didn't speak the same language. Differences become more significant if a technical and non-technical party needs to align. In specific industries, lives can be in danger if things go south. Think of aviation, chemical plants, or automotive.&lt;/p&gt;

&lt;p&gt;So we must speak the same language. And we already saw that customers won't speak ours. This leaves us with only one possibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution: Developers Need to Learn the Customer's Language
&lt;/h2&gt;

&lt;p&gt;To bridge the communication gap, developers must actively engage with customers and adopt their language. Developers can effectively tailor solutions that meet their needs by understanding the customer's domain, priorities, and challenges.&lt;/p&gt;

&lt;p&gt;There are effective techniques developers can use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Empathy:&lt;/strong&gt; Developers should empathize with customers' challenges and strive to understand their perspective. Putting ourselves in someone else's shoes is a powerful way to improve communication.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active Listening:&lt;/strong&gt; Actively listening to the concerns and requirements of customers can help developers gain insights into their needs. The most potent way of active listening is by repeating our interpretation by rephrasing what the other party told us. Customers can reflect on that and confirm or correct our understanding.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't Invent New Words and Phrases:&lt;/strong&gt; Instead of introducing new domain terms, developers should use the language familiar to customers. For example, if the client talks about "buyers" in a webshop, don't call them "users".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.eventstorming.com/" rel="noopener noreferrer"&gt;Event Storming&lt;/a&gt;:&lt;/strong&gt; This collaborative workshop technique allows developers and customers to explore complex business domains together, fostering a shared understanding and language. It may not seem easy initially, but it's worth using. Experience shows every participant—including domain experts—learn new things about their business during an event storming session.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Impact of AI
&lt;/h2&gt;

&lt;p&gt;In the post "How To Use AI Developer Tools In 2024", there is a &lt;a href="//../ai-tooling/how-to-use-ai-dev-tools-2024/#ai-as-a-programmer"&gt;section&lt;/a&gt; on how AI may transform developers' jobs. We'll have to deal with less technical nuances and focus more on problem-solving.&lt;/p&gt;

&lt;p&gt;Will it mean that customers won't need software engineers anymore? Not so fast:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjngat3bcjwz6ocwhe7m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjngat3bcjwz6ocwhe7m.png" alt="AI won't take over yet" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Software engineering is much more than coding. We'll still need to split large, complicated problems into small, simple ones. We'll have to understand the infrastructure. We'll have to be able to modify existing systems.&lt;/p&gt;

&lt;p&gt;So AI can shrink the gap, but it won't disappear.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Bridging the communication gap between developers and customers is crucial for successful collaboration in software development. While customers may not fully speak the language of developers, techniques like empathy, active listening, and event-storming can facilitate clear communication and alignment.&lt;/p&gt;

&lt;p&gt;As AI continues to evolve, it offers new tools to streamline communication and enhance collaboration. However, human expertise and understanding remain essential.&lt;/p&gt;

&lt;p&gt;By embracing collaboration and a shared commitment to communication, developers and customers can navigate the complexities of software development and build a brighter future together.&lt;/p&gt;

</description>
      <category>communication</category>
      <category>softskills</category>
      <category>ai</category>
    </item>
    <item>
      <title>Replacing Type Code With State/Strategy</title>
      <dc:creator>Attila Fejér</dc:creator>
      <pubDate>Thu, 02 May 2024 06:58:00 +0000</pubDate>
      <link>https://dev.to/fanatixan/replacing-type-code-with-statestrategy-mfk</link>
      <guid>https://dev.to/fanatixan/replacing-type-code-with-statestrategy-mfk</guid>
      <description>&lt;p&gt;Previously, we talked about potential issues &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; can cause, and what to do when the type affects only data, or behavior, too.&lt;/p&gt;

&lt;p&gt;Now that we are &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; ninjas, we can go even further and see how to tackle when the type code and the behavior change dynamically at runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;We'll dive into the realm of &lt;a href="https://en.wikipedia.org/wiki/Dungeons_%26_Dragons" rel="noopener noreferrer"&gt;DnD&lt;/a&gt;. Or something similar.&lt;/p&gt;

&lt;p&gt;In our game, we'll have four rooms. One is the start, the others contain different things: a dragon, treasure, and fireproof armor. We can &lt;strong&gt;move&lt;/strong&gt; between specific rooms:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ssk11yw79h44pujnvl6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ssk11yw79h44pujnvl6.png" alt="Dungeon with four rooms" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we don't move, we should &lt;strong&gt;act&lt;/strong&gt; depending on the room: pick up the armor, attack the dragon, or open the chest.&lt;/p&gt;

&lt;p&gt;Our initial code skeleton is the following:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Game&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;START&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;DRAGON&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;CHEST&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ARMOR&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;IN_PROGRESS&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ENDED&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Action&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;MOVE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ACT&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;MovementDirection&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;NORTH&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;SOUTH&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;EAST&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;WEST&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;START&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nc"&gt;GameStatus&lt;/span&gt; &lt;span class="n"&gt;gameStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IN_PROGRESS&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;playerFireproof&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;dragonLives&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gameStatus&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IN_PROGRESS&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentRoomDescription&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
      &lt;span class="nc"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nextUserAction&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;Action&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ACT&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;movementDirection&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;Action&lt;/span&gt; &lt;span class="nf"&gt;nextUserAction&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementation skipped for easier understanding&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;MovementDirection&lt;/span&gt; &lt;span class="nf"&gt;movementDirection&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementation skipped for easier understanding&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;currentRoomDescription&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// TODO&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// TODO&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MovementDirection&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// TODO&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three things depend on the current room:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The room's description&lt;/li&gt;
&lt;li&gt;If we move to a direction, in which room do we end up&lt;/li&gt;
&lt;li&gt;The action we can perform&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For simplicity, we won't show any error messages when the user tries to do anything invalid. For example, when they try to move in a direction where there aren't any doors.&lt;/p&gt;

&lt;p&gt;Let's see a naive implementation:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Game&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// rest of the code&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;currentRoomDescription&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;START&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"You are in an empty room. You see a door to the North and to the East."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DRAGON&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dragonLives&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"You see a dragon. You can attack it if you want. Behind it there is a door to the East. You can go back South."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"The dragon is dead. You see a door to the South and to the East."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CHEST&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"There is a chest in the middle of the room. You can open it. You can also go back to the West."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ARMOR&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;playerFireproof&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"You are in an empty room. You see a door to the West."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"There is a fireproof armor in the middle of the room. You can pick it up. You can also go back to the West."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;START&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;// do nothing - no action is available in the start room&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DRAGON&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;dragonLives&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// we can't do anything if the dragon is dead&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;playerFireproof&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// the player is fireproof so they can kill the dragon&lt;/span&gt;
          &lt;span class="n"&gt;dragonLives&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;gameStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ENDED&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The dragon burned you alive. You're dead. Game over."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CHEST&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;gameStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ENDED&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"You got the chest. Congratulations, you won!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ARMOR&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;// player picks up the armor&lt;/span&gt;
        &lt;span class="n"&gt;playerFireproof&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MovementDirection&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;START&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;MovementDirection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NORTH&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DRAGON&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;MovementDirection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EAST&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ARMOR&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DRAGON&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;MovementDirection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SOUTH&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;START&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;MovementDirection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EAST&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;dragonLives&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
              &lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CHEST&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CHEST&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;MovementDirection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;WEST&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DRAGON&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ARMOR&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;MovementDirection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;WEST&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;START&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yikes, that's super ugly. The code already got out of hand when we had only four rooms. We don't want to imagine how unmaintainable will it get for dozens or hundreds of rooms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improving the Code
&lt;/h2&gt;

&lt;p&gt;Fortunately, &lt;a href="https://dev.to/fanatixan/replacing-type-code-with-subclasses-1icb"&gt;we already learned&lt;/a&gt; that we can create a class hierarchy to deal with different behaviors. The only problem is that we didn't have to deal with changing states before.&lt;/p&gt;

&lt;p&gt;The solution is easy. Keep the room-independent things in the game class and extract the rest.&lt;/p&gt;

&lt;p&gt;Before we do that, we need to refactor a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's worth to extract the &lt;code&gt;MovementDirection&lt;/code&gt; enum because it's not that tightly coupled to the &lt;code&gt;Game&lt;/code&gt; class&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;move()&lt;/code&gt; method should return the next room since it doesn't have access to the &lt;code&gt;Game.room&lt;/code&gt; field anymore&lt;/li&gt;
&lt;li&gt;Similarly, it's worth to extract the &lt;code&gt;GameStatus&lt;/code&gt; enum and make &lt;code&gt;act()&lt;/code&gt; return the new status&lt;/li&gt;
&lt;li&gt;We should create the &lt;code&gt;Player&lt;/code&gt; class to manage the player's state&lt;/li&gt;
&lt;li&gt;We pass the &lt;code&gt;Player&lt;/code&gt; to the &lt;code&gt;act()&lt;/code&gt; method to use/alter the player's state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After all the steps above, the code looks like following:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;MovementDirection&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="no"&gt;NORTH&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;SOUTH&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;EAST&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;WEST&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="no"&gt;IN_PROGRESS&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ENDED&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Player&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;fireproof&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;pickUpFireproofArmor&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fireproof&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isFireproof&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fireproof&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Game&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;START&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;DRAGON&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;CHEST&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ARMOR&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Action&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;MOVE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ACT&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;START&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nc"&gt;Player&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Player&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="nc"&gt;GameStatus&lt;/span&gt; &lt;span class="n"&gt;gameStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IN_PROGRESS&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gameStatus&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IN_PROGRESS&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentRoomDescription&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
      &lt;span class="nc"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nextUserAction&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;Action&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ACT&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;gameStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;move&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;movementDirection&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;Action&lt;/span&gt; &lt;span class="nf"&gt;nextUserAction&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementation skipped for easier understanding&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;MovementDirection&lt;/span&gt; &lt;span class="nf"&gt;movementDirection&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementation skipped for easier understanding&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;


  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;currentRoomDescription&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementation skipped for easier understanding&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;GameStatus&lt;/span&gt; &lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Player&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementation skipped for easier understanding&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MovementDirection&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementation skipped for easier understanding&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step is to move the three room-dependent methods to a new interface:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Game&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// code skipped for easier understanding&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gameStatus&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IN_PROGRESS&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
      &lt;span class="nc"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nextUserAction&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;Action&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ACT&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;gameStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;act&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;room&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;move&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;movementDirection&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;Action&lt;/span&gt; &lt;span class="nf"&gt;nextUserAction&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementation skipped for easier understanding&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;MovementDirection&lt;/span&gt; &lt;span class="nf"&gt;movementDirection&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// implementation skipped for easier understanding&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;description&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

  &lt;span class="nc"&gt;GameStatus&lt;/span&gt; &lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Player&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MovementDirection&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it's time to move forward and implement the four rooms:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="no"&gt;START&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StartRoom&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="no"&gt;DRAGON&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DragonRoom&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="no"&gt;ARMOR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArmorRoom&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="no"&gt;CHEST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ChestRoom&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;description&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

  &lt;span class="nc"&gt;GameStatus&lt;/span&gt; &lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Player&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MovementDirection&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StartRoom&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;description&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"You are in an empty room. You see a door to the North and to the East."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;GameStatus&lt;/span&gt; &lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Player&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// nothing to do&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IN_PROGRESS&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MovementDirection&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;MovementDirection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NORTH&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DRAGON&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;MovementDirection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EAST&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ARMOR&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DragonRoom&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;dragonLives&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;description&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dragonLives&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"You see a dragon. You can attack it if you want. Behind it there is a door to the East. You can go back South."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"The dragon is dead. You see a door to the South and to the East."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;GameStatus&lt;/span&gt; &lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Player&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;dragonLives&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// we can't do anything if the dragon is dead&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IN_PROGRESS&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isFireproof&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// the player is fireproof so they can kill the dragon&lt;/span&gt;
      &lt;span class="n"&gt;dragonLives&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IN_PROGRESS&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The dragon burned you alive. You're dead. Game over."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ENDED&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MovementDirection&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;MovementDirection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SOUTH&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;START&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;MovementDirection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EAST&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;dragonLives&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CHEST&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChestRoom&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;description&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"There is a chest in the middle of the room. You can open it. You can also go back to the West."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;GameStatus&lt;/span&gt; &lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Player&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"You got the chest. Congratulations, you won!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ENDED&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MovementDirection&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;MovementDirection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;WEST&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DRAGON&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ArmorRoom&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;armorPickedUp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;description&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;armorPickedUp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"You are in an empty room. You see a door to the West."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"There is a fireproof armor in the middle of the room. You can pick it up. You can also go back to the West."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;GameStatus&lt;/span&gt; &lt;span class="nf"&gt;act&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Player&lt;/span&gt; &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;armorPickedUp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pickUpFireproofArmor&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;GameStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IN_PROGRESS&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;Room&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MovementDirection&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;MovementDirection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;WEST&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Room&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;START&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that we introduced constants in the &lt;code&gt;Room&lt;/code&gt; interface so every room will have a single instance. This is useful because every room class handles its state management independently. It improves &lt;a href="https://en.wikipedia.org/wiki/Cohesion_(computer_science)" rel="noopener noreferrer"&gt;cohesion&lt;/a&gt; and follows the &lt;a href="https://en.wikipedia.org/wiki/Single-responsibility_principle" rel="noopener noreferrer"&gt;single-responsibility principle&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also note that every class we have now is much simpler than before&lt;sup id="fnref1"&gt;1&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;In the previous post in the series we already saw the advantages of introducing subclasses. Therefore, we'll talk about what's new in this implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing State/Strategy
&lt;/h2&gt;

&lt;p&gt;Compared to our pet example in the previous post, we had shared behavior and state among the classes. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Game status&lt;/li&gt;
&lt;li&gt;Flow of the game&lt;/li&gt;
&lt;li&gt;Reading user input&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Adding the common behavior to a superclass could have been a solution. From an architectural perspective, that would have been violating the &lt;a href="https://en.wikipedia.org/wiki/SOLID" rel="noopener noreferrer"&gt;SOLID&lt;/a&gt; principles; therefore, a suboptimal choice.&lt;/p&gt;

&lt;p&gt;Not to mention that instead of managing the game status in multiple places is challenging.&lt;/p&gt;

&lt;p&gt;It was a wiser decision to keep the common parts in the &lt;code&gt;Game&lt;/code&gt; class and extract the changing parts to the &lt;code&gt;Room&lt;/code&gt; interface and its implementations.&lt;/p&gt;

&lt;p&gt;This refactoring has a name: &lt;a href="https://refactoring.guru/replace-type-code-with-state-strategy" rel="noopener noreferrer"&gt;replace type code with state/strategy&lt;/a&gt;. The state/strategy refers to the &lt;a href="https://refactoring.guru/design-patterns/state" rel="noopener noreferrer"&gt;State&lt;/a&gt; and &lt;a href="https://refactoring.guru/design-patterns/strategy" rel="noopener noreferrer"&gt;Strategy&lt;/a&gt; design patterns.&lt;/p&gt;

&lt;p&gt;Their intent is exactly the same as we implemented above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separate the common parts from the changing parts&lt;/li&gt;
&lt;li&gt;Introduce a class hierarchy for the changing parts&lt;/li&gt;
&lt;li&gt;Make them interchangeable at runtime&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Their class diagrams (and code representations) are the same. The differentiator is only philosophical:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the different implementations do different things, then it's the State pattern. For example, different rooms have different behaviors.&lt;/li&gt;
&lt;li&gt;If they do the same things, but differently, then it's the Strategy. For example, when we save an image to different file formats, the result is the same: an image file on the disk, but the algorithms that converted the image to a binary representation are different.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Further Patterns
&lt;/h2&gt;

&lt;p&gt;There are many other patterns we could use to replace conditional statements with polymorphism. Each of them has specific conditions under which they work the best.&lt;/p&gt;

&lt;p&gt;A non-comprehensive list of such patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/design-patterns/abstract-factory" rel="noopener noreferrer"&gt;Abstract Factory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/design-patterns/command" rel="noopener noreferrer"&gt;Command&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/design-patterns/visitor" rel="noopener noreferrer"&gt;Visitor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/design-patterns/chain-of-responsibility" rel="noopener noreferrer"&gt;Chain of Responsibility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/design-patterns/decorator" rel="noopener noreferrer"&gt;Decorator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/design-patterns/proxy" rel="noopener noreferrer"&gt;Proxy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's worth knowing them because they are very powerful - if we use them wisely.&lt;/p&gt;

&lt;p&gt;Do you struggle with any of those? I might write a post about them. Drop me a comment or an email to express your interest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If we feel that conditional statements are hard to maintain, we have many alternatives. In this series, we saw reasons beyond maintainability. We also understood a few specific refactoring techniques and their limitations.&lt;/p&gt;

&lt;p&gt;But the most important thing is to use these techniques wisely. If a pattern is overused, it can decrease maintainability like any other technique. We should always remember that there isn't a single best solution, a one-size-fits-all technique. Because, in engineering, the best answer to most questions is: "it depends".&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Yes, we still have a few &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; statements in the &lt;code&gt;Room.move()&lt;/code&gt; implementations, but that should be our homework to get rid of those. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>programming</category>
      <category>refactoring</category>
      <category>switchcase</category>
      <category>designpatterns</category>
    </item>
    <item>
      <title>AI Tools and Refactoring</title>
      <dc:creator>Attila Fejér</dc:creator>
      <pubDate>Wed, 24 Apr 2024 19:11:00 +0000</pubDate>
      <link>https://dev.to/fanatixan/ai-tools-and-refactoring-4lfo</link>
      <guid>https://dev.to/fanatixan/ai-tools-and-refactoring-4lfo</guid>
      <description>&lt;p&gt;Previously in the series, we saw that AI tools have limitations. We also&lt;br&gt;
discussed maximizing our productivity by using them to write code - without&lt;br&gt;
shooting ourselves in our legs.&lt;/p&gt;

&lt;p&gt;In this post, we'll cover one more piece of the puzzle: how they can (or can't)&lt;br&gt;
help us to refactor.&lt;/p&gt;



&lt;p&gt;This post was heavily influenced by thoughtworks' excellent podcast episode&lt;br&gt;
&lt;a href="https://www.thoughtworks.com/insights/podcasts/technology-podcasts/refactoring-with-ai" rel="noopener noreferrer"&gt;Refactoring with AI&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Goal of Refactoring
&lt;/h2&gt;

&lt;p&gt;If we want to boil it down, refactoring has a simple goal: to make it easier to&lt;br&gt;
change the code.&lt;/p&gt;

&lt;p&gt;People usually make this identical to improving code quality. Most of the time,&lt;br&gt;
this is indeed what we want to achieve. Higher-quality code is easier to&lt;br&gt;
understand, reason about, and, as a result, modify.&lt;/p&gt;

&lt;p&gt;However, there is a case where we decrease code quality during refactoring.&lt;br&gt;
Sometimes, we need to restructure the code to introduce new behavior later. For&lt;br&gt;
example, consider we have a &lt;code&gt;Dog&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"woof"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"run"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We realize that we want to have other types of pets, so we introduce a &lt;code&gt;Pet&lt;/code&gt;&lt;br&gt;
superclass:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"woof"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"run"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code got unnecessarily complicated - for the current feature set. However,&lt;br&gt;
now it's much easier to introduce cats to the codebase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"meow"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"climb"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the rest of the article, we'll focus on code quality improvement because&lt;br&gt;
that's the primary motivation for refactoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measuring Code Quality
&lt;/h2&gt;

&lt;p&gt;We want to quantify code quality objectively. Otherwise, it'd be hard to reason&lt;br&gt;
whether refactoring improved it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codescene.com/" rel="noopener noreferrer"&gt;CodeScene&lt;/a&gt; has a metric called code health. Adam&lt;br&gt;
Tornhill, the CTO and founder of the company, explains it in the following way:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The interesting thing with code quality is that there's not a single metric&lt;br&gt;
that can capture a multifaceted concept like that. I mean, no matter what&lt;br&gt;
metric you come up with, there's always a way around it, or there's always a&lt;br&gt;
counter case. What we've been working on for the past six to seven years, is&lt;br&gt;
to develop the code health metric.&lt;/p&gt;

&lt;p&gt;The idea with code health is that, instead of looking at a single metric, you&lt;br&gt;
look at a bunch of metrics that complement each other. What we did was that,&lt;br&gt;
we looked at 25 metrics that we know from research that they correlate with an&lt;br&gt;
increased challenge in understanding the code. The code becomes harder to&lt;br&gt;
understand.&lt;/p&gt;

&lt;p&gt;What we do is, basically, we take these metrics, there are 25 of them, stick&lt;br&gt;
them as probes into the code, and pull them out and see what did we find.&lt;br&gt;
Then, you can always, weigh these different metrics together, and you can&lt;br&gt;
categorize code as being either healthy, or unhealthy. My experience is&lt;br&gt;
definitely that when code is unhealthy, when it's of poor quality, it's never&lt;br&gt;
a single thing. It's always a combination of factors.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Improving Code Quality With AI
&lt;/h2&gt;

&lt;p&gt;Now that we can measure code quality, we can benchmark AI tools' capabilities.&lt;br&gt;
Fortunately, Adam did the heavy lifting for us:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Basically, the challenge we were looking at was that, we have a tool that is&lt;br&gt;
capable of identifying bad code, prioritizing it, but then of course, you need&lt;br&gt;
to act on that data. You need to do something with the code, improve it. This&lt;br&gt;
is a really hard task, so we thought that maybe generative AI can help us with&lt;br&gt;
that. What we started out with was a data lake with more than 100,000 examples&lt;br&gt;
of poor code. We also had a ground truth, because we had unit tests that&lt;br&gt;
covered all these code samples.&lt;/p&gt;

&lt;p&gt;We knew that the code does, at least, what the test says it does. What we then&lt;br&gt;
did was that we benchmarked a bunch of AI service as like Open AI, Google,&lt;br&gt;
LLaMA from Facebook, and instructed them to refactor the code. What we found&lt;br&gt;
was quite dramatic, &lt;strong&gt;in 30% of the cases, the AI failed to improve the&lt;br&gt;
code&lt;/strong&gt;. Its code health didn't improve, it just wrote the code in a different&lt;br&gt;
way, but &lt;strong&gt;the biggest drop off was when it came to correctness, because in&lt;br&gt;
two-thirds of the cases, the AI actually broke the tests&lt;/strong&gt;, meaning, it's not&lt;br&gt;
the refactoring, it has actually changed the behavior. I find it a little bit&lt;br&gt;
depressing that in two-thirds of the cases, the AI won't be able to refactor&lt;br&gt;
the code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What does that mean to us? We can't use AI to refactor the code?&lt;/p&gt;

&lt;p&gt;Fortunately, that's not the case. Even though we can't unquestionably trust AI&lt;br&gt;
to improve our code, we can utilize it in a controlled fashion:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Detection&lt;/strong&gt;: Static code analyzers are very efficient but have limited
capabilities. They identify bad practices as patterns - which are sometimes
hard to detect. AI tools can deal with more complex cases - especially if they
work with the
&lt;a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" rel="noopener noreferrer"&gt;abstract syntax tree&lt;/a&gt;
instead of the code itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Suggestions&lt;/strong&gt;: Once we detect a problem, we can suggest solutions.
Generative AI can shine in that, too.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Localized refactoring&lt;/strong&gt;: If we restrict the scope of the refactoring, tools
have to work with a much less complex problem space. Less complexity means
less room for errors - namely, breaking the tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The commonality in these techniques is that we have control over what is&lt;br&gt;
happening in the codebase - which is crucial for today's AI tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The tools that are available today can't reliably improve code quality. Or even&lt;br&gt;
ensure correctness. For these reasons, tests and manual supervision are still&lt;br&gt;
essential when we use AI tools.&lt;/p&gt;

&lt;p&gt;We should take Adam's results with a grain of salt, though. The tools he tried&lt;br&gt;
weren't optimized for refactoring. We saw that code quality and correctness are&lt;br&gt;
quantifiable through code health and the number of failing tests. Once AI tool&lt;br&gt;
creators optimize their products toward these metrics, we can expect them to&lt;br&gt;
improve - significantly. I can't wait to see it.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>refactoring</category>
    </item>
    <item>
      <title>How To Use AI Developer Tools In 2024</title>
      <dc:creator>Attila Fejér</dc:creator>
      <pubDate>Thu, 18 Apr 2024 12:19:00 +0000</pubDate>
      <link>https://dev.to/fanatixan/how-to-use-ai-developer-tools-in-2024-1loo</link>
      <guid>https://dev.to/fanatixan/how-to-use-ai-developer-tools-in-2024-1loo</guid>
      <description>&lt;p&gt;In the previous post, we saw the limitations of AI developer tools. Yes, they are not perfect. However, they are still able to improve our productivity significantly.&lt;/p&gt;

&lt;p&gt;This time, we'll dive into how we can effectively use them to achieve a better development experience, higher-quality output, and faster delivery.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Do We Need AI?
&lt;/h2&gt;

&lt;p&gt;First, we need to understand our pain points to identify solutions. According to &lt;a href="https://www.software.com/reports/code-time-report" rel="noopener noreferrer"&gt;software.com's Global Code Time Report&lt;/a&gt;, the median daily code time per developer is &lt;strong&gt;52 minutes&lt;/strong&gt;. Considering that most of us enjoy this activity most, this is a shockingly low number.&lt;/p&gt;

&lt;p&gt;The rest of our time goes into the following activities&lt;sup id="fnref1"&gt;1&lt;/sup&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Meetings&lt;/strong&gt;: We must share knowledge and synchronize our work with peers. Also, we need to keep in touch with stakeholders. Many companies have other types of meetings with varying usefulness.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintaining documentation&lt;/strong&gt;: A different form of communication is written text. To ease the job of our peers, we should maintain documentation - whether it's a user story, software documentation, process documentation, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reading&lt;/strong&gt;: Ideally, someone reads the documentation we write. On top of that, we read many other things. A few examples are existing code, StackOverflow, and language specifications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learning&lt;/strong&gt;: IT is a rapidly evolving industry. If we want to be up-to-date, we must invest in upskilling ourselves.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Administration and chores&lt;/strong&gt;: Reporting, periodic password changes, software updates, and timesheet submission fall in this category.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code reviews/pull requests&lt;/strong&gt;: Code reviews ensure software quality. But, depending on the author and the reviewer, they can take significant time to perform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaborative work&lt;/strong&gt;: Software engineering is a team sport. We need to help each other or brainstorm about solutions for more effective work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Building software&lt;/strong&gt;: Build times are still a factor&lt;sup id="fnref2"&gt;2&lt;/sup&gt;. Different languages, frameworks, codebase sizes, and building processes heavily affect this, but we can't ignore it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging and maintenance&lt;/strong&gt;: Finding problems in the code and refactoring are essential parts of the software lifecycle, and they can be very time-consuming tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context switching&lt;/strong&gt;: We suck at multitasking, and our focusing capabilities are also limited. The overwhelming amount of external stimuli and the cognitive load of software development puts the cherry on top. As a result, context switching is a significant time consumer&lt;sup id="fnref3"&gt;3&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Socializing&lt;/strong&gt;: Humans are social creatures. Even software engineers need human interactions. Interacting with our peers outside of work-related topics is crucial to our mental health.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resting&lt;/strong&gt;: Time-to-time, we need a break. We must take a short walk, stretch, look at our emails, or use the company ping-pong table to recharge our batteries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This list is not exhaustive but covers the most important items.&lt;/p&gt;

&lt;p&gt;We can boost our productivity and happiness by making as many of the above activities as efficient as possible.&lt;/p&gt;

&lt;p&gt;The two most exciting areas where AI can help us are text processing and code generation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Text Processing
&lt;/h2&gt;

&lt;p&gt;As we learned in the previous post, we shouldn't trust AI tools unquestioningly. But that doesn't mean they can't be helpful. We should also pay attention to legal considerations when we use them - especially for work. We should keep these considerations in mind when we apply the following tips.&lt;/p&gt;

&lt;p&gt;Reading through lengthy texts - especially poorly structured - is challenging. Large language models (LLM) are pretty good at extracting information from them.&lt;/p&gt;

&lt;p&gt;For example, we could ask them to summarize the entire text so we can have a bird's eye view of it. Then, if we need more detailed information about a specific topic, we can ask directed questions. &lt;strong&gt;It's essential to ask for a reference in the original text to double-check the validity of the answer.&lt;/strong&gt; There are many prompt engineering techniques to achieve this. &lt;a href="https://www.promptingguide.ai/" rel="noopener noreferrer"&gt;Prompt engineering guide&lt;/a&gt; is an excellent site to understand them.&lt;/p&gt;

&lt;p&gt;When it comes to user stories, we can identify them manually and create them from requirements using prompting techniques. Using a standardized user story template is beneficial so that AI will include all the necessary information.&lt;/p&gt;

&lt;p&gt;Handling PRs is also easier with AI. When we send it, we can summarize our changes in free text (for example, &lt;a href="https://graphite.dev/" rel="noopener noreferrer"&gt;Graphite&lt;/a&gt; does this). Reviewers can also generate a summary if the author didn't create one. On top of that, they can prompt about different parts of the change to better understand it.&lt;/p&gt;

&lt;p&gt;We can even request code examples based on language, library, or framework documentation. Like with StackOverflow answers, we shouldn't copy-paste the code without understanding it first.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI as a Programmer
&lt;/h2&gt;

&lt;p&gt;Compared to text processing, it's even more exciting that LLMs can generate code from our prompts because they already know of many technologies.&lt;/p&gt;

&lt;p&gt;Nvidia CEO Jensen Huang &lt;a href="https://www.techradar.com/pro/nvidia-ceo-predicts-the-death-of-coding-jensen-huang-says-ai-will-do-the-work-so-kids-dont-need-to-learn" rel="noopener noreferrer"&gt;predicts that AI will kill coding&lt;/a&gt;. John Carmack, the co-creator of Doom and Quake &lt;a href="https://twitter.com/ID_AA_Carmack/status/1762110222321975442" rel="noopener noreferrer"&gt;replied&lt;/a&gt; to him with the following:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Coding” was never the source of value, and people shouldn’t get overly attached to it. Problem solving is the core skill. The discipline and precision demanded by traditional programming will remain valuable transferable attributes, but they won’t be a barrier to entry.&lt;/p&gt;

&lt;p&gt;Many times over the years I have thought about a great programmer I knew that loved assembly language to the point of not wanting to move to C. I have to fight some similar feelings of my own around using existing massive codebases and inefficient languages, but I push through.&lt;/p&gt;

&lt;p&gt;I had somewhat resigned myself to the fact that I might be missing out on the “final abstraction”, where you realize that managing people is more powerful than any personal tool. I just don’t like it, and I can live with the limitations that puts on me.&lt;/p&gt;

&lt;p&gt;I suspect that I will enjoy managing AIs more, even if they wind up being better programmers than I am.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, could we use AI to replace software engineers? In a previous post&lt;sup id="fnref4"&gt;4&lt;/sup&gt;, we learned that requirements and code are different representations of the same thing: software behavior. Since it's nothing more than transforming one representation to the other, theoretically, they could generate entire applications (including tests) from the requirements.&lt;/p&gt;

&lt;p&gt;With current tooling, doing this wouldn't be wise for the following reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We have no control over the code quality&lt;/li&gt;
&lt;li&gt;We can't easily verify that the requirements, code, and tests are describing the same behavior&lt;/li&gt;
&lt;li&gt;Humans still suck at writing precise requirements&lt;/li&gt;
&lt;li&gt;Implementing entire applications is still too complex for current AI tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The solution is to follow the same process we do today: create the code one user story at a time. The changes will be more localized and easier to reason about. Also, we should have manual control over what is happening during development. What changes is that we'll use AI to generate some parts of the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test Vs. Code Generation
&lt;/h2&gt;

&lt;p&gt;We already know from the post about software behavior&lt;sup id="fnref4"&gt;4&lt;/sup&gt; that tests and code cross-verify each other. Therefore, we should write one manually and generate the other with AI. This way, we can ensure that the software works as intended. But which one should we write manually?&lt;/p&gt;

&lt;p&gt;Tests and code are on a different abstraction level. Tests describe &lt;strong&gt;what&lt;/strong&gt; the software should do, while code defines &lt;strong&gt;how&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Many developers focus on writing the code first and then adding the tests because they don't like testing. It seems obvious to automate test generation because they dislike that part. However, this introduces a few problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is like writing the requirements based on the code. We verify that the code does what it does - including bugs.&lt;/li&gt;
&lt;li&gt;Jumping from requirements (user stories) to implementation is jumping from the "what" to the "how" question. It's a significant cognitive load.&lt;/li&gt;
&lt;li&gt;Verifying that the code, the tests, and the requirements are in sync is not obvious.&lt;/li&gt;
&lt;li&gt;It's hard to incrementally add behavior to code when we think about the final solution or when the current implementation traps our thinking.&lt;/li&gt;
&lt;li&gt;We may need to rewrite entire parts of the code to alter its behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the other hand, manually writing the tests has many benefits over the previous way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Both tests and requirements focus on &lt;strong&gt;what&lt;/strong&gt; the software should do - making it easier to transform one into the other - primarily if we use a high-level syntax like &lt;a href="https://cucumber.io/docs/gherkin/" rel="noopener noreferrer"&gt;Gherkin&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;If the tests and the requirements are in sync and the generated code passes the tests, we can be sure that the code works as intended.&lt;/li&gt;
&lt;li&gt;The developer's cognitive load is lower.&lt;/li&gt;
&lt;li&gt;Every test represents a single behavior. Adding a new behavior means adding more tests - without touching existing ones.&lt;/li&gt;
&lt;li&gt;AI will generate code to pass tests. It doesn't mind rewriting huge portions of the codebase.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, we reinvented test-first development (TFD). Currently, the industry prefers TDD over TFD. Primarily because it's easier for humans to evolve the code incrementally, one behavior at a time, rather than writing it in one shot. AI tools don't have this limitation; they can deal with more complexity and larger code blocks. In other words, they might bring the golden age of TFD&lt;sup id="fnref5"&gt;5&lt;/sup&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As of 2024, AI tools won't replace software engineers. But they can significantly improve our productivity if we know how to use them. We must learn effective prompting and new working methods to utilize their capabilities.&lt;/p&gt;

&lt;p&gt;In this exciting era, every developer has the potential to drive change and revolutionize how we work. Are you ready to do that?&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;I heavily relied on &lt;a href="https://drpicox.medium.com/developers-spend-less-than-10-of-time-coding-51c36c73a93b" rel="noopener noreferrer"&gt;this post&lt;/a&gt; as a reference ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;&lt;a href="https://xkcd.com/303/" rel="noopener noreferrer"&gt;XKCD's evergreen comic about compilation&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;&lt;a href="https://www.monkeyuser.com/2018/focus/" rel="noopener noreferrer"&gt;This comic&lt;/a&gt; is an excellent representation ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;&lt;a href="https://dev.to/fanatixan/describing-software-behavior-30ll"&gt;Describing Software Behavior&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;At least for the few months before they wipe out humanity ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>programming</category>
      <category>ai</category>
    </item>
    <item>
      <title>Describing Software Behavior</title>
      <dc:creator>Attila Fejér</dc:creator>
      <pubDate>Mon, 15 Apr 2024 09:24:00 +0000</pubDate>
      <link>https://dev.to/fanatixan/describing-software-behavior-30ll</link>
      <guid>https://dev.to/fanatixan/describing-software-behavior-30ll</guid>
      <description>&lt;p&gt;In the world of software development, understanding software behavior is crucial. It's not just about writing code; it involves various steps and artifacts. In this post, we'll dive into the different ways to describe what a software product does, showing how they all connect to depict software behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development Process
&lt;/h2&gt;

&lt;p&gt;Software development is a multi-step process. Every step produces a specific type of output. If we want to boil it down, we create the following artifacts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Requirements&lt;/strong&gt;: The client introduces their needs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User Stories&lt;/strong&gt;: We turn the requirements into action items&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code&lt;/strong&gt;: We write the code to implement the product&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests&lt;/strong&gt;: We create tests to verify that the product behaves as expected&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Binary&lt;/strong&gt;: The executable software&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Obviously, phases can overlap, repeat, or even be reordered. For example, using agile methodologies or TDD, having new feature requests, and using interpreted languages can alter the process. The important thing is that these are the primary artifacts we create while developing the software, and most of them are present&lt;sup id="fnref1"&gt;1&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;It may be surprising that &lt;strong&gt;all these artifacts do the same thing: they describe the software's behavior&lt;/strong&gt;. The difference is the syntax and abstraction level:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The requirements are free-text and easily understandable by anyone who knows   the domain&lt;sup id="fnref2"&gt;2&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;User stories are more formal. In an ideal world, they contain examples and   user acceptance test (UAT) descriptions.&lt;/li&gt;
&lt;li&gt;Code is the ultimate description of the software's behavior. If we change the code, the software will behave differently.&lt;/li&gt;
&lt;li&gt;We often call tests executable documentation. They are as formal as the code but grasp a different perspective. The tests define &lt;strong&gt;what&lt;/strong&gt; the software should do, while the code describes &lt;strong&gt;how&lt;/strong&gt; it does its thing.&lt;/li&gt;
&lt;li&gt;A binary is also code: the only code that computers directly understand.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Creating them is very time-consuming and requires extensive manual work. This is why software development is error-prone. All these should describe the same behaviors, in theory&lt;sup id="fnref3"&gt;3&lt;/sup&gt;. But real life is very different. So, somehow, we need to ensure that these are in sync.&lt;/p&gt;

&lt;p&gt;We have two simple strategies to ensure consistency: automation and verification&lt;sup id="fnref4"&gt;4&lt;/sup&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automation
&lt;/h2&gt;

&lt;p&gt;All of these artifacts exist for a reason. In other words, we need all of them. But what if we don't create them manually but generate them from one of the others? Then, we generate the output from scratch every time the source format changes. This way, we don't have to look for places we need to update; by definition, the source and the output will be in sync.&lt;/p&gt;

&lt;p&gt;This approach has two preconditions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We need a way to convert one format to another effortlessly&lt;/li&gt;
&lt;li&gt;The generation needs to be deterministic&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Compiling the code to binary is a classic example. And indeed, we don't write machine code by hand anymore. Because of this (and because we already saw that binaries are low-level code), we'll treat binaries as code in the rest of the article and don't mention them specifically.&lt;/p&gt;

&lt;p&gt;A less obvious example is executable specifications—for instance, &lt;a href="https://cucumber.io/docs/gherkin/" rel="noopener noreferrer"&gt;Gherkin&lt;/a&gt; or &lt;a href="https://fitnesse.org/" rel="noopener noreferrer"&gt;FitNesse&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But not everything is easy to automate. Think of the user stories. Two developers can't even agree on using tabs or spaces&lt;sup id="fnref5"&gt;5&lt;/sup&gt;. It is on another level to make them understand user stories the same way and transform them into code. But there is hope: coding guidelines, standards, and new tooling&lt;sup id="fnref6"&gt;6&lt;/sup&gt; constantly make these steps more consistent and effortless.&lt;/p&gt;

&lt;p&gt;Generating one asset from the other has one more Achilles heel: errors in the source. Because the generated artifact will contain that error, too; for example, if the code has a typo in a print statement, the generated binary will print the message with the typo.&lt;/p&gt;

&lt;p&gt;This is when we can turn the situation into an advantage: we can cross-verify the different behavior descriptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verification
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.oxfordlearnersdictionaries.com/definition/english/verification" rel="noopener noreferrer"&gt;Oxford Dictionary&lt;/a&gt; has the following definition for "verification":&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[Verification is] the act of showing or checking that something is true or accurate.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For us, verification means checking that our assets are telling the same story. If we're unsure of something, we must step up one abstraction level and check there. In other words, we verify user stories based on requirements, code and tests based on user stories.&lt;/p&gt;

&lt;p&gt;Can we automate those checks? Currently, it's impossible to reliably verify the contents of free text. Not to mention two texts with different structure.&lt;/p&gt;

&lt;p&gt;What about code and tests? They are formal; therefore, they should be easier to verify. And indeed, we write tests to verify the code. The beauty is that this goes both ways: the code can verify tests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8i67rs9hm7z12oaoq0wh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8i67rs9hm7z12oaoq0wh.gif" alt="Say whaaat?!" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All of us were in a situation where we looked at our code for hours and didn't understand why it didn't pass the tests. Ultimately, it turned out we made a mistake in the test.&lt;/p&gt;

&lt;p&gt;It's the second reason why we shouldn't generate tests from the code. They will verify that the code works as the code works. How useful. If we have a bug&lt;sup id="fnref7"&gt;7&lt;/sup&gt;, the test will confirm the bug as the expected behavior. We'll have false confidence, and we will ensure we'll have a more challenging time catching the bug.&lt;/p&gt;

&lt;p&gt;As a summary, we can visualize the verification paths with the following diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftox7u4itwuysnimsvfrs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftox7u4itwuysnimsvfrs.png" alt=" " width="800" height="968"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reducing The Number of Levels
&lt;/h2&gt;

&lt;p&gt;After all the headaches that all these processes involve, it's natural that we want to simplify things by getting rid of unnecessary steps. Unfortunately, it's not that easy.&lt;/p&gt;

&lt;p&gt;The most significant difference between code and other description formats is the scope: code defines how to solve a problem, while the rest describes the expected behavior.&lt;/p&gt;

&lt;p&gt;To close the gap, we have two possible solutions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a programming language that focuses on the "what" and not the "how"&lt;/li&gt;
&lt;li&gt;Develop tools that understand what humans want&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Since our industry constantly looks for possible optimizations, these solutions aren't new at all.&lt;/p&gt;

&lt;p&gt;We call languages that focus on the "what" declarative languages. Two examples of them are &lt;a href="https://en.wikipedia.org/wiki/SQL" rel="noopener noreferrer"&gt;SQL&lt;/a&gt; (1974) and &lt;a href="https://www.swi-prolog.org/" rel="noopener noreferrer"&gt;Prolog&lt;/a&gt; (1987). In fact, they created SQL to enable end users to extract the data they need directly from the database. It turned out so great that even some developers can't write proper queries today. How could we expect end users to use these technologies properly?&lt;/p&gt;

&lt;p&gt;So, if we can't speak formal languages, why don't we teach computers to understand our language? That's exactly what we want to achieve with large language models. Recent developments are impressive, but we are still far from the end goal.&lt;/p&gt;

&lt;p&gt;There is a straightforward reason that none of the two approaches succeeded so far: humans.&lt;/p&gt;

&lt;p&gt;We are bad at properly articulating what we want or need. And even worse at thinking with new paradigms. Also, we tend to overcomplicate things.&lt;/p&gt;

&lt;p&gt;Solving all these problems is challenging, but AI has come a long way in the past few years. We can expect its development speed to increase, and today's mundane tasks will be bad memories tomorrow.&lt;/p&gt;

&lt;p&gt;But we live in the present, and we need solutions now. In a new post, we'll discuss how to work more efficiently with today's AI tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We define software behavior on multiple abstraction levels because people in different roles have different requirements. Those abstraction levels have deep interconnections we couldn't reduce in the past.&lt;/p&gt;

&lt;p&gt;With the rise of AI, the game seems to be changing, and our tasks will be much easier in the future.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Because we always write tests, right? ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;Presuming that they're free of contradictions-which they usually aren't ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;And we know what's the difference between theory and practice. In theory, nothing. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;Simple, but not easy ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=SsoOG6ZeyUI" rel="noopener noreferrer"&gt;Tabs versus Spaces&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn6"&gt;
&lt;p&gt;Looking at you, AI ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn7"&gt;
&lt;p&gt;Every decent application contains at least one line of code and one bug ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>behavior</category>
      <category>requirements</category>
    </item>
    <item>
      <title>AI Developer Tool Limitations In 2024</title>
      <dc:creator>Attila Fejér</dc:creator>
      <pubDate>Wed, 03 Apr 2024 18:53:00 +0000</pubDate>
      <link>https://dev.to/fanatixan/ai-developer-tool-limitations-in-2024-3d0b</link>
      <guid>https://dev.to/fanatixan/ai-developer-tool-limitations-in-2024-3d0b</guid>
      <description>&lt;p&gt;With the rise of &lt;a href="https://chat.openai.com/" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt;, &lt;a href="https://gemini.google.com/app" rel="noopener noreferrer"&gt;&lt;del&gt;Bard&lt;/del&gt; Gemini&lt;/a&gt;, &lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;GitHub Copilot&lt;/a&gt;, &lt;a href="https://preview.devin.ai/" rel="noopener noreferrer"&gt;Devin&lt;/a&gt;, and other AI tools&lt;sup id="fnref1"&gt;1&lt;/sup&gt;, developers started to fear that AI tooling would replace them. Even though their capabilities are indeed impressive, I don't fear our jobs will go away in 2024.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Software Development Is
&lt;/h2&gt;

&lt;p&gt;Let's start with understanding what we do as software developers.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An obvious answer is &lt;strong&gt;programming&lt;/strong&gt; because we have to tell the computer how to solve a problem.&lt;/li&gt;
&lt;li&gt;To do that, we need to &lt;strong&gt;identify the steps&lt;/strong&gt; to solve the problem. These are the steps we formalize using a programming language.&lt;/li&gt;
&lt;li&gt;If we want to solve a problem, we need to &lt;strong&gt;know what the problem is&lt;/strong&gt; in the first place. Usually, this is what clients try to tell us.&lt;/li&gt;
&lt;li&gt;More often than not, they are telling us &lt;strong&gt;what they want, not what they need&lt;/strong&gt;. In other words, they tell us their perception of their needs. Their story is filled with their biases, previous experiences, irrational desires, and personal limitations. The following portion of the well-known tree swing comic perfectly demonstrates this:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frockit.zone%2Fpost%2Fai-tooling%2Fai-dev-tool-limitations-2024%2Fask-vs-need.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frockit.zone%2Fpost%2Fai-tooling%2Fai-dev-tool-limitations-2024%2Fask-vs-need.png" width="570" height="389"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
    Client ask vs need -&lt;br&gt;
    &lt;a href="https://www.linkedin.com/pulse/tree-swing-communications-benjamin-j-donnelly-pmp/" rel="noopener noreferrer"&gt;Image source&lt;/a&gt;&lt;br&gt;
  
  &lt;/p&gt;

&lt;p&gt;Assuming that due to a miracle, we know exactly what the client needs, there is still one more gotcha: communication and precision.&lt;/p&gt;

&lt;p&gt;In most cases, software products are delivered by teams, not one-man-armies. If there is any miscommunication or misunderstanding between any two members of the team, they will have a different understanding of the desired outcome. Not to mention the edge cases and tiny details of the solution that nobody clarified.&lt;/p&gt;

&lt;p&gt;If those are not resolved, the product they deliver will be different from what the client needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Limitations
&lt;/h2&gt;

&lt;p&gt;Identifying the problem and its solution needs a deep understanding of human nature and behavior. Currently, AI tools don't have those. Even most humans lack those abilities - no wonder many organizations struggle with their software delivery.&lt;/p&gt;

&lt;p&gt;On top of these, there is a fundamental difference between humans and AI. We are pretty good at understanding vague descriptions. We have decades of life experience that we can utilize to fill the gaps and resolve contradictions in what they ask from us. On the other hand, machines will do &lt;strong&gt;exactly&lt;/strong&gt; what we ask them to do.&lt;/p&gt;

&lt;p&gt;There is a simple reason we are so good at working from bad specifications. 99% of the time, in any part of life, we have to work with flawed information. So we had to learn how to deal with them effectively. AI tools are not there (yet). They need a very comprehensive and precise specification.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frockit.zone%2Fpost%2Fai-tooling%2Fai-dev-tool-limitations-2024%2Fprecise-spec.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frockit.zone%2Fpost%2Fai-tooling%2Fai-dev-tool-limitations-2024%2Fprecise-spec.jpg" width="650" height="613"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
    A very comprehensive and precise spec -&lt;br&gt;
    &lt;a href="https://www.commitstrip.com/en/2016/08/25/a-very-comprehensive-and-precise-spec/?" rel="noopener noreferrer"&gt;Image source&lt;/a&gt;&lt;br&gt;
  
  &lt;/p&gt;

&lt;h2&gt;
  
  
  How Generative AI Works
&lt;/h2&gt;

&lt;p&gt;If we want to boil it down, generative AI&lt;sup id="fnref2"&gt;2&lt;/sup&gt; tools that create code are backed by large language models&lt;sup id="fnref3"&gt;3&lt;/sup&gt;. In a nutshell, they are trained on enormous amounts of text (code), and based on the context, they predict what could come next. There are multiple possible continuations. Based on their settings, they will go with one of the most likely ones.&lt;/p&gt;

&lt;p&gt;This works surprisingly well. But it also means that - unlike humans - AI tools can't create something completely new. They need existing references in their training data.&lt;/p&gt;

&lt;p&gt;It means two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;New technologies are not present in their training data so they didn't have a chance to learn them&lt;/li&gt;
&lt;li&gt;They can't solve new, complicated problems&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Training an AI to use a new technology is pretty easy. We need to show them enough code examples that use that technology. The problem is that we need to create that first. We are back to square one.&lt;/p&gt;

&lt;p&gt;Solving a complicated problem can be challenging to humans, too. But we can &lt;strong&gt;understand&lt;/strong&gt; and &lt;strong&gt;analyze&lt;/strong&gt; a new problem, and come up with a solution. AI can only predict a solution, but that's nothing more than guesswork for new problems. Like when we try to tell a dinosaur's color from their remains.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maintainability
&lt;/h2&gt;

&lt;p&gt;Let's say we have a well-defined problem that's not challenging and we want to implement it using a mature technology. For example, we need a registration form with plain old HTML and a Node.js + Express backend. That's familiar ground for AI tools, so we can bravely use them to generate the code. They even create tests&lt;sup id="fnref4"&gt;4&lt;/sup&gt;. Everything is working, we delivered it in record time, and the client is satisfied. This seems like a win-win situation. But is it?&lt;/p&gt;

&lt;p&gt;What happens if the next day the client asks to integrate the newest and shiniest captcha? We already know that since it's a new technology, the AI most likely won't be familiar with it. No problem, it seems a simple task. We are confident we can implement it ourselves in no time.&lt;/p&gt;

&lt;p&gt;If the generated code is high-quality we indeed don't have any problems. But what happens if it isn't? What if it's the worst spaghetti code we ever faced?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frockit.zone%2Fpost%2Fai-tooling%2Fai-dev-tool-limitations-2024%2Fspaghetti-code-monster.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Frockit.zone%2Fpost%2Fai-tooling%2Fai-dev-tool-limitations-2024%2Fspaghetti-code-monster.jpg" width="800" height="800"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
    Fighting the spaghetti code monster - &lt;br&gt;
    Generated with&lt;br&gt;
    &lt;a href="https://designer.microsoft.com/image-creator" rel="noopener noreferrer"&gt;Microsoft Designer Image Creator&lt;/a&gt;&lt;br&gt;
  
  &lt;/p&gt;

&lt;p&gt;We either try to tame it and make it more maintainable (maybe with the AI tool we already lost confidence in), or trash it and rewrite it from scratch. Either way, it will take too much time compared to the initial solution.&lt;/p&gt;

&lt;p&gt;Because of AI limitations, humans will have to understand and maintain the code. If it's low quality, or even too smart&lt;sup id="fnref5"&gt;5&lt;/sup&gt;, we will have a very hard time dealing with it. It's tricky to ensure a generated code's quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Legal Issues
&lt;/h2&gt;

&lt;p&gt;Most of the code is created for and by companies to realize revenue. It's still an unregulated question that who owns AI-generated content. The prompt writer? The AI tool's creator? The owner of the training data?&lt;/p&gt;

&lt;p&gt;The problem becomes even &lt;del&gt;more interesting&lt;/del&gt; tougher if we think about the code's behavior and its responsibility. What if the code causes harm? For example, deletes some important files. Sells stocks and we lose money. Controls hardware that causes harm to humans. Whose responsibility will that be?&lt;/p&gt;

&lt;p&gt;This question is tricky enough with self-driving cars&lt;sup id="fnref6"&gt;6&lt;/sup&gt;. It becomes a disaster if we add AI-generated code to the mix&lt;sup id="fnref7"&gt;7&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;With that level of uncertainty, many companies don't want to jump on the AI train. I can't blame them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As we saw, AI tooling has major limitations when it comes to software development. But it's nothing more than how things stand in April 2024. AI solutions evolve at an incredible speed. No doubt they will become much better not only in the coming years but also in the coming months.&lt;/p&gt;

&lt;p&gt;In this post, we mostly talked about limitations. Fortunately, it doesn't mean that these tools aren't useful. In a follow-up post, we'll see how we can and should use them to maximize our productivity. Because it's already a cliche that AI won't steal our jobs. Someone who knows how to use AI will.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;A non-comprehensive list: &lt;a href="https://deepmind.google/discover/blog/competitive-programming-with-alphacode/" rel="noopener noreferrer"&gt;AlphaCode&lt;/a&gt;, &lt;a href="https://www.tabnine.com/" rel="noopener noreferrer"&gt;Tabnine&lt;/a&gt;, &lt;a href="https://sourcery.ai/" rel="noopener noreferrer"&gt;Sourcery&lt;/a&gt;, &lt;a href="https://snyk.io/platform/deepcode-ai/" rel="noopener noreferrer"&gt;DeepCode AI&lt;/a&gt;, &lt;a href="https://wpcode.com/" rel="noopener noreferrer"&gt;WPCode&lt;/a&gt;, &lt;a href="https://www.askcodi.com/" rel="noopener noreferrer"&gt;Ask Codi&lt;/a&gt;, &lt;a href="https://www.codiga.io/" rel="noopener noreferrer"&gt;Codiga&lt;/a&gt;, &lt;a href="https://jedi.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;Jedi&lt;/a&gt;, &lt;a href="https://aws.amazon.com/codewhisperer/?ref=codesubmit" rel="noopener noreferrer"&gt;CodeWhisperer&lt;/a&gt;, &lt;a href="https://magic.dev/" rel="noopener noreferrer"&gt;Magic&lt;/a&gt;, &lt;a href="https://sourcery.ai/" rel="noopener noreferrer"&gt;Sourcery&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Generative_artificial_intelligence" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Generative_artificial_intelligence&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Large_language_model" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Large_language_model&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;But can we trust those tests? We'll talk more about that in the next post. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;A great example is the &lt;a href="https://en.wikipedia.org/wiki/Fast_inverse_square_root#Overview_of_the_code" rel="noopener noreferrer"&gt;reverse square root function in the Quake engine&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn6"&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Self-driving_car_liability" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Self-driving_car_liability&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn7"&gt;
&lt;p&gt;Maybe it's time to retrain ourselves as lawyers so we'll have plenty of work when we're not needed as developers. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>ai</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Replacing Type Code With Subclasses</title>
      <dc:creator>Attila Fejér</dc:creator>
      <pubDate>Sun, 04 Feb 2024 10:57:36 +0000</pubDate>
      <link>https://dev.to/fanatixan/replacing-type-code-with-subclasses-1icb</link>
      <guid>https://dev.to/fanatixan/replacing-type-code-with-subclasses-1icb</guid>
      <description>&lt;p&gt;We've previously dived into the complexities and maintenance challenges of &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; and saw a refactoring technique for simple scenarios.&lt;/p&gt;

&lt;p&gt;Today, we'll raise the bar a bit and focus on situations when our type code affects behavior. We'll use pets to demonstrate the concepts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting Point
&lt;/h2&gt;

&lt;p&gt;We want to model different pets: dogs, cats, and birds. Initially, we might represent this with a type code:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;DOG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;CAT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;BIRD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;Pet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;DOG:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"woof"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;CAT:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"meow"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;BIRD:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"chirp"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unknown pet type"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;DOG:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"run"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;CAT:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"climb"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;BIRD:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"fly"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unknown pet type"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And its usage:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="n"&gt;buddy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Pet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DOG&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buddy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We already saw that &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt;, has several downsides&lt;sup id="fnref1"&gt;1&lt;/sup&gt;. It's not only repetitive but also violates the Open/Closed Principle. Adding a new pet type means editing multiple parts of the class.&lt;/p&gt;

&lt;h2&gt;
  
  
  Refactoring: Using an Enum
&lt;/h2&gt;

&lt;p&gt;As we learned in the previous post&lt;sup id="fnref2"&gt;2&lt;/sup&gt;, we can refactor this code into an enum:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="no"&gt;DOG&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"woof"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"run"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
  &lt;span class="no"&gt;CAT&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"meow"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"climb"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
  &lt;span class="no"&gt;BIRD&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"chirp"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"fly"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;Pet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sound&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;movement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Its usage is even simpler than the previous:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="n"&gt;buddy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;DOG&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buddy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far so good. But while pizzas had only data&lt;sup id="fnref2"&gt;2&lt;/sup&gt;, pets are more dynamic and they have behavior, too. For example, they can interact with objects, like balls:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Ball&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;bat&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ignore&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="no"&gt;DOG&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"woof"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"run"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
  &lt;span class="no"&gt;CAT&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"meow"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"climb"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
  &lt;span class="no"&gt;BIRD&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"chirp"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"fly"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;Pet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sound&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;movement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;interact&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Ball&lt;/span&gt; &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;DOG:&lt;/span&gt;
        &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fetch&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;CAT:&lt;/span&gt;
        &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bat&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;BIRD:&lt;/span&gt;
        &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ignore&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Despite previous efforts, &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; have returned to the code. Fortunately, we can get rid of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operation as Data
&lt;/h2&gt;

&lt;p&gt;The first possibility is to treat operations like data. There are programming languages, where functions are first-class-citizens and we can store them in variables. Such languages are C and JavaScript. A possible solution in JS can look like the following:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Ball&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="nf"&gt;bat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="nf"&gt;ignore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;DOG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;woof&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;run&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;CAT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;meow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;climb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;BIRD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chirp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fly&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;movement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ballInteraction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sound&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;movement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;movement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ballInteraction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ballInteraction&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;communicate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sound&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;movement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;interact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ball&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ballInteraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ball&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But in Java, we can't store functions in variables (obviously 😒). But since Java 8, we can use function-like constructs: functional interfaces, lambda expressions (similar to JS arrow functions), and method references (which is a syntactic sugar for lambdas):&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="no"&gt;DOG&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"woof"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"run"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fetch&lt;/span&gt;&lt;span class="o"&gt;()),&lt;/span&gt;  &lt;span class="c1"&gt;// lambda&lt;/span&gt;
  &lt;span class="no"&gt;CAT&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"meow"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"climb"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bat&lt;/span&gt;&lt;span class="o"&gt;()),&lt;/span&gt;          &lt;span class="c1"&gt;// lambda&lt;/span&gt;
  &lt;span class="no"&gt;BIRD&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"chirp"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"fly"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;Ball:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ignore&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;          &lt;span class="c1"&gt;// method reference&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Ball&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ballInteraction&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;              &lt;span class="c1"&gt;// functional interface expecting a single Ball argument&lt;/span&gt;

  &lt;span class="nc"&gt;Pet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Ball&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ballInteraction&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sound&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;movement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ballInteraction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ballInteraction&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sound&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;movement&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;interact&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Ball&lt;/span&gt; &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ballInteraction&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Despite that it works, this solution has multiple downsides:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Violating Open/Closed Principle&lt;/strong&gt;: We still have to modify the &lt;code&gt;Pet&lt;/code&gt; enum to introduce new pet types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One instance per type&lt;/strong&gt;: We can have only one instance per pet type. For example, we can't have two dogs with different names.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readability&lt;/strong&gt;: The instantiation starts to become long and unreadable, especially with many arguments and more complex interactions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Introducing Subclasses
&lt;/h2&gt;

&lt;p&gt;Since Java is an object-oriented language, let's apply some polymorphism. Refactor our &lt;code&gt;Pet&lt;/code&gt; enum to a base class and subclasses for each pet type. This way, we encapsulate the behavior specific to each pet type within its subclass:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;interact&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Ball&lt;/span&gt; &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"woof"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"run"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;interact&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Ball&lt;/span&gt; &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fetch&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"meow"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"climb"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;interact&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Ball&lt;/span&gt; &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bat&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bird&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"chirp"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"fly"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;interact&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Ball&lt;/span&gt; &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ball&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ignore&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: in this example, &lt;code&gt;Pet&lt;/code&gt; could have been an interface of a class. This detail doesn't matter regarding the approach.&lt;/p&gt;

&lt;p&gt;And its usage:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="n"&gt;buddy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buddy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;communicate&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The advantages of this approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Encapsulation of Behavior&lt;/strong&gt;: Each subclass defines its unique behavior, making the code more organized and readable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open/Closed Principle&lt;/strong&gt;: Our &lt;code&gt;Pet&lt;/code&gt; class is now open for extension but closed for modification. Adding a new pet type becomes much easier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elimination of &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt;&lt;/strong&gt;: We've removed the cumbersome &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; structures, leading to cleaner and more maintainable code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamicity&lt;/strong&gt;: Subclasses can have as many instances as we need. Also, they can have their own fields and behaviors that other pet types don't.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This refactoring's name is (not surprisingly) &lt;a href="https://refactoring.guru/replace-type-code-with-subclasses" rel="noopener noreferrer"&gt;replace type code with subclasses&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;When the type code affects behavior, refactoring type codes to subclasses offers numerous benefits in terms of maintainability and scalability. It aligns with the principles of good object-oriented design and results in cleaner, more modular code.&lt;/p&gt;

&lt;p&gt;But for simple cases, a good old enum with some function references can be a good choice, too.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;The downsides of switch case in the &lt;a href="https://dev.to/fanatixan/the-dark-side-of-switch-case-kia"&gt;first part&lt;/a&gt; of the series ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;&lt;a href="https://dev.to/fanatixan/replacing-type-code-with-class-1c5i"&gt;Replacing Type Code with Enum&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>programming</category>
      <category>refactoring</category>
      <category>switchcase</category>
    </item>
    <item>
      <title>Replacing Type Code With Class</title>
      <dc:creator>Attila Fejér</dc:creator>
      <pubDate>Sun, 23 Apr 2023 07:48:00 +0000</pubDate>
      <link>https://dev.to/fanatixan/replacing-type-code-with-class-1c5i</link>
      <guid>https://dev.to/fanatixan/replacing-type-code-with-class-1c5i</guid>
      <description>&lt;p&gt;In the previous part, we had an overview of why &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; could be hard to maintain. This part will focus on the simplest scenario: when type-code only affects data, not behavior. We'll do this by modeling a pizzeria.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial Solution
&lt;/h2&gt;

&lt;p&gt;In our pizzeria, when customers place an order, they can choose the size and kind of toppings they want. The price of the pizza only depends on its size. For the sake of simplicity (and because our slogan is "You dream it, we make it"), we don't want to limit what kind of toppings customers can choose. Therefore, we'll model the toppings as a list of strings.&lt;br&gt;
So our pizza class will look like the following:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;SIZE_SMALL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;SIZE_NORMAL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;SIZE_LARGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toppings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;price&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SIZE_SMALL:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SIZE_NORMAL:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SIZE_LARGE:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The field 'size' has an invalid value"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The use of this class is pretty straightforward. Assuming that we want to calculate the price of our new favorite normal-size coconut-catnip pizza&lt;sup id="fnref1"&gt;1&lt;/sup&gt;, we would write:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Pizza&lt;/span&gt; &lt;span class="n"&gt;pizza&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"coconut"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"catnip"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SIZE_NORMAL&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pizza&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Until this, we always gave five pizzas to our delivery guy at every turn he made because he couldn't carry more large pizzas. But what about if we get an order of ten small pizzas? It would be a shame to deliver it in two rounds. After all, two small pizzas weigh less than a large one.&lt;/p&gt;

&lt;p&gt;So to optimize our process, we want to calculate the weight of each pizza. Again, for simplicity's sake, we assume a pizza's weight depends only on size. So we add this method to our class:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SIZE_SMALL:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SIZE_NORMAL:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.75&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SIZE_LARGE:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;1.25&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The field 'size' has an invalid value"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It was as easy as copying the previous method and changing the result type, the method name, and the return values.&lt;/p&gt;

&lt;p&gt;What would happen if we needed one more method, depending on the size? Let's say a &lt;code&gt;toString()&lt;/code&gt; method. We would make new copies again and again. Those who don't like this much code duplication, raise your hands! Well, if you didn't raise your hand, shame on you! But don't worry; I'll convince you it isn't good.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extending Size Options
&lt;/h2&gt;

&lt;p&gt;Let's say our pizzeria is so popular we want to present monster-size pizzas. It's pretty simple; we should create a new constant for the new size and a new &lt;code&gt;case&lt;/code&gt; clause for each &lt;code&gt;switch&lt;/code&gt; statement. Our new code:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;SIZE_SMALL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;SIZE_NORMAL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;SIZE_LARGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;SIZE_MONSTER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toppings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;price&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SIZE_SMALL:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SIZE_NORMAL:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SIZE_LARGE:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The field 'size' has an invalid value"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SIZE_SMALL:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SIZE_NORMAL:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.75&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SIZE_LARGE:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;1.25&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;SIZE_MONSTER:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The field 'size' has an invalid value"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can already feel a smell. We had to modify a method to extend its capabilities. That violates the &lt;a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle" rel="noopener noreferrer"&gt;Open/Closed Principle&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Unfortunately, we have bigger issues when we want to use it:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Pizza&lt;/span&gt; &lt;span class="n"&gt;pizza&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"coconut"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"catnip"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SIZE_MONSTER&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pizza&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We get an &lt;code&gt;IllegalStateException&lt;/code&gt;. Why?&lt;/p&gt;

&lt;p&gt;Of course, we just forgot to insert the new &lt;code&gt;case&lt;/code&gt; statement into our &lt;code&gt;price()&lt;/code&gt; method. You probably noticed it already, but it's an elementary example. If you had a more complex situation, it's much harder to remember every &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt;s to change. I almost don't dare to mention how much harder it is if your &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt;s are not in a simple class but scattered all over your codebase&lt;sup id="fnref2"&gt;2&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Still not convinced? Don't worry; there's more.&lt;/p&gt;

&lt;p&gt;Let's forget for a minute that we implemented this class. Let's look at our only constructor's signature:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What does it tell us? Not so much. And of course, the class doesn't have any JavaDoc. No worries, we will figure out how to use it. Our first try:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Pizza&lt;/span&gt; &lt;span class="n"&gt;pizza&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pizza&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aaaand we get an &lt;code&gt;IllegalStateException&lt;/code&gt; in the second row. Pretty sure it's because we used null as the first argument, right?&lt;/p&gt;

&lt;p&gt;Of course, we know that this isn't the problem: we provided an invalid size value. Yes, it would be better if we did some argument checking in the constructor, but that's not the point. If somehow we modified our size field internally and it ended up invalid, the problem would be the same. It doesn't matter how hard we try to avoid these scenarios; the possibility remains.&lt;/p&gt;

&lt;p&gt;It would be much better if we resolved the root cause of the problem and our field couldn't have an invalid value at all. More accurately, if the value validation would happen at compile time and not runtime.&lt;/p&gt;

&lt;p&gt;What? Validation at compile time? Of course! We call it static typing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing an Enum
&lt;/h2&gt;

&lt;p&gt;Let's try a new approach. Instead of &lt;code&gt;int&lt;/code&gt; constants, we declare a &lt;code&gt;Size&lt;/code&gt; enum:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;SMALL&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;NORMAL&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;LARGE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;MONSTER&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toppings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;price&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SMALL&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NORMAL&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LARGE&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MONSTER&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The field 'size' has an invalid value"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SMALL&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NORMAL&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.75&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LARGE&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;1.25&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MONSTER&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The field 'size' has an invalid value"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instantiation:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Pizza&lt;/span&gt; &lt;span class="n"&gt;pizza&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"coconut"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"catnip"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MONSTER&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because of static typing in Java, the size field will always have a valid value (except when we pass &lt;code&gt;null&lt;/code&gt;, but let's leave that problem to another day). But the &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; is still there. Every time we create a new size, all &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; statements we use with size as a condition must be updated. We will probably forget one or two.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Rid of Switch-Case
&lt;/h2&gt;

&lt;p&gt;Let's modify the &lt;code&gt;Size&lt;/code&gt; enum to a class. Classes can have fields, so we don't have to use the &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; statement anymore:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;getPrice&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;getWeight&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="no"&gt;SIZE_SMALL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="no"&gt;SIZE_NORMAL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.75&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="no"&gt;SIZE_LARGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.25&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="no"&gt;SIZE_MONSTER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toppings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;price&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPrice&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWeight&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using it:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Pizza&lt;/span&gt; &lt;span class="n"&gt;pizza&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"coconut"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"catnip"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SIZE_MONSTER&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why is it better? We have multiple reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can't pass an invalid &lt;code&gt;Size&lt;/code&gt;. The &lt;code&gt;Size&lt;/code&gt; constructor is private, which means it can't be called from outside. Only predefined size constants can be used.&lt;/li&gt;
&lt;li&gt;If we want to support a new size, we create a new instance. The compiler will raise an error if we forget to set a required value since the constructor lacks an argument.&lt;/li&gt;
&lt;li&gt;Because of the absence of the &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; statement, our code is much cleaner.&lt;/li&gt;
&lt;li&gt;If we want the pizza to have a new property that depends on the size, we only have to add a new field to the &lt;code&gt;Size&lt;/code&gt; class, make it mandatory in the constructor and write a new getter. The compiler will mark all errors; we are good to go after fixing them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So this is the ultimate solution? Well, almost. The enum way was a bit cleaner because it declared all its constants. Let's see how we can return to them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Revenge of the Enums
&lt;/h2&gt;

&lt;p&gt;First, let's refactor our code and move the constant declarations into the &lt;code&gt;Size&lt;/code&gt; class:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="no"&gt;SMALL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="no"&gt;NORMAL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.75&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="no"&gt;LARGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.25&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="no"&gt;MONSTER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;getPrice&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;getWeight&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toppings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;price&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPrice&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWeight&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Pizza&lt;/span&gt; &lt;span class="n"&gt;pizza&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"coconut"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"catnip"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MONSTER&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this way, we can create new &lt;code&gt;Size&lt;/code&gt; instances in the &lt;code&gt;Pizza&lt;/code&gt; class too, which can be confusing. We could move the &lt;code&gt;Size&lt;/code&gt; class to its file. Because of the private constructor, it couldn't be called from outside.&lt;/p&gt;

&lt;p&gt;There is a different solution, which involves enums again. But we already covered that part; what new can enums possibly provide? Let's examine what enums are and how they work in Java.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Enums
&lt;/h3&gt;

&lt;p&gt;In C (and most languages) enum is a convenient way of declaring automatically incrementing &lt;code&gt;int&lt;/code&gt; constants. If we wanted, we could set the value of some of the constants manually or even repeat the values:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;pizza_size&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;SMALL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NORMAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LARGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EXTRA_LARGE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MONSTER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EXTRA_LARGE&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;pizza_size&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NORMAL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, &lt;code&gt;SMALL&lt;/code&gt;, &lt;code&gt;NORMAL&lt;/code&gt;, &lt;code&gt;LARGE&lt;/code&gt;, and &lt;code&gt;MONSTER&lt;/code&gt; will have the values &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;, &lt;code&gt;4&lt;/code&gt;, and &lt;code&gt;4&lt;/code&gt;, respectively. But basically, those are just &lt;code&gt;int&lt;/code&gt; constants. Enum variables can still have any value. C++ and C# also use a similar approach.&lt;/p&gt;

&lt;p&gt;But not Java. Of course, you could say Java always chooses its path. Don't judge quickly because the Java enum is very cool.&lt;/p&gt;

&lt;p&gt;Java enums are similar to the &lt;code&gt;Size&lt;/code&gt; class we just implemented. They are classes (static ones, if declared as inner types) with a private constructor. The only instances they can have are the ones we declared.&lt;/p&gt;

&lt;p&gt;There are a couple of advantages of this design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can compare enum variables with &lt;code&gt;==&lt;/code&gt;, like &lt;code&gt;int&lt;/code&gt;s. If the contained constants differ, we compare the reference of two different instances, which returns false. If they have the same value, they will be represented by the same object, so the references will be the same. Hence, the comparison will return true. It means convenient, fast, and readable comparison.&lt;/li&gt;
&lt;li&gt;Because they are classes, they can have properties, methods, and constructors. The only limitation we have is the visibility of the constructors: they are always private.&lt;/li&gt;
&lt;li&gt;We cannot accidentally instantiate them (because of the private constructor). Instantiation always happens as a new constant declaration.&lt;/li&gt;
&lt;li&gt;They are always ordered, which can be rather valuable sometimes. The order is the declaration order, and we can query the (0-based) ordinal with the implicit &lt;code&gt;int ordinal()&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;Similarly, we can access the declared name using the &lt;code&gt;String name()&lt;/code&gt; method or convert the name to a constant with the &lt;code&gt;static T valueOf(String)&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;Instances are always &lt;code&gt;public static final&lt;/code&gt;, and constructors are &lt;code&gt;private&lt;/code&gt;. We don't have to specify these keywords (in fact, we get an error if we use different visibility).&lt;/li&gt;
&lt;li&gt;Because of the private constructor, we cannot extend enums (would it even make sense?).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Applying Smart Enums
&lt;/h3&gt;

&lt;p&gt;Because of the above, we can rewrite the &lt;code&gt;Size&lt;/code&gt; class to an enum:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;enum&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="no"&gt;SMALL&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="no"&gt;NORMAL&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.75&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="no"&gt;LARGE&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.25&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="no"&gt;MONSTER&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;getPrice&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;getWeight&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Size&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toppings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toppings&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;price&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPrice&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWeight&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's very similar to our previous example but with less boilerplate code. Sweet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dealing With User Input
&lt;/h2&gt;

&lt;p&gt;So far, we have determined values based on size. But that size comes from the user. If we have a web application, it's most probably comes from a dropdown or a radio button:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;select&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"size"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"SMALL"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Small&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"MEDIUM"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Medium&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"LARGE"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Large&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"MONSTER"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Monster&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here, sizes are strings. How can we convert those to &lt;code&gt;Size&lt;/code&gt; instances?&lt;/p&gt;

&lt;p&gt;In Java, it's pretty straightforward with the enum solution:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sizeName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Size&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Pizza&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sizeName&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But what if we need to work with a different language, let's say JavaScript? We could always introduce a &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt;, but we know better now.&lt;/p&gt;

&lt;p&gt;A better solution is to use lookup tables. Every language has an implementation for it with possibly different names: map, dictionary, table; you name it.&lt;/p&gt;

&lt;p&gt;For example, in JavaScript, the simplest solution is to use an object:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sizes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;SMALL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Pizza&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SMALL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;MEDIUM&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Pizza&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MEDIUM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;LARGE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Pizza&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LARGE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;MONSTER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Pizza&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MONSTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The usage is straightforward:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sizeName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sizeName&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want, we can even inline the constant declarations:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sizes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;SMALL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Pizza&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;NORMAL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Pizza&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.75&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;LARGE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Pizza&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.25&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;MONSTER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Pizza&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since lookup tables are more flexible in certain circumstances, this is a good solution, too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post, our type code was the pizza size. We can use the above solutions effectively if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A handful of attributes' values depend on the type code&lt;/li&gt;
&lt;li&gt;The methods' behavior is always the same (They don't do different things if the type code changes. Returning different values is a single behavior. Eating a pizza or wearing it as a hat are not.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We introduced a few possible ways to refactor the code and get rid of &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introducing a class with a fixed set of constant instances&lt;sup id="fnref3"&gt;3&lt;/sup&gt;
&lt;/li&gt;
&lt;li&gt;In Java, using enums to achieve the same&lt;/li&gt;
&lt;li&gt;Using lookup tables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the behavior of our class also depends on the type code, we have to use different approaches. We will cover them in the following parts.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Yummy ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;For a deeper explanation, take a look at the &lt;a href="https://dev.to/fanatixan/the-dark-side-of-switch-case-kia"&gt;first part&lt;/a&gt; of the series ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;This refactoring even has a name: &lt;a href="https://refactoring.guru/replace-type-code-with-class" rel="noopener noreferrer"&gt;Replace Type Code With Class&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>programming</category>
      <category>refactoring</category>
      <category>switchcase</category>
    </item>
    <item>
      <title>The Dark Side of Switch-Case</title>
      <dc:creator>Attila Fejér</dc:creator>
      <pubDate>Sun, 23 Apr 2023 07:47:00 +0000</pubDate>
      <link>https://dev.to/fanatixan/the-dark-side-of-switch-case-kia</link>
      <guid>https://dev.to/fanatixan/the-dark-side-of-switch-case-kia</guid>
      <description>&lt;p&gt;In a nutshell: &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; makes code harder to maintain. We'll understand the reasons to eliminate it and see when its usage is justified.&lt;/p&gt;

&lt;p&gt;Since the topic is enormous, we'll learn about the different tactics in separate posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Avoid Switch-Case
&lt;/h2&gt;

&lt;p&gt;As we mentioned, the critical problem is maintainability. For companies that use high-level languages independently of the platform (mobile, desktop, frontend, backend, you name it), maintainability is one of the most crucial metrics of the code. Performance is only secondary (within reasonable bounds) since processing power is cheaper than developers. We don't want to squeeze the last bit of performance out of the code. We want to make it easy to read and modify so developers can debug and add features more effectively.&lt;/p&gt;

&lt;p&gt;But there are circumstances when performance is primary. Usually, we use lower-level languages in these situations. Here are a few examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Embedded systems, where the processing power is limited (washing machine, microwave, toys), or we need to strive for low energy consumption (sensor networks)&lt;/li&gt;
&lt;li&gt;Real-time systems, where a timeout has potentially catastrophic effects (cars, trains, planes, chemical plants)&lt;/li&gt;
&lt;li&gt;Low-level code with possibly many dependents (OS kernel, device firmware)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In such cases&lt;sup id="fnref1"&gt;1&lt;/sup&gt;, a &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; statement is an excellent choice because of its performance.&lt;/p&gt;

&lt;p&gt;Let's look under the hood to understand why it performs well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Switch-case Under the Hood
&lt;/h2&gt;

&lt;p&gt;Let's consider a simple example in C:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;connectionState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;statusLed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;CONNECTED&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;// CONNECTED == 0&lt;/span&gt;
    &lt;span class="n"&gt;statusLed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SOLID_GREEN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;CONNECTING&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;// CONNECTING == 1&lt;/span&gt;
    &lt;span class="n"&gt;statusLed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BLINKING_BLUE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;      &lt;span class="c1"&gt;// ERROR == 2&lt;/span&gt;
    &lt;span class="n"&gt;statusLed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BLINKING_RED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the possible values are small, consecutive numbers, the compiler could generate the following assembly-like pseudo code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  jump_forward    connectionState /* skips connectionState lines */

  jump            connected       /* value 0 */
  jump            connecting      /* value 1 */
  jump            error           /* value 2 */

connected:
  assign          statusCode, SOLID_GREEN
  jump            after_switch

connecting:
  assign          statusCode, BLINKING_BLUE
  jump            after_switch

error:
  assign          statusCode, BLINKING_RED
  jump            after_switch

after_switch:
  /* rest of the code */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that it's far from valid assembly code, but it's good enough to understand what's going on:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;jump_forward&lt;/code&gt; goes to a statement relative to the current one. When its argument is &lt;code&gt;0&lt;/code&gt;, it goes to the next one. When it's &lt;code&gt;1&lt;/code&gt;, it goes to the second, and so on.&lt;/li&gt;
&lt;li&gt;From those labels, we unconditionally jump to a specific location containing the &lt;code&gt;case&lt;/code&gt; statement's body.&lt;/li&gt;
&lt;li&gt;At the end of the &lt;code&gt;case&lt;/code&gt; statement, we go after the end of the &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As we can see, the number of instructions we need to get to the block that executes a &lt;code&gt;case&lt;/code&gt; statement's body is independent of the number of &lt;code&gt;case&lt;/code&gt;s. That's not only fast; it's also scalable.&lt;/p&gt;

&lt;p&gt;What if the values aren't consecutive? Wouldn't having those &lt;code&gt;jump&lt;/code&gt; statements with empty instructions between them be a waste of code memory?&lt;/p&gt;

&lt;p&gt;Fortunately, compilers are smart and can optimize to handle these situations effectively. Let's modify the constants in the previous example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;connectionState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;statusLed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;CONNECTED&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;// CONNECTED == 0&lt;/span&gt;
    &lt;span class="n"&gt;statusLed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SOLID_GREEN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;CONNECTING&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;// CONNECTING == 2&lt;/span&gt;
    &lt;span class="n"&gt;statusLed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BLINKING_BLUE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;      &lt;span class="c1"&gt;// ERROR == 16&lt;/span&gt;
    &lt;span class="n"&gt;statusLed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BLINKING_RED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A possible compilation could be this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  jump_forward    connectionState               /* skips connectionState lines */

  assign          statusCode, SOLID_GREEN       /* value 0 */
  jump            after_switch

  assign          statusCode, BLINKING_BLUE     /* value 2 */
  jump            after_switch

after_switch:                                   /* we have space for 13 instructions here */
  /* first few lines of rest of the code */
  jump continue_working

  assign          statusCode, BLINKING_RED      /* value 6 */
  jump            after_switch

continue_working:
  /* rest of the code */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, the spaces between &lt;code&gt;case&lt;/code&gt; handlers won't necessarily go to waste. We could inline a &lt;code&gt;case&lt;/code&gt;'s body (and by that, we got rid of a few jumps) or some other code&lt;sup id="fnref2"&gt;2&lt;/sup&gt;. Compilers are tricky bastards, indeed&lt;sup id="fnref3"&gt;3&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;For more complicated situations (for example, when the &lt;code&gt;switch&lt;/code&gt;'s condition is a string), the compiler has other tricks, like lookup tables. The worst-case scenario is &lt;code&gt;O(n)&lt;/code&gt; complexity, where &lt;code&gt;n&lt;/code&gt; is the number of &lt;code&gt;case&lt;/code&gt; statements. The compiler can analyze a &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; and use the best strategy. With other techniques, it may not be as obvious what to do.&lt;/p&gt;

&lt;p&gt;Now we know why &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; is so fast to execute. Let's dive into what are its maintainability issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Switch-case Maintainability
&lt;/h2&gt;

&lt;p&gt;So what's this nonsense that &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; is hard to maintain? It's far more readable and maintainable than complex if-else structures, right? Indeed, but it doesn't mean we don't have better alternatives.&lt;/p&gt;

&lt;p&gt;Often, we use &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; to differentiate between different values of the same thing and perform operations depending on the value. For example, a person's blood type (A, B, AB, 0) or the species of a pet (dog, cat). We call a property type-code or discriminator if we use it to distinguish different kinds of an object.&lt;/p&gt;

&lt;p&gt;In the former case, the type could be the person object's attribute, while the latter is the pet object's class.&lt;/p&gt;

&lt;p&gt;Let's see an example of the second scenario in Java (17+):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Pet&lt;/span&gt; &lt;span class="n"&gt;pet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pet&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;Dog:&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"woof"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;Cat:&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"meow"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It looks simple enough, but there are multiple problems with this approach.&lt;/p&gt;

&lt;p&gt;First, when we introduce a &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; statement, it tends to appear in multiple places. Either because we want to do different things based on the type-code (like giving the proper food to the pet) or make a behavior conditional based on a different type-code (treat a dog differently whether they are a good boi).&lt;/p&gt;

&lt;p&gt;Second, the possible value set of type-codes tend to change. For example, we may want to handle hamsters and fish as pets. Then we need to remember to update all the &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; statements we have. And most probably, we'll have many of them because of the previous point&lt;sup id="fnref4"&gt;4&lt;/sup&gt;. And it's hard to remember all the places we need to update, which leads to mysterious bugs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We understood why &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; is good and when to use it. We also saw why &lt;code&gt;switch&lt;/code&gt;es &lt;del&gt;get stitches&lt;/del&gt;&lt;sup id="fnref5"&gt;5&lt;/sup&gt; are hard to maintain.&lt;/p&gt;

&lt;p&gt;In the following parts, we'll see different scenarios where we can do better than &lt;code&gt;switch&lt;/code&gt;-&lt;code&gt;case&lt;/code&gt; from a maintainability perspective. Each of them has different optimal solutions. We'll see their characteristics and get rules of thumb about the solutions' usability.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Pun intended ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;They may introduce more &lt;code&gt;jump&lt;/code&gt;s we didn't need previously. Alternatively, subroutines (aka, functions) could fit in and need jumps anyway. Or we could leave them blank if we have more than enough memory. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;Not to mention their developers. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;We'll see this effect in the next part of the series. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;Sorry, I couldn't resist. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>programming</category>
      <category>refactoring</category>
      <category>switchcase</category>
    </item>
    <item>
      <title>Tech Content Creators' Responsibilities</title>
      <dc:creator>Attila Fejér</dc:creator>
      <pubDate>Wed, 15 Mar 2023 11:02:20 +0000</pubDate>
      <link>https://dev.to/fanatixan/tech-content-creators-responsibilities-23dp</link>
      <guid>https://dev.to/fanatixan/tech-content-creators-responsibilities-23dp</guid>
      <description>&lt;p&gt;As online learning flourishes, it’s easier than ever to learn new things. If we search for virtually any technology, we’ll get remarkable amounts of results. In some sense, it’s good, since we have the freedom to choose. But how should we make that choice?&lt;/p&gt;

&lt;h2&gt;
  
  
  Judging Content Quality
&lt;/h2&gt;

&lt;p&gt;There are multiple properties of a tech course - let it be text- or video-based. Usually, it's easy to instantly get an impression of content quality by looking for clues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grammar, accent&lt;/li&gt;
&lt;li&gt;Illustrations&lt;/li&gt;
&lt;li&gt;Text understandability&lt;/li&gt;
&lt;li&gt;Visual design&lt;/li&gt;
&lt;li&gt;Examples&lt;/li&gt;
&lt;li&gt;Clarity of the explanations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the list could go on.&lt;/p&gt;

&lt;p&gt;We have biases against content based on the above impression. And sometimes these biases are harmful:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We could quickly close a very good article because it's hard to read due to an unfortunate font or color choice&lt;/li&gt;
&lt;li&gt;We may get fooled by content, that checks all the above boxes but has other, harder-to-detect problems&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Point one is only harmful to the content's publisher: fewer people will use what they created.&lt;/p&gt;

&lt;p&gt;On the other hand, point two is bad for consumers. The reason is simple: if the creator puts in the effort to produce high-quality content from most perspectives, we tend to think it's indeed high-quality from every aspect. Unfortunately, in many cases, we're wrong - and the author doesn't necessarily do this willingly.&lt;/p&gt;

&lt;p&gt;But what are these hard-to-detect problems?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hidden Quality
&lt;/h2&gt;

&lt;p&gt;Let's consider a simple example: we're looking at a tutorial about the most recent JS framework: RockIT.js (patent pending)&lt;sup id="fnref1"&gt;1&lt;/sup&gt;. The examples are simple, to let the reader concentrate on core concepts without technology and domain getting in the way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;RockIT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another, featuring click events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
      &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nx"&gt;RockIT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;button @click&amp;gt;Click me!&amp;lt;/button&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here it's easy to see a problem: JS embedded in HTML and HTML embedded in JS. For quite some time we know that these are bad ideas.&lt;/p&gt;

&lt;p&gt;But beginners don't have the experience to recognize the problem. The approach looks simple enough, so they get the evergreen CPDD&lt;sup id="fnref2"&gt;2&lt;/sup&gt; from their toolbox and start writing &lt;del&gt;code&lt;/del&gt; garbage. Because the examples above aren't more than garbage in large-scale applications.&lt;/p&gt;

&lt;p&gt;Whose fault is it? In my opinion, it's the creator's responsibility to present best practices. And in the above examples, they failed miserably.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;p&gt;As technology evolves, best practices come and go. What people considered best practices a few years ago, might be antipatterns today. But that doesn't mean we shouldn't strive for using current best practices.&lt;/p&gt;

&lt;p&gt;What happens if we don't? Let's get back to the examples above. Our beginner reader uses the framework with satisfaction. They're sharing their experience with friends, even starting a blog&lt;sup id="fnref3"&gt;3&lt;/sup&gt;. The blog's readers start sharing, too. The bad habit is spreading. It's a downward spiral.&lt;/p&gt;

&lt;p&gt;But it isn't only spreading. As people keep using the practice, it's solidifying until it becomes a habit.&lt;/p&gt;

&lt;p&gt;Later, they see an example, where all the files are separated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- index.html --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// hello.js&lt;/span&gt;
&lt;span class="nx"&gt;RockIT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- hello.html --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello World!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most probably they'll think that this example is strange and overcomplicated. It has three files instead of one. They can't immediately oversee the implementation. (Funnily, as the application grows, the one-file solution will be less understandable. But they might not see that yet.) And most importantly: they're used to a different style. And it's much harder to change an existing habit than to form a new one.&lt;/p&gt;

&lt;p&gt;Most probably, the content creator didn't mean all this to happen. Maybe they weren't aware of the best practices. Or they didn't know the impact it might have on the community. But despite their intentions, the harm was already done and it's extremely hard to revert.&lt;/p&gt;

&lt;p&gt;Let's see a real-life example. The average developer codes for quite some time before they write their first unit test. They're used to &lt;del&gt;manual tests&lt;/del&gt; clicking every button until the application seems working. It's strange for them to write tests. And we didn't even talk about using TDD.&lt;/p&gt;

&lt;p&gt;On the other hand, what happens if we train someone from day one to use TDD? Developing with TDD will be their habit and it'll be strange to do things differently.&lt;/p&gt;

&lt;p&gt;And that's exactly my point. To successfully spread best practices, we must start early. Especially those with a higher abstraction level. Let that practice be technological, methodological, or architectural. Bad practices are similar to fires: we should prevent them instead of putting them out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As consumers, we should be critical. We shouldn't copy-paste blindly code examples. We should try to understand the concepts, and apply best practices whenever we can.&lt;/p&gt;

&lt;p&gt;As content creators, we must not cut corners. We should have a deep understanding of technology, the most recent industry standards, and architectural styles. We should build those into our materials. At the end of the day, we're not responsible for how others use the technology we're presenting. But at least, we did what we could.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;I hope it's obvious that I'm just fooling around with this non-existing framework ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;Copy-Paste Driven Development ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;It seems that these days, anyone can do that ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>learning</category>
      <category>softwareengineering</category>
      <category>opinion</category>
    </item>
  </channel>
</rss>
