<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ software design - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ software design - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Wed, 20 May 2026 22:47:10 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/software-design/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Learn Software Design Basics: Key Phases and Best Practices ]]>
                </title>
                <description>
                    <![CDATA[ Coding has become one of the most common tasks in modern society. With computers now central to almost every field, more people are designing algorithms and writing code to solve various problems. From healthcare to finance, robust software systems p... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-software-design-basics/</link>
                <guid isPermaLink="false">67cb6446f54b40e1e9144db0</guid>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software architecture ]]>
                    </category>
                
                    <category>
                        <![CDATA[ System Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TDD (Test-driven development) ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Coding Best Practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Programming Blogs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Soham Banerjee ]]>
                </dc:creator>
                <pubDate>Fri, 07 Mar 2025 21:25:26 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1741188275855/9858518f-38c0-4e3b-8be1-7c56b68c77a7.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Coding has become one of the most common tasks in modern society. With computers now central to almost every field, more people are designing algorithms and writing code to solve various problems.</p>
<p>From healthcare to finance, robust software systems power our daily operations, making good software design essential to avoid inefficiencies and bottlenecks. This involves not just writing code but also designing systems that are easy to scale, maintain, and debug, while allowing others to contribute effectively.</p>
<p>Inefficient or ineffective software design can lead to significant issues, like scope creep, miscommunication within teams, project delays, resource misallocation, and complex systems that are difficult to maintain or understand. Without a strong design, teams often accumulate technical debt, which hinders long-term progress and increases maintenance costs.</p>
<p>This article will introduce you to key software design elements that will help you and your team address these challenges and guide you in building efficient, scalable systems. By understanding and applying these elements correctly, you can set up a project for both short-term and long-term success.</p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>I’ll explain these concepts through examples, but a basic understanding of programming in any language is required for this article (knowledge of Python will be especially beneficial).</p>
<h2 id="heading-scope"><strong>Scope</strong></h2>
<p>The article will introduce key software design elements and explain them using an example. While I won’t provide a full software design for the example problem, I will include enough details to effectively illustrate each design element.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-overview-of-key-software-design-elements">Overview of Key Software Design Elements</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-a-walkthrough-of-the-software-design-process">A Walkthrough of the Software Design Process</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-problem-statement">Problem Statement</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-use-cases">Use Cases</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-requirements">Requirements</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-high-level-system-architecture">High Level System Architecture</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-detailed-software-design-and-component-breakdown">Detailed Software Design and Component Breakdown</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion-the-value-of-thoughtful-software-design">Conclusion: The Value of Thoughtful Software Design</a></p>
</li>
</ul>
<h2 id="heading-overview-of-key-software-design-elements"><strong>Overview of Key Software Design Elements</strong></h2>
<p>To fully understand the benefits of the software design process, you’ll need to understand some key elements and their scope.</p>
<p>Once you have a good grasp of these, the next step is to define them for the specific problem at hand. Accurately defining these elements reduces risks and simplifies the implementation phase.</p>
<p>Doing this groundwork before implementation helps prevent late discoveries, minimizes the need for rewriting, and makes sure that the design can handle constraints and corner cases.</p>
<p>Now let’s briefly go over the key elements of the software design process:</p>
<ol>
<li><p><strong>Creating a problem statement</strong>: This step involves creating a clear and concise description of the problem that needs to be solved, along with its scope. The scope is essential because it focuses on the exact problem to be addressed and includes assumptions that must be considered during design.</p>
</li>
<li><p><strong>Identifying use cases</strong>: This step outlines all possible user interactions with the software to achieve the desired outcome. It is a critical input to the architecture, as it helps create a design that addresses both general and edge-case use cases.</p>
</li>
<li><p><strong>Stating requirements</strong>: This step defines the expectations of the software, such as its limitations, behaviors, and capabilities for different use cases.</p>
</li>
<li><p><strong>Designing the architecture</strong>: This step provides a high-level structure of the software design, focusing on how to meet the requirements. The architecture typically includes components, how they interact, and how data flows through the system.</p>
</li>
<li><p><strong>Drafting a detailed design</strong>: This step refines the high-level architecture into detailed, component-specific designs, ready for implementation.</p>
</li>
</ol>
<p>In addition to these core elements, there are two important factors you need to consider throughout the design phase.</p>
<p>First, you’ll need to identify and state any assumptions you have. Assumptions can be present at any stage in the design process. Making correct assumptions increases the likelihood of success, improves focus, and reduces complexity in the design.</p>
<p>Second, you’ll need to create good documentation. Documentation is one of the most important elements in the software design process. It’s essential to document each stage as you go along. Documentation serves as the only formal record of the software design and is invaluable for presentations to management, for onboarding new team members, and for anyone returning to the project after a break. It saves valuable time and ensures continuity, as we often overestimate our own memory.</p>
<p>The figure below provides a visual summary of the key software design elements discussed in this section.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738540359869/2ee49614-84b1-439a-ae7e-af637c0f34dd.png?auto=compress,format&amp;format=webp" alt="Figure 1: Key software design elements" width="2244" height="402" loading="lazy"></p>
<p>Next, we’ll apply these key software design elements to a practical example, demonstrating how each element contributes to building a robust and scalable system.</p>
<h2 id="heading-a-walkthrough-of-the-software-design-process"><strong>A Walkthrough of the Software Design Process</strong></h2>
<p>In any well-structured software project, clearly defining the problem is the first crucial step before diving into design and implementation. A well-defined problem ensures that the software meets user needs, remains maintainable, and scales effectively over time.</p>
<p>For this walkthrough, we will focus on designing a financial expense categorization system that processes and analyzes transaction data. This system is a part of a larger financial management solution and needs to be easy to debug, maintain, and scale.</p>
<h3 id="heading-problem-statement"><strong>Problem Statement</strong></h3>
<p>The problem statement provides a high-level goal for the software that we’ll design.</p>
<p>For this example, here’s our statement: Design a software solution that categorizes monthly expenses and generates a report from a list of transactions.</p>
<h4 id="heading-define-the-scope"><strong>Define the scope</strong></h4>
<p>Defining the scope clarifies the smaller tasks that must be accomplished to meet the high-level goal. It outlines the focus of the software design and includes some assumptions.</p>
<p>Includes:</p>
<ol>
<li><p>Implementing a parser to process a list of transactions provided as input.</p>
</li>
<li><p>Filtering transactions for a given month.</p>
</li>
<li><p>Analyzing, categorizing, and generating a report for each expense category.</p>
</li>
</ol>
<p>Excludes:</p>
<p>Performance and memory optimization (excluded due to the limited scope of this article). While performance and memory optimizations are not the primary focus here, it’s important to keep future scalability in mind. Small design choices made now, such as selecting data structures, can help avoid significant refactoring later when the system grows.</p>
<p>Assumptions:</p>
<ol>
<li><p>The list of transactions will be provided as a CSV file in the following format:<br> Columns: "Date, Description, Amount, Type, Category Label".</p>
</li>
<li><p>Expense categories will be provided as input through a JSON file.</p>
</li>
<li><p>The software will run in a shell environment, and inputs will be taken as command-line arguments.</p>
</li>
</ol>
<p>Now that the scope is clear, let’s examine how users will interact with the system through various use cases.</p>
<h3 id="heading-use-cases"><strong>Use Cases</strong></h3>
<p>Use cases define how users will interact with the system to accomplish specific goals. Identifying accurate and valid use cases is critical to creating comprehensive requirements. Failing to capture enough use cases can lead to a design that is incomplete and lacks robustness. This may result in the need for redesigns, which increases time and resource consumption.</p>
<p>On the other hand, identifying too many use cases without considering their feasibility can lead to overly complex designs that are difficult to maintain and implement in the short term.</p>
<p>For our specific problem, the user will need to provide the following inputs while running the software in a shell:</p>
<ol>
<li><p>A CSV file containing a list of transactions.</p>
</li>
<li><p>A month number.</p>
</li>
<li><p>A JSON file containing expense categories.</p>
</li>
</ol>
<p>We need to consider all possible ways the user can interact with the script to achieve the desired outcome. For each of the three inputs, there are two possibilities: valid input or invalid input. This gives us 8 potential use cases (2 possibilities per input: valid and invalid). It's important to define what constitutes valid and invalid inputs for this problem:</p>
<ul>
<li><p>CSV File: Valid if it is in the format described in Assumption 1 (columns: "Date, Description, Amount, Type, Category Label").</p>
</li>
<li><p>Month Number: Valid if the value is between 1 and 12.</p>
</li>
<li><p>JSON File: Valid if it contains expense categories in the correct JSON format.</p>
</li>
</ul>
<p>An input is invalid if it doesn't meet these definitions or if the input is absent.</p>
<p>It’s also crucial to consider the correlation between inputs when evaluating the feasibility of certain use cases, as they may interact with each other in unforeseen ways. Based on these use cases, we can now define the specific requirements that the system must meet.</p>
<h3 id="heading-requirements"><strong>Requirements</strong></h3>
<p>Now, let’s define the expected behaviors, limitations, and capabilities for each use case. Requirements serve as the foundation for architecture, specifications, and implementation. Based on our problem statement, the software will need to accomplish the following tasks:</p>
<ol>
<li><p>The script shall take three inputs: a CSV file of transactions, a month number, and a JSON file of expense categories.</p>
</li>
<li><p>The script shall verify all inputs.</p>
</li>
<li><p>The script shall throw an error and exit if the CSV file cannot be opened or if it does not match the format in Assumption 1.</p>
</li>
<li><p>The script shall throw an error and exit if the JSON file cannot be opened.</p>
</li>
<li><p>The script shall throw an error if the month number is not between 1 and 12.</p>
</li>
<li><p>The script shall parse each transaction and load it into a data structure.</p>
</li>
<li><p>The script shall filter transactions by the specified month.</p>
</li>
<li><p>The script shall load the expense categories from the JSON file into a data structure.</p>
</li>
<li><p>The script shall categorize transactions based on the category label provided in the CSV file.</p>
</li>
<li><p>The script shall throw an exception if a category label in the CSV file is not present in the expense categories.</p>
</li>
<li><p>The script shall use a categorizing function to assign transactions to categories from the JSON file.</p>
</li>
<li><p>A class shall encapsulate categorized transactions, providing APIs to modify or access them.</p>
</li>
<li><p>The script shall support statistics calculation and report generation for categorized transactions.</p>
</li>
</ol>
<p>With the requirements in place, we can now design a high-level architecture to meet those needs.</p>
<h3 id="heading-high-level-system-architecture"><strong>High Level System Architecture</strong></h3>
<p>In this stage, we will design the system at a high level, much like creating a master plan. Architecture involves organizing the software's functions into distinct components, illustrating how they interact, and mapping the flow of control and data through the system. While designing the architecture in this tutorial, we’ll incorporate good design principles.</p>
<p>For this example, the high-level requirements include:</p>
<ol>
<li><p>Loading inputs and verifying them.</p>
</li>
<li><p>Applying time-based filtering.</p>
</li>
<li><p>Categorizing transactions based on category labels and descriptions.</p>
</li>
<li><p>Managing categorized transactions in a finance registry.</p>
</li>
<li><p>Generating reports from the categorized data.</p>
</li>
</ol>
<p>One important component of software architecture is telemetry. Telemetry gathers data on the software's behavior, which is invaluable for debugging and performance assessment in real-world environments.</p>
<p>For smaller systems, simpler logging mechanisms may be sufficient to track basic errors and monitor performance. The decision to implement telemetry should depend on the complexity of the system and operational requirements.</p>
<p>Since telemetry provides such a helpful feedback loop for improving the design in future iterations, we’ll add it to the list of components here.</p>
<p>We’ll build our system architecture around a Test-Driven Development (TDD) approach. We’ll design each component with testing in mind to ensure it meets our requirements.</p>
<p>Just keep in mind that while TDD is a strong practice for ensuring code quality, it may not be the best fit for all projects. In scenarios where you need rapid prototyping or exploratory development, testing might be prioritized after initial iterations. Balancing between TDD and other methodologies depends on the project context and team preferences.</p>
<p>Our architecture will follow a modular structure, meaning the system will be divided into self-contained components. Each component will be responsible for specific functionality, making the system easier to test, maintain, and scale.</p>
<p>To achieve this, the architecture will emphasize loose coupling between components. Each component will interact with others through well-defined interfaces or APIs, ensuring minimal dependencies. We’ll abstract and encapsulate internal implementation details, exposing only the necessary information for interaction. Also, each component will handle its own errors and exceptions to ensure robustness and fault isolation.</p>
<p>But it is also important to consider a centralized error-handling strategy in some cases. Centralizing error handling can reduce redundancy, improve consistency, and make maintenance easier. The choice between local and centralized error handling should depend on the system's complexity and how components interact. This will contribute to the overall scalability and maintainability of the system.</p>
<p>Below is a summary of each component's functionality in this architecture:</p>
<ul>
<li><p>Load and verify input: This component will take the CSV file, JSON file, and month number as input, verify their validity, and load the data into structures.</p>
</li>
<li><p>Time-based filter: This component will filter transactions based on the input month and store the filtered transactions in a data structure.</p>
</li>
<li><p>Label-based categorization: This component will categorize transactions based on the category label in the CSV file.</p>
</li>
<li><p>Description-based categorization: This component will categorize transactions using an algorithm based on the transaction description.</p>
</li>
<li><p>Finance registry: This component will store all categorized transactions for further processing. It isolates the post-processing of categorized transactions from the categorization process and provides methods for updating or retrieving datasets.</p>
</li>
<li><p>Report generation: This component will generate expense reports from the categorized transaction data.</p>
</li>
<li><p>Telemetry: This component will monitor the performance of other components. It will track the flow of transactions, ensuring that all transactions are categorized either by label or description. Additional parameters can be added as needed to monitor specific functionalities.</p>
</li>
</ul>
<p>The diagram below demonstrates the flow of data through these components:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738540585066/6236b867-8c57-4a04-b5ea-4f9dd7f1fef3.png?auto=compress,format&amp;format=webp" alt="Figure 2: Flow of data through various components defined in the architecture" width="2360" height="794" loading="lazy"></p>
<h3 id="heading-detailed-software-design-and-component-breakdown"><strong>Detailed Software Design and Component Breakdown</strong></h3>
<p>While we won't cover the full system design, this section will highlight key components and their specifications. For this example, I will assume the role of both the designer and implementer of the software.</p>
<p>Software design and specifications depend on several factors, including the designer's knowledge, skill set, available time, and resources. We’ll define some of the design details for the system, starting with the choice of the implementation language.</p>
<p>Choosing the right language is based on several important factors:</p>
<ol>
<li><p>The language must meet the software requirements.</p>
</li>
<li><p>It should be stable, and have strong support from an active developer community.</p>
</li>
<li><p>Additional considerations include performance (speed and memory), scalability (ability to grow with future requirements), and platform support (ability to run on all major operating systems).</p>
</li>
</ol>
<p>If you’re the one implementing this design, you’ll need to be familiar with and confident using that programming language. For this project, I chose Python because it meets all the project requirements, has a robust developer community for support, it’s stable, and I’m confident in using it to complete the implementation successfully.</p>
<h4 id="heading-data-structures"><strong>Data Structures</strong></h4>
<p>Now, let’s look at the fundamental data structures that we’ll use in the design. We need to load the contents of the CSV file into a data structure for further analysis and processing. In Python, the Pandas DataFrame from the Pandas library is ideal for analyzing and processing tables, so we will use it to store the transactions.</p>
<p>For generating report, we will encapsulate categorized transactions along with relevant statistics, such as the total number of transactions, mean amount, and maximum amount, within a dedicated dataset class. This approach ensures a clear separation of concerns, where the dataset class manages data processing, while the reporting component focuses on presentation.</p>
<p>By structuring the system this way, we enhance reusability, maintainability, and scalability, making it easier to extend and modify in the future.</p>
<p>This dataset class will include:</p>
<ul>
<li><p>Member variables: category name, category description, a Pandas DataFrame for transactions, total number of transactions, mean amount, and max amount of transactions.</p>
</li>
<li><p>Member functions: set/get DataFrame, save dataset to CSV (useful for debugging).</p>
</li>
</ul>
<p>Here’s an example of a Dataset class in Python for structured data management and processing:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd  <span class="hljs-comment"># Import Pandas for data handling</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dataset</span>:</span>
    <span class="hljs-string">"""
    A class representing a structured dataset with a name, predefined keys, 
    and a Pandas DataFrame.
    """</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, name, keys</span>):</span>
        <span class="hljs-string">"""
        Initializes the Dataset object.

        Parameters:
        name (str): The name of the dataset.
        keys (list): A list of expected column names for the dataset.

        Attributes:
        self.name (str): Stores the dataset name as a string.
        self.keys (list): Stores the expected column names for data organization.
        self.mean_amt (float): Tracks the mean (average) transaction amount.
        self.max_amt (float): Tracks the maximum transaction amount.
        self.count (int): Stores the total number of transactions in the dataset.
        self.dataframe (pd.DataFrame): A Pandas DataFrame initialized with the specified column names.
        """</span>
        self.name = str(name)  <span class="hljs-comment"># Convert and store dataset name as a string</span>
        self.keys = keys  <span class="hljs-comment"># Store expected column names for consistency</span>
        self.mean_amt = <span class="hljs-number">0</span>  <span class="hljs-comment"># Initialize mean transaction amount to zero</span>
        self.max_amt = <span class="hljs-number">0</span>  <span class="hljs-comment"># Initialize max transaction amount to zero</span>
        self.count = <span class="hljs-number">0</span>  <span class="hljs-comment"># Initialize transaction count to zero</span>
        self.dataframe = pd.DataFrame(columns=keys)  <span class="hljs-comment"># Initialize empty DataFrame with predefined columns</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">getName</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""
        Returns the name of the dataset.

        Returns:
        str: The name of the dataset.
        """</span>
        <span class="hljs-keyword">return</span> self.name  <span class="hljs-comment"># Fixed: Removed incorrect parentheses</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">getValue</span>(<span class="hljs-params">self, key</span>):</span>
        <span class="hljs-string">"""
        Retrieves a specific column from the DataFrame.

        Parameters:
        key (str): The column name to retrieve.

        Returns:
        pandas.Series or None: The column data if the key exists, otherwise None.
        """</span>
        <span class="hljs-keyword">if</span> key <span class="hljs-keyword">in</span> self.dataframe.columns:
            <span class="hljs-keyword">return</span> self.dataframe[key]
        <span class="hljs-keyword">else</span>:
            print(<span class="hljs-string">f"Warning: Key '<span class="hljs-subst">{key}</span>' not found in DataFrame."</span>)
            <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>  <span class="hljs-comment"># Prevents KeyError</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">getKeys</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""
        Returns the list of expected keys (column names) of the dataset.

        Returns:
        list: The keys defining the dataset.
        """</span>
        <span class="hljs-keyword">return</span> self.keys

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">setDataFrame</span>(<span class="hljs-params">self, dataframe</span>):</span>
        <span class="hljs-string">"""
        Sets the dataset's DataFrame while ensuring it contains only expected keys.

        Parameters:
        dataframe (pandas.DataFrame): The DataFrame to assign to the dataset.
        """</span>
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> isinstance(dataframe, pd.DataFrame):
            <span class="hljs-keyword">raise</span> TypeError(<span class="hljs-string">"Provided data is not a valid pandas DataFrame."</span>)

        <span class="hljs-comment"># Ensure only the expected columns are included</span>
        self.dataframe = dataframe[self.keys].copy() <span class="hljs-keyword">if</span> set(self.keys).issubset(dataframe.columns) <span class="hljs-keyword">else</span> dataframe.copy()

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">getDataFrame</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""
        Returns the DataFrame associated with the dataset.

        Returns:
        pandas.DataFrame: The dataset's DataFrame.
        """</span>
        <span class="hljs-keyword">return</span> self.dataframe

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">save_to_csv</span>(<span class="hljs-params">self, file_name</span>):</span>
        <span class="hljs-string">"""
        Saves the dataset's DataFrame to a CSV file.

        Parameters:
        file_name (str): The name of the CSV file to save.
        """</span>
        self.dataframe.to_csv(file_name, mode=<span class="hljs-string">'w'</span>, index=<span class="hljs-literal">False</span>)  <span class="hljs-comment"># Save the DataFrame to CSV</span>
</code></pre>
<p>In the previous section, we outlined the high-level system architecture, detailing the core components and their interactions. Now, let’s dive into the detailed design of some of the individual components, specifying how we’ll implement each one and how it’ll function within the system. We’ll also break down the components to explain how they work together to process the input and generate the report.</p>
<p>Below, you can see the flow diagram for the software, illustrating the interaction between the core components and the flow of data through the system.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739209441033/60142953-c1f4-4146-b64e-c042039e1ef6.png?auto=compress,format&amp;format=webp" alt="Figure 3 Software Flow Diagram" width="1940" height="1128" loading="lazy"></p>
<h4 id="heading-category-label-based-filtering-component"><strong>Category Label-Based Filtering Component</strong></h4>
<p>The Category Label-Based Filtering Component classifies transactions by matching their "Category Label" with predefined expense categories from a JSON file. Transactions with valid category labels are stored in the finance registry, while unmatched ones remain for further processing.</p>
<ul>
<li><p>Input: DataFrame of time-filtered transactions, expense categories from JSON.</p>
</li>
<li><p>Libraries used: Pandas DataFrame.</p>
</li>
<li><p>Software design: Filters transactions based on the "Category Label" column and assigns them to corresponding categories. Transactions that cannot be categorized remain for further processing.</p>
</li>
<li><p>Output: DataFrame of remaining transactions with empty values in the "Category Label" field.</p>
</li>
<li><p>Component tests: Validate handling of valid, invalid, and missing category labels.</p>
</li>
</ul>
<h4 id="heading-finance-registry-component"><strong>Finance Registry Component</strong></h4>
<p>The Finance Registry Component manages categorized transactions by storing them as datasets for each expense category. It maintains a structured collection of DataFrames, each containing transactions and summary statistics such as total count, max amount, and mean amount.</p>
<ul>
<li><p>Input: Expense categories from JSON.</p>
</li>
<li><p>Libraries used: Pandas DataFrame.</p>
</li>
<li><p>Software design: Implements a class that organizes datasets for all expense categories, providing methods to set and retrieve DataFrames.</p>
</li>
<li><p>Component tests: Validate dataset creation, ensuring correct storage and retrieval of categorized transactions.</p>
</li>
</ul>
<p>Here’s a simple and efficient Finance Registry implementation in Python for managing categorized financial datasets:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> Dataset <span class="hljs-keyword">import</span> Dataset
<span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd  <span class="hljs-comment"># Ensure Pandas is imported if used elsewhere</span>

<span class="hljs-comment"># Define column structure for datasets</span>
KEYS = (<span class="hljs-string">"Date"</span>, <span class="hljs-string">"Description"</span>, <span class="hljs-string">"Amount"</span>, <span class="hljs-string">"Transaction Type"</span>, <span class="hljs-string">"Category"</span>, <span class="hljs-string">"Account Name"</span>, <span class="hljs-string">"Labels"</span>, <span class="hljs-string">"Notes"</span>)

<span class="hljs-comment"># Define dataset names for different financial categories</span>
EXAMPLE_DATASET_NAMES = (<span class="hljs-string">"Investment"</span>, <span class="hljs-string">"Expense"</span>, <span class="hljs-string">"Savings"</span>)

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FinanceRegistry</span>:</span>
    <span class="hljs-string">"""
    A class to manage categorized financial datasets, including investment, expense, and savings datasets.
    This registry allows structured access to transaction data and maintains aggregated financial metrics.
    """</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""
        Initializes the FinanceRegistry object.

        Attributes:
        self.example_dataset (dict): A dictionary storing Dataset objects for financial datasets.
        """</span>
        self.example_dataset = {name: Dataset(name, KEYS) <span class="hljs-keyword">for</span> name <span class="hljs-keyword">in</span> EXAMPLE_DATASET_NAMES}  <span class="hljs-comment"># Create datasets for categories</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">setExampleDatasetToRegistry</span>(<span class="hljs-params">self, name, dataframe</span>):</span>
        <span class="hljs-string">"""
        Merges a new dataframe into the existing dataset for a given financial category.

        Parameters:
        name (str): The category name (e.g., "Investment", "Expense", or "Savings").
        dataframe (pd.DataFrame): The new data to be added.

        If the dataset already contains data, it concatenates the new dataframe to the existing one.

        Raises:
        ValueError: If the provided name is not a valid dataset category.
        """</span>
        <span class="hljs-keyword">if</span> name <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> self.example_dataset:
            <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">f"Invalid dataset name: '<span class="hljs-subst">{name}</span>'. Expected one of <span class="hljs-subst">{EXAMPLE_DATASET_NAMES}</span>"</span>)

        df = self.example_dataset[name].getDataFrame()  <span class="hljs-comment"># Get existing dataset</span>

        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> dataframe.empty:  <span class="hljs-comment"># Ensure the new dataframe is not empty</span>
            dataframe = pd.concat([df, dataframe], axis=<span class="hljs-number">0</span>, ignore_index=<span class="hljs-literal">True</span>)  <span class="hljs-comment"># Append new data</span>

        self.example_dataset[name].setDataFrame(dataframe)  <span class="hljs-comment"># Update dataset in registry</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">getExampleDatasetFromRegistry</span>(<span class="hljs-params">self, name</span>):</span>
        <span class="hljs-string">"""
        Retrieves the dataset for a given financial category.

        Parameters:
        name (str): The category name (e.g., "Investment", "Expense", or "Savings").

        Returns:
        Dataset: The dataset corresponding to the given name.

        Raises:
        ValueError: If the provided name is not a valid dataset category.
        """</span>
        <span class="hljs-keyword">if</span> name <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> self.example_dataset:
            <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">f"Invalid dataset name: '<span class="hljs-subst">{name}</span>'. Expected one of <span class="hljs-subst">{EXAMPLE_DATASET_NAMES}</span>"</span>)

        <span class="hljs-keyword">return</span> self.example_dataset[name]
</code></pre>
<p>The diagram below illustrates how the Finance Registry organizes these datasets for further processing in the Report Generation component.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739209411075/7a772e4f-9687-4c96-8995-10a70e27a36d.png?auto=compress,format&amp;format=webp" alt="Figure 4 Finance Registry datasets for expense category" width="1850" height="864" loading="lazy"></p>
<h4 id="heading-report-generation-component"><strong>Report Generation Component</strong></h4>
<p>The Report Generation Component processes categorized transaction datasets from the finance registry and generates summary statistics. It calculates key financial metrics such as maximum amount, mean amount, and total transaction count. It also provides functionality to display categorized transactions in a structured format within the shell.</p>
<ul>
<li><p>Input: Datasets of categorized transactions from the finance registry.</p>
</li>
<li><p>Libraries used: Numpy for calculations, Tabulate for formatted shell output (if needed).</p>
</li>
<li><p>Software design: Implements a class with methods to compute financial statistics and display transaction summaries per expense category.</p>
</li>
<li><p>Component tests: Validate correct calculation of mean, max, and total transactions, and ensure accurate display of categorized datasets in the shell.</p>
</li>
</ul>
<p>Here’s a function to compute transaction statistics, including mean, max, and count, from a dataset in the report generation component:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> Dataset <span class="hljs-keyword">import</span> Dataset
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">calculateStats</span>(<span class="hljs-params">dataset</span>):</span>
    <span class="hljs-string">"""
    Computes statistical metrics for a given dataset.

    Parameters:
    dataset: The dataset containing transaction data.

    Updates:
    - dataset.mean: Mean transaction amount.
    - dataset.max: Maximum transaction amount.
    - dataset.count: Number of transactions.
    """</span>

    <span class="hljs-comment"># Return early if the dataset has no transactions</span>
    <span class="hljs-keyword">if</span> dataset.dataframe.empty:
        <span class="hljs-keyword">return</span>

    <span class="hljs-comment"># Extract transaction amounts as a list</span>
    tx_amount_list = dataset.dataframe[<span class="hljs-string">'Amount'</span>].astype(float).round(<span class="hljs-number">2</span>).tolist()

    <span class="hljs-comment"># Adjust transaction amounts based on "Transaction Type"</span>
    <span class="hljs-keyword">for</span> i, tx_type <span class="hljs-keyword">in</span> enumerate(dataset.dataframe[<span class="hljs-string">'Transaction Type'</span>]):
        <span class="hljs-keyword">if</span> tx_type == <span class="hljs-string">'debit'</span>:
            tx_amount_list[i] *= <span class="hljs-number">-1</span>  <span class="hljs-comment"># Convert debit transactions to negative values</span>

    <span class="hljs-comment"># Compute statistical metrics</span>
    dataset.mean = round(np.mean(tx_amount_list), <span class="hljs-number">2</span>)
    dataset.max = max(tx_amount_list)
    dataset.count = len(tx_amount_list)
</code></pre>
<p>This concludes the design section, where we explored key software design elements with a practical example. The next step, implementation, is beyond the scope of this article. But it's crucial to recognize that new challenges often emerge during development, requiring updates to requirements, architecture, and specifications.</p>
<p>The purpose of this article is not to provide a full implementation, but to teach you some basic software design principles through an example. The focus is on understanding how to structure software, define clear requirements, and create scalable architectures, all before writing code.</p>
<p>By following a structured design process, you can shift complex problem-solving from implementation to the architecture phase, where you can explore solutions more effectively using flowcharts, block diagrams, and documentation. This makes the development process more organized, efficient, and maintainable, a crucial skill for real-world software engineering.</p>
<p>If you're learning to code, remember that good design is just as important as writing code itself!</p>
<h2 id="heading-conclusion-the-value-of-thoughtful-software-design"><strong>Conclusion: The Value of Thoughtful Software Design</strong></h2>
<p>With well-defined problem statements, scope, requirements, specifications, and design, even complex problems can be solved and maintained in a sustainable way.</p>
<p>The steps we went through in this article can help you break down any problem, regardless of its complexity, into smaller, actionable tasks that you and your team can efficiently tackle.</p>
<p>Without proper planning, projects are often plagued by scope creep, wasted time and resources, miscommunication between teams, overly complicated designs, technical debt, and frequent redesigns.<br>Good design is often simple design, but achieving simplicity is difficult without thorough planning.</p>
<p>Approaching each problem with the mindset of defining a Problem Statement, Scope, Use Cases, Requirements, Architecture, and Specifications helps cultivate a strong software design mindset. This mindset is crucial for developing software that is scalable, maintainable, and high quality.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Wireframing? How to Go from Paper Sketches to High Fidelity Wireframes ]]>
                </title>
                <description>
                    <![CDATA[ What are Wireframes? Wireframes are visual representations of the structure, layout, and functionality of a website, application, or other digital product.  You typically create them during the early stages of the design process, and they provide a s... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-wireframing/</link>
                <guid isPermaLink="false">66d03a3f64be048ac359a361</guid>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #wireframe ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Faith Olohijere ]]>
                </dc:creator>
                <pubDate>Tue, 09 May 2023 22:06:49 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/unsplash_Pa0I38PfNPs.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="heading-what-are-wireframes">What are Wireframes?</h2>
<p>Wireframes are visual representations of the structure, layout, and functionality of a website, application, or other digital product. </p>
<p>You typically create them during the early stages of the design process, and they provide a simplified and focused view of the user interface and user experience.</p>
<p>You can create a wireframe using a variety of tools, including paper and pencil, whiteboards, or specialized digital software. They usually consist of basic shapes, lines, and text, and aim to communicate the hierarchy of information, the placement of interactive elements, and the flow of user interactions.</p>
<p>Wireframes serve as a blueprint for the design process. They allow designers and stakeholders to quickly iterate and refine ideas before investing time and resources into creating a fully functional prototype or final product. They are an essential tool for creating effective and user-friendly digital experiences.</p>
<h2 id="heading-why-is-wireframing-important">Why is Wireframing Important?</h2>
<p>Wireframing is an important process in web and app design because it helps designers to plan and communicate the layout and functionality of a website or application before it is built. Here are some reasons why wireframing is important:</p>
<ol>
<li>Wireframing helps stake holders visualize the structure of the design: Wireframing allows designers to create a visual representation of the website or application's structure. This includes the layout of pages, navigation, and the placement of various elements.</li>
<li>It helps designers focus on functionality: With wireframing, designers can focus on the functionality of the website or application without getting distracted by colors, typography, and other design elements.</li>
<li>It saves time and money: Wireframing can save time and money in the long run by identifying potential problems and making necessary changes early on in the design process, rather than during the development phase.</li>
<li>It's an easy way to gather feedback: Wireframes are a great way to gather feedback from stakeholders and users, as they provide a clear and simple representation of the design without distracting visual elements.</li>
<li>Plan for responsive design: Wireframing is essential when designing for different screen sizes and devices. It allows designers to plan for responsive design and ensure that the website or application works well on all devices.</li>
</ol>
<h2 id="heading-types-of-wireframes">Types of Wireframes</h2>
<p>Everyone has a specific way of doing wireframes. Some designers go from paper sketches to high fidelity wireframes or from low-fidelity wireframes to high-fidelity wireframes. </p>
<p>It all depends on the particular project the designer is working on, what they intend to achieve, and the timeframe they have.</p>
<h3 id="heading-paper-sketches">Paper Sketches</h3>
<p>I begin my wireframing process by doing paper sketches first, because it allows me put out my ideas really fast without having to bother about neatness and quality. It also saves time when designing – you just think of quick solutions and put them on paper.</p>
<h4 id="heading-some-techniques-for-paper-sketching">Some Techniques for Paper Sketching</h4>
<ul>
<li><strong>Crazy Eights</strong></li>
</ul>
<p>In the design world, "Crazy Eights" is a quick sketching exercise that helps designers to quickly generate a variety of design ideas and explore different solutions to a problem, in a short amount of time. </p>
<p>Here's how to do Crazy Eights in design:</p>
<ol>
<li>Start with a blank sheet of paper and fold it in half, then in half again, and one more time so that you end up with 8 rectangles on the page.</li>
<li>Set a timer for 8 minutes.</li>
<li>Within the first rectangle, sketch out an idea for the design problem you're working on. It doesn't need to be perfect, just get the basic idea down on paper.</li>
<li>When the timer goes off, move on to the next rectangle and sketch a new idea. Keep going until you've filled all 8 rectangles.</li>
<li>Once you've completed all 8 sketches, take a few minutes to review your ideas and identify the strongest ones.</li>
<li>Use the strongest ideas as a starting point for your design, and continue refining and iterating until you have a final product.</li>
</ol>
<p>You'll see an example of this in a bit when I walk you through my wireframing process.</p>
<ul>
<li><strong>20 Second Sketches</strong></li>
</ul>
<p>Set a timer for 20 seconds and sketch a simple object or scene. Repeat this exercise multiple times, trying to capture as much detail as possible in each sketch.</p>
<ul>
<li><strong>Collaborative Sketching</strong></li>
</ul>
<p>Pair up with another person and take turns adding to a sketch. Each person has a set amount of time to add their own unique element to the drawing. This exercise encourages collaboration and improvisation.</p>
<h3 id="heading-low-fidelity-wireframing">Low-Fidelity Wireframing</h3>
<p>Low-fidelity wireframing is a technique of creating a rough visual representation of a design using simple shapes, lines, and text. Low-fidelity wireframes are the most basic of wireframes. This type of wireframing is typically done with pen and paper, or with a digital tool that allows for quick, low-detail sketches. </p>
<p>Mostly, they focus on the core content and structure of the interface, and are simple and straightforward. Low-fidelity wireframes are a useful tool for designers to quickly explore and iterate on different layout and content options, without getting bogged down in details that can distract from the overall design direction. </p>
<h4 id="heading-advantages-of-low-fidelity-wireframing">Advantages of Low Fidelity Wireframing</h4>
<ul>
<li>Speed: Low-fidelity wireframes can be created quickly and easily, allowing designers to explore multiple ideas in a short amount of time.</li>
<li>Flexibility: Low-fidelity wireframes are easy to modify and change as the design evolves, allowing designers to iterate quickly.</li>
<li>Focus: By focusing on the structure and layout of a design, low-fidelity wireframing helps designers avoid getting distracted by details that may not be relevant.</li>
<li>Collaboration: Low-fidelity wireframes can be easily shared and discussed with other team members, allowing for greater collaboration and feedback.</li>
</ul>
<h4 id="heading-disadvantages-of-low-fidelity-wireframing">Disadvantages of Low Fidelity Wireframing</h4>
<ul>
<li>Lack of Detail: Low-fidelity wireframes may not provide enough detail to fully convey the intended design, which can lead to misunderstandings and miscommunications.</li>
<li>Limited Interactivity: Low-fidelity wireframes are static and do not allow for interaction, which can make it difficult to test usability and user flow.</li>
<li>Limited Realism: Unlike high fidelity wireframes, low-fidelity wireframes may not accurately represent the final product, which can make it difficult to communicate the design to stakeholders who may not be familiar with wireframes.</li>
</ul>
<h4 id="heading-why-you-might-want-to-use-low-fidelity-wireframes">Why You Might Want to Use Low-Fidelity Wireframes</h4>
<ul>
<li>For early-stage conceptualization: Low-fidelity wireframes are great for early-stage conceptualization. Because they allow you to quickly iterate and experiment with different layout options without getting caught up in the visual details, low-fidelity wireframes are extremely useful during the initial stages of your design. </li>
<li>For Time and Resource Efficiency: In situations where time is of great essence, low-fidelity wireframes helps to make changes more rapidly, saving time when needed. Also, it requires fewer resources, which is ideal for situations where resources are scarce.</li>
<li>For User Testing and Feedback: Low-fidelity wireframes provide a clear representation of the overall structure of your design, allowing for easier feedback from stakeholders and team members. Low-fidelity wireframes are also important during user testing sessions, as it helps you collect valuable insights on the fundamental structure and functionality of a design, before investing significant effort in visual design. </li>
</ul>
<h3 id="heading-mid-fidelity-wireframing">Mid-Fidelity Wireframing</h3>
<p>Mid-fidelity wireframing refers to wireframes that are created with a moderate level of detail and design elements. These wireframes typically focus on the overall structure of a product and may include basic typography and design elements.</p>
<h4 id="heading-advantages-of-mid-fidelity-wireframing">Advantages of Mid-Fidelity Wireframing</h4>
<ul>
<li>Efficient Design Process: Mid-fidelity wireframing can be completed quickly and efficiently, allowing designers to iterate and test their designs faster.</li>
<li>Cost-effective: Mid-fidelity wireframes are less expensive to create than high fidelity wireframes, making them a more cost-effective option for design projects.</li>
<li>Usability Testing: Mid-fidelity wireframes can be used for usability testing, providing insights into user behaviour and interaction with the product.</li>
<li>Flexibility: Definitely one of the most importnat advantages of mid-fidelity wireframes. Mid-fidelity wireframes are less detailed than high fidelity wireframes, making it easier to make changes and pivot design direction during the design process.</li>
</ul>
<h4 id="heading-disadvantages-of-mid-fidelity-wireframing">Disadvantages of Mid-Fidelity Wireframing</h4>
<ul>
<li>Less Realistic: Mid-fidelity wireframes may not accurately represent the design's final look, which can impact stakeholder and client expectations.</li>
<li>Limited Visual Details: Mid-fidelity wireframes do not provide as much detail as high fidelity wireframes, making it difficult to communicate the final design vision to stakeholders.</li>
<li>User Experience Limitations: Because mid-fidelity designs do not have enough visual details to test the user experience effectively, leading to potential usability issues.</li>
</ul>
<p>You'll see an example of this below when we walk through my process.</p>
<h4 id="heading-why-you-might-want-to-use-mid-fidelity-wireframes">Why You Might Want to Use Mid-Fidelity Wireframes</h4>
<ul>
<li>For Refining Structure and Content: When you need to refine the structure, content and layout of your design, mid-fidelity wireframes are beneficial. They allow you add more detail to your wireframes while being relatively quick to create and modify.</li>
<li>Information Architecture: Mid-fidelity wireframes provide a clearer structure and visual representation of the design, showing off the userflow better than low-fidelity wireframes. </li>
<li>Stakeholder Presentation and Approvals: Mid-fidelity wireframes are more polished and appealing than low-fidelity wireframes. This makes them a more effective tool when presenting design ideas to stakeholders and clients.</li>
<li>Design Consistency: By adding more visual details to the wireframes, a consisent design language can be established across multiple screens or pages.  </li>
</ul>
<h3 id="heading-high-fidelity-wireframing">High-Fidelity Wireframing</h3>
<p>High fidelity wireframing refers to the creation of detailed, visually-rich wireframes that closely resemble the final product or website. </p>
<p>These wireframes are often created using tools like Adobe XD or Figma and include elements like typography, color schemes, and detailed user interface elements.</p>
<h4 id="heading-advantages-of-high-fidelity-wireframing">Advantages of High-Fidelity Wireframing</h4>
<p>Some advantages of high-fidelity wireframes include:</p>
<ul>
<li>Detailed Representation: High fidelity wireframes provide a more detailed representation of the final product, making it easier to communicate the design vision to stakeholders.</li>
<li>Efficient Testing: High fidelity wireframes can be used for testing purposes, helping designers identify any usability issues before the development phase begins.</li>
<li>Better Visuals and User Experience: High fidelity wireframes are aesthetically pleasing and provide a more realistic view of the final product which helps users visualize the design better. It gives the users better understanding of how to interact with the product.</li>
</ul>
<h4 id="heading-disadvantages-of-high-fidelity-wireframing">Disadvantages of High-Fidelity Wireframing</h4>
<ul>
<li>Time-consuming: High fidelity wireframes take longer to create than low-fidelity wireframes. It can be challenging to complete high fidelity wireframes withing tight project timelines. </li>
<li>Cost: High fidelity wireframes can be expensive to create, as it requires a significant amount of skill and effort from the design team.</li>
<li>Limited Flexibility: High fidelity wireframes are not as flexible as low-fidelity or mid-fidelity wireframes. They are detailed and specific, which makes it challenging to change the design direction once they are completed.</li>
</ul>
<p>You'll see an example of this in a moment during my process walkthrough.</p>
<h4 id="heading-why-you-might-want-to-use-high-fidelity-wireframes">Why You Might Want to Use High-Fidelity Wireframes</h4>
<ul>
<li>Hand-off to Development: High-fidelity wireframes provide accurate visuals, detailed specifications, and design assets that facilitate the handoff process to developers. </li>
<li>High Visual Realism: High-fidelity wireframes closely resemble the final visual design and provides a realistic representation of the user interface, to potential users and stakeholders.</li>
<li>User Experience Validation: High-fidelity wireframes allow you to test and validate the user experience more accurately. With realistic visuals, you can simulate user interactions, flows and transitions, enabling users to provide meaningful feedback and uncover potential usability issues before development.</li>
<li>Design Consistency: By including more visual elements than the mid-fidelity wireframes, high-fidelity wireframes helps establish a consistent visual hierarchy and design language that can be carried over to the final product.</li>
<li>Style Guide Creation: High-fidelity wireframes play a crucial role in developing a style guide for your design. They establish the visuals and design assets that will be used till the launch of the product. </li>
</ul>
<h2 id="heading-my-wireframing-process">My Wireframing Process</h2>
<p>I worked on a mobile app to help pregnant mothers through their pregnancy journey. I started with paper sketches, moved on to mid fidelity wireframes, and then did my high fidelity wireframes. </p>
<h3 id="heading-step-1-paper-sketches">Step 1 – Paper Sketches</h3>
<p>For my paper sketches, I used the Crazy Eights(8s) method, which is a very quick way to put out ideas and inspirations. </p>
<p>Basically, I took out my drawing book, drew 8 identical phone frames and sketched out how I wanted my design to look using a pen. The sketches were more elaborate than usual, because I wanted to move straight to doing mid-fidelity wireframes.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/IMG_20230507_092729_458.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Crazy Eights sketches</em></p>
<h3 id="heading-step-2-moving-to-mid-fidelity-wireframes">Step 2 – Moving to Mid Fidelity Wireframes</h3>
<p>Next up, I opened a new Figma file on my laptop and transferred my sketches on paper to phone mockups on Figma. </p>
<p>First, I chose the frame I wanted to use for the designs – Iphone 13 pro.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Phone-frame1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choose the phone you want to use</em></p>
<p>Then I used my sketches as a guide. It was mostly replicating what I already had on paper, digitally.</p>
<p>Next I used rectangles to denote images, and lorem ipsum (dummy text) for parts of the design which needed long texts.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/frame-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Adding rectangles and dummy text</em></p>
<p>Prior to this, I had created a style guide. So I just got the icons from the style guide.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Group-10.png" alt="Image" width="600" height="400" loading="lazy">
<em>My Mid-fidelity Wireframes</em></p>
<h3 id="heading-step-3-creating-high-fidelity-wireframes">Step 3 – Creating High Fidelity Wireframes</h3>
<p>This was the last phase of my wireframing. Here, I added colours, images, and real text to my designs.</p>
<ol>
<li>I started by adding colours to the mid-fidelity screens.</li>
<li>I also wrote out real text for the screens, making sure the copy matched the branding and purpose of the app.</li>
<li>Lastly, I added illustrations and images where needed, helping users relate to the design.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/frame-1-high-fidelity.png" alt="Image" width="600" height="400" loading="lazy">
<em>Example of high fidelity wireframing</em></p>
<p>In high-fidelity wireframing, once the overall structure is in place, you can start adding more details and refining the design. This includes adding visual elements such as images, icons, and typography, as well as defining interactions and transitions.</p>
<p>Share the high-fidelity wireframe with stakeholders, users, or other team members, and gather feedback. Use this feedback to refine the design and make any necessary changes. </p>
<p>Once the wireframe has been approved and refined, finalize it by adding annotations, notes, and any other necessary documentation. The wireframe should be detailed enough to provide a clear understanding of the design to developers, but not so detailed that it hinders the design process.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/05/Group-9.png" alt="Image" width="600" height="400" loading="lazy">
<em>Completed High Fidelity Wireframes</em></p>
<p>Note that you can use any type of wireframe you would like to, depending on the specific project you're working on, the stage of the project and your objectives. You should also consider the complexity of the design, the available time and resources, and the needs of the stakeholders and users when determining the appropriate fidelity level for your wireframes. </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Wireframing is an essential step in the design process that helps ensure a successful outcome. It enables designers to visualize the layout and functionality of a platform before investing significant time and resources into coding and development. </p>
<p>Incorporating wireframing into your design process can lead to more efficient, effective, and user-friendly designs.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is SOLID? Principles for Better Software Design ]]>
                </title>
                <description>
                    <![CDATA[ The SOLID principles are a set of guidelines for writing high-quality, maintainable, and scalable software.  They were introduced by Robert C. Martin in his 2000 paper “Design Principles and Design Patterns” to help developers write software that is ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/solid-principles-for-better-software-design/</link>
                <guid isPermaLink="false">66ba0ec7439ed06e055759f0</guid>
                
                    <category>
                        <![CDATA[ design patterns ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ solid ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ashutosh Krishna ]]>
                </dc:creator>
                <pubDate>Wed, 03 May 2023 14:00:01 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/solid-principles.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The SOLID principles are a set of guidelines for writing high-quality, maintainable, and scalable software. </p>
<p>They were introduced by Robert C. Martin in his 2000 paper <a target="_blank" href="https://fi.ort.edu.uy/innovaportal/file/2032/1/design_principles.pdf">“Design Principles and Design Patterns”</a> to help developers write software that is easy to understand, modify, and extend. </p>
<p>These concepts were later built upon by Michael Feathers, who introduced us to the SOLID acronym.</p>
<p>The SOLID acronym stands for:</p>
<ul>
<li><strong>S</strong>ingle Responsibility Principle (SRP)</li>
<li><strong>O</strong>pen-Closed Principle (OCP)</li>
<li><strong>L</strong>iskov Substitution Principle (LSP)</li>
<li><strong>I</strong>nterface Segregation Principle (ISP)</li>
<li><strong>D</strong>ependency Inversion Principle (DIP)</li>
</ul>
<p>These principles provide a way for developers to organize their code and create software that is flexible, easy to change, and testable. Applying SOLID principles can lead to code that is more modular, maintainable, and extensible, and it can make it easier for developers to work collaboratively on a codebase.</p>
<p>In this tutorial, we will explore each of the SOLID principles in detail, explain why they are important, and provide examples of how you can apply them in practice. By the end of this tutorial, you should have a good understanding of the SOLID principles and how to apply them to your software development projects.</p>
<h2 id="heading-what-is-the-single-responsibility-principle"><strong>What is the Single Responsibility Principle?</strong></h2>
<p>The Single Responsibility Principle (SRP) states that <strong>a class should have only one reason to change</strong>, or in other words, <strong>it should have only one responsibility</strong>. This means that a class should have only one job to do, and it should do it well.</p>
<p>If a class has too many responsibilities, it can become hard to understand, maintain, and modify. Changes to one responsibility can inadvertently affect another responsibility, leading to unintended consequences and bugs. By following SRP, we can create code that is more modular, easier to understand, and less prone to errors.</p>
<p>Let's take an example that violates the SRP:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Marker</span> </span>{
    String name;
    String color;
    <span class="hljs-keyword">int</span> price;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Marker</span><span class="hljs-params">(String name, String color, <span class="hljs-keyword">int</span> price)</span> </span>{
        <span class="hljs-keyword">this</span>.name = name;
        <span class="hljs-keyword">this</span>.color = color;
        <span class="hljs-keyword">this</span>.price = price;
    }
}
</code></pre>
<p>The above code defines a simple <code>Marker</code> class having three instance variables – <code>name</code>, <code>color</code> and <code>price</code>.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Invoice</span> </span>{
    <span class="hljs-keyword">private</span> Marker marker;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> quantity;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Invoice</span><span class="hljs-params">(Marker marker, <span class="hljs-keyword">int</span> quantity)</span> </span>{
        <span class="hljs-keyword">this</span>.marker = marker;
        <span class="hljs-keyword">this</span>.quantity = quantity;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">calculateTotal</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> marker.price * <span class="hljs-keyword">this</span>.quantity;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">printInvoice</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// printing implementation</span>
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">saveToDb</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// save to database implementation</span>
    }
}
</code></pre>
<p>The above <code>Invoice</code> class violates the SRP because it has multiple responsibilities – it is responsible for calculating the total amount, printing the invoice, and saving the invoice to the database. As a result, if the calculation logic changes, such as the addition of taxes, the <code>calculateTotal()</code> method would require modification. Similarly, if the printing or database-saving implementation changes at any point, the class would need to be changed. </p>
<p>There are several reasons for the class to be modified, which could lead to increased maintenance costs and complexity.</p>
<p>Here's how you can modify the code to follow the SRP:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Invoice</span> </span>{
    <span class="hljs-keyword">private</span> Marker marker;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> quantity;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Invoice</span><span class="hljs-params">(Marker marker, <span class="hljs-keyword">int</span> quantity)</span> </span>{
        <span class="hljs-keyword">this</span>.marker = marker;
        <span class="hljs-keyword">this</span>.quantity = quantity;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">calculateTotal</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> marker.price * <span class="hljs-keyword">this</span>.quantity;
    }
}
</code></pre>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">InvoiceDao</span> </span>{
    <span class="hljs-keyword">private</span> Invoice invoice;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">InvoiceDao</span><span class="hljs-params">(Invoice invoice)</span> </span>{
        <span class="hljs-keyword">this</span>.invoice = invoice;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">saveToDb</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// save to database implementation</span>
    }
}
</code></pre>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">InvoicePrinter</span> </span>{
    <span class="hljs-keyword">private</span> Invoice invoice;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">InvoicePrinter</span><span class="hljs-params">(Invoice invoice)</span> </span>{
        <span class="hljs-keyword">this</span>.invoice = invoice;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">printInvoice</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// printing implementation</span>
    }
}
</code></pre>
<p>In this refactored example, we have split the responsibilities of the <code>Invoice</code> class into three separate classes: <code>Invoice</code>, <code>InvoiceDao</code>, and <code>InvoicePrinter</code>. </p>
<p>The <code>Invoice</code> class is responsible only for calculating the total amount, and the printing and saving responsibilities have been delegated to separate classes. This makes the code more modular, easier to understand, and less prone to errors.</p>
<h2 id="heading-what-is-the-open-closed-principle"><strong>What is the Open-Closed Principle?</strong></h2>
<p>The Open-Closed Principle (OCP) states that <strong>software entities (classes, modules, functions, and so on) should be open for extension but closed for modification</strong>. This means that the behavior of a software entity can be extended without modifying its source code.</p>
<p>The OCP is essential because it promotes software extensibility and maintainability. By allowing software entities to be extended without modification, developers can add new functionality without the risk of breaking existing code. This results in code that is easier to maintain, extend, and reuse.</p>
<p>Let's take the previous example again.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">InvoiceDao</span> </span>{
    <span class="hljs-keyword">private</span> Invoice invoice;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">InvoiceDao</span><span class="hljs-params">(Invoice invoice)</span> </span>{
        <span class="hljs-keyword">this</span>.invoice = invoice;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">saveToDb</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// save to database implementation</span>
    }
}
</code></pre>
<p>The <code>InvoiceDao</code> class has a single responsibility of saving the invoice to the database. But, suppose there's a new requirement to save the invoice to a file as well. One way to implement this requirement would be to modify the existing <code>InvoiceDao</code> class by adding a <code>saveToFile()</code> method. But this violates the Open-Closed Principle because it modifies the existing code that has already been tested and is live in production.</p>
<p>To follow the OCP, a better solution would be to create an <code>InvoiceDao</code> interface and implement it separately for database and file saving as shown below:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">InvoiceDao</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">save</span><span class="hljs-params">(Invoice invoice)</span></span>;
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DatabaseInvoiceDao</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">InvoiceDao</span> </span>{
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">save</span><span class="hljs-params">(Invoice invoice)</span> </span>{
        <span class="hljs-comment">// save to database implementation</span>
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FileInvoiceDao</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">InvoiceDao</span> </span>{
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">save</span><span class="hljs-params">(Invoice invoice)</span> </span>{
        <span class="hljs-comment">// save to file implementation</span>
    }
}
</code></pre>
<p>This way, if there's a new requirement to save the invoice to another data store, you can implement a new <code>InvoiceDao</code> implementation without modifying the existing code. Now the <code>InvoiceDao</code> interface is open for extension and closed for modification, which follows the OCP.</p>
<h2 id="heading-what-is-the-liskov-substitution-principle"><strong>What is the </strong>L<strong>iskov Substitution Principle?</strong></h2>
<p>The Liskov Substitution Principle (LSP) states that <strong>any instance of a derived class should be substitutable for an instance of its base class without affecting the correctness of the program</strong>. </p>
<p>In other words, a derived class should behave like its base class in all contexts. In more simple terms, if class A is a subtype of class B, you should be able to replace B with A without breaking the behavior of your program.</p>
<p>The importance of the LSP lies in its ability to ensure that the behavior of a program remains consistent and predictable when substituting objects of different classes. Violating the LSP can lead to unexpected behavior, bugs, and maintainability issues.</p>
<p>Let's take an example.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Bike</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">turnOnEngine</span><span class="hljs-params">()</span></span>;

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">accelerate</span><span class="hljs-params">()</span></span>;
}
</code></pre>
<p>In the given example, the interface <code>Bike</code> has two methods, <code>turnOnEngine()</code> and <code>accelerate()</code>. Two classes implement this interface, <code>Motorbike</code> and <code>Bicycle</code>.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Motorbike</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Bike</span> </span>{

    <span class="hljs-keyword">boolean</span> isEngineOn;
    <span class="hljs-keyword">int</span> speed;

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">turnOnEngine</span><span class="hljs-params">()</span> </span>{
        isEngineOn = <span class="hljs-keyword">true</span>;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">accelerate</span><span class="hljs-params">()</span> </span>{
        speed += <span class="hljs-number">5</span>;
    }
}
</code></pre>
<p><code>Motorbike</code> correctly implements the <code>turnOnEngine()</code> method, as it sets the <code>isEngineOn</code> boolean to true. It also correctly implements the <code>accelerate()</code> method by increasing the <code>speed</code> by 5.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Bicycle</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Bike</span> </span>{

    <span class="hljs-keyword">boolean</span> isEngineOn;
    <span class="hljs-keyword">int</span> speed;

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">turnOnEngine</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> AssertionError(<span class="hljs-string">"There is no engine!"</span>);
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">accelerate</span><span class="hljs-params">()</span> </span>{
        speed += <span class="hljs-number">5</span>;
    }
}
</code></pre>
<p>However, the <code>Bicycle</code> class throws an <code>AssertionError</code> in the <code>turnOnEngine()</code> method because it has no engine. This means that an instance of <code>Bicycle</code> cannot be substituted for an instance of <code>Bike</code> without breaking the behavior of the program.</p>
<p>In other words, if the <code>Bicycle</code> class is considered a subtype of the <code>Bike</code> interface, then according to the LSP, any instance of <code>Bike</code> should be replaceable with an instance of <code>Bicycle</code> without altering the correctness of the program. </p>
<p>But in this case, it's not true because <code>Bicycle</code> throws an <code>AssertionError</code> while trying to turn on the engine. Therefore, the code violates the LSP.</p>
<h2 id="heading-what-is-the-interface-segregation-principle"><strong>What is the </strong>I<strong>nterface Segregation Principle?</strong></h2>
<p>The Interface Segregation Principle (ISP) focuses on designing interfaces that are specific to their client's needs. It states that no client should be forced to depend on methods it does not use.</p>
<p>The principle suggests that <strong>instead of creating a large interface that covers all the possible methods, it's better to create smaller, more focused interfaces for specific use cases</strong>. This approach results in interfaces that are more cohesive and less coupled.</p>
<p>Consider a <code>Vehicle</code> interface as below:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Vehicle</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">startEngine</span><span class="hljs-params">()</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">stopEngine</span><span class="hljs-params">()</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">drive</span><span class="hljs-params">()</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">fly</span><span class="hljs-params">()</span></span>;
}
</code></pre>
<p>And then you have a class called <code>Car</code> that implements the <code>Vehicle</code> interface:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Car</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Vehicle</span> </span>{

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">startEngine</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">stopEngine</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drive</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">fly</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> UnsupportedOperationException(<span class="hljs-string">"This vehicle cannot fly."</span>);
    }
}
</code></pre>
<p>In this example, the <code>Vehicle</code> interface has too many methods. The <code>Car</code> class is forced to implement all of them, even though they cannot fly. This violates the ISP because the <code>Vehicle</code> interface is not properly segregated into smaller interfaces based on related functionality.</p>
<p>Let's understand how you can follow the ISP here. Suppose you refactor the <code>Vehicle</code> interface into smaller, more focused interfaces:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Drivable</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">startEngine</span><span class="hljs-params">()</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">stopEngine</span><span class="hljs-params">()</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">drive</span><span class="hljs-params">()</span></span>;
}

<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Flyable</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">fly</span><span class="hljs-params">()</span></span>;
}
</code></pre>
<p>Now, you can have a class called <code>Car</code> that only implements the <code>Drivable</code> interface:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Car</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Drivable</span> </span>{

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">startEngine</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">stopEngine</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drive</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }
}
</code></pre>
<p>And, thanks to interface segregation, you can have another class called <code>Airplane</code> that implements both the <code>Drivable</code> and <code>Flyable</code> interfaces:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Airplane</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Drivable</span>, <span class="hljs-title">Flyable</span> </span>{

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">startEngine</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">stopEngine</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drive</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">fly</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }
}
</code></pre>
<p>In this example, you have properly segregated the <code>Vehicle</code> interface into smaller interfaces based on related functionality. This adheres to the ISP and makes your code more flexible and maintainable.</p>
<h2 id="heading-what-is-the-dependency-inversion-principle"><strong>What is the Dependency Inversion Principle?</strong></h2>
<p>The Dependency Inversion Principle (DIP) states that <strong>high-level modules should not depend on low-level modules, but both should depend on abstractions</strong>. Abstractions should not depend on details – details should depend on abstractions. </p>
<p>This principle aims to reduce coupling between modules, increase modularity, and make the code easier to maintain, test, and extend.</p>
<p>For example, consider a scenario where you have a class that needs to use an instance of another class. In the traditional approach, the first class would directly create an instance of the second class, leading to a tight coupling between them. This makes it difficult to change the implementation of the second class or to test the first class independently. </p>
<p>But if you apply the DIP, the first class would depend on an abstraction of the second class instead of the implementation. This would make it possible to easily change the implementation and test the first class independently.</p>
<p>Here is an example that violates the DIP:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">WeatherTracker</span> </span>{
    <span class="hljs-keyword">private</span> String currentConditions;
    <span class="hljs-keyword">private</span> Emailer emailer;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">WeatherTracker</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">this</span>.emailer = <span class="hljs-keyword">new</span> Emailer();
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setCurrentConditions</span><span class="hljs-params">(String weatherDescription)</span> </span>{
        <span class="hljs-keyword">this</span>.currentConditions = weatherDescription;
        <span class="hljs-keyword">if</span> (weatherDescription == <span class="hljs-string">"rainy"</span>) {
            emailer.sendEmail(<span class="hljs-string">"It is rainy"</span>);
        }
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Emailer</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sendEmail</span><span class="hljs-params">(String message)</span> </span>{
        System.out.println(<span class="hljs-string">"Email sent: "</span> + message);
    }
}
</code></pre>
<p>In this example, the <code>WeatherTracker</code> class directly creates an instance of the <code>Emailer</code> class, making it tightly coupled to the implementation. This makes it difficult to change the implementation of the <code>Emailer</code> class or to test the <code>WeatherTracker</code> class independently.</p>
<p>Here is an example of how to apply the DIP to the above code:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Notifier</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">alertWeatherConditions</span><span class="hljs-params">(String weatherDescription)</span></span>;
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">WeatherTracker</span> </span>{
    <span class="hljs-keyword">private</span> String currentConditions;
    <span class="hljs-keyword">private</span> Notifier notifier;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">WeatherTracker</span><span class="hljs-params">(Notifier notifier)</span> </span>{
        <span class="hljs-keyword">this</span>.notifier = notifier;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setCurrentConditions</span><span class="hljs-params">(String weatherDescription)</span> </span>{
        <span class="hljs-keyword">this</span>.currentConditions = weatherDescription;
        <span class="hljs-keyword">if</span> (weatherDescription == <span class="hljs-string">"rainy"</span>) {
            notifier.alertWeatherConditions(<span class="hljs-string">"It is rainy"</span>);
        }
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Emailer</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Notifier</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">alertWeatherConditions</span><span class="hljs-params">(String weatherDescription)</span> </span>{
        System.out.println(<span class="hljs-string">"Email sent: "</span> + weatherDescription);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SMS</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Notifier</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">alertWeatherConditions</span><span class="hljs-params">(String weatherDescription)</span> </span>{
        System.out.println(<span class="hljs-string">"SMS sent: "</span> + weatherDescription);
    }
}
</code></pre>
<p>In this example, we created a <code>Notifier</code> interface that defines the <code>alertWeatherConditions</code> method. The <code>WeatherTracker</code> class now depends on this interface instead of the <code>Emailer</code> class, making it possible to easily change the implementation and test the <code>WeatherTracker</code> class independently. </p>
<p>We also created two implementations of the <code>Notifier</code> interface, <code>Emailer</code>, and <code>SMS</code>, to demonstrate how you can change the implementation of the <code>WeatherTracker</code> class without affecting its behavior.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>In this article, you learned about the SOLID principles which are a very important part of general Design Principles. </p>
<p>By applying these principles in your software development projects, you can create code that is easier to maintain, extend, and modify, leading to more robust, flexible, and reusable software. This will also lead to better collaboration among team members, as the code becomes more modular and easier to work with.</p>
<blockquote>
<p>For more such tutorials, you can follow <a target="_blank" href="https://blog.ashutoshkrris.in/">my personal blog</a>.</p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ SOLID Principles for Programming and Software Design ]]>
                </title>
                <description>
                    <![CDATA[ The SOLID principles of object-oriented programming help make object-oriented designs more understandable, flexible, and maintainable. They also make it easy to create readable and testable code that many developers can collaboratively work with anyw... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/solid-principles-for-programming-and-software-design/</link>
                <guid isPermaLink="false">66d45ff4230dff0166905821</guid>
                
                    <category>
                        <![CDATA[ clean code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software architecture ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ solid ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Joel Olawanle ]]>
                </dc:creator>
                <pubDate>Wed, 09 Nov 2022 22:43:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/11/Untitled1.drawio--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The SOLID principles of object-oriented programming help make object-oriented designs more understandable, flexible, and maintainable.</p>
<p>They also make it easy to create readable and testable code that many developers can collaboratively work with anywhere and anytime. And they make you aware of the best way to write code 💪.</p>
<p>SOLID is a mnemonic acronym that stands for the five design principles of Object-Oriented class design. These principles are:</p>
<ul>
<li><p><strong>S</strong> - Single-responsibility Principle</p>
</li>
<li><p><strong>O</strong> - Open-closed Principle</p>
</li>
<li><p><strong>L</strong> - Liskov Substitution Principle</p>
</li>
<li><p><strong>I</strong> - Interface Segregation Principle</p>
</li>
<li><p><strong>D</strong> - Dependency Inversion Principle</p>
</li>
</ul>
<p>In this article, you will learn what these principles stand for and how they work using JavaScript examples. The examples should be fine even if you are not fully conversant with JavaScript, because they apply to other programming languages as well.</p>
<h2 id="heading-what-is-the-single-responsibility-principle-srp">What is the Single-Responsibility Principle (SRP)?</h2>
<p>The Single-responsibility Principle, or SRP, states that a class should only have one reason to change. This means that a class should have only one job and do one thing.</p>
<p>Let’s take a look at a proper example. You’ll always be tempted to put similar classes together – but unfortunately, this goes against the Single-responsibility principle. Why?</p>
<p>The <code>ValidatePerson</code> object below has three methods: two validation methods, (<code>ValidateName()</code> and <code>ValidateAge()</code>), and a <code>Display()</code> method.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ValidatePerson</span> </span>{
    <span class="hljs-keyword">constructor</span>(name, age) {
        <span class="hljs-built_in">this</span>.name = name;
        <span class="hljs-built_in">this</span>.age = age;
    }

    ValidateName(name) {
        <span class="hljs-keyword">if</span> (name.length &gt; <span class="hljs-number">3</span>) {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
    }

    ValidateAge(age) {
        <span class="hljs-keyword">if</span> (age &gt; <span class="hljs-number">18</span>) {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
    }

    Display() {
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.ValidateName(<span class="hljs-built_in">this</span>.name) &amp;&amp; <span class="hljs-built_in">this</span>.ValidateAge(<span class="hljs-built_in">this</span>.age)) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Name: <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> and Age: <span class="hljs-subst">${<span class="hljs-built_in">this</span>.age}</span>`</span>);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Invalid'</span>);
        }
    }
}
</code></pre>
<p>The <code>Display()</code> method goes against the SRP because the goal is that a class should have only one job and do one thing. The <code>ValidatePerson</code> class does two jobs – it validates the person’s name and age and then displays some information.</p>
<p>The way to avoid this problem is to separate code that supports different actions and jobs so that each class only performs one job and has one reason to change.</p>
<p>This means that the <code>ValidatePerson</code> class will only be responsible for validating a user, as seen below:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ValidatePerson</span> </span>{
    <span class="hljs-keyword">constructor</span>(name, age) {
        <span class="hljs-built_in">this</span>.name = name;
        <span class="hljs-built_in">this</span>.age = age;
    }

    ValidateName(name) {
        <span class="hljs-keyword">if</span> (name.length &gt; <span class="hljs-number">3</span>) {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
    }

    ValidateAge(age) {
        <span class="hljs-keyword">if</span> (age &gt; <span class="hljs-number">18</span>) {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
    }
}
</code></pre>
<p>While the new class <code>DisplayPerson</code> will now be responsible for displaying a person, as you can see in the code block below:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DisplayPerson</span> </span>{
    <span class="hljs-keyword">constructor</span>(name, age) {
        <span class="hljs-built_in">this</span>.name = name;
        <span class="hljs-built_in">this</span>.age = age;
        <span class="hljs-built_in">this</span>.validate = <span class="hljs-keyword">new</span> ValidatePerson(<span class="hljs-built_in">this</span>.name, <span class="hljs-built_in">this</span>.age);
    }

    Display() {
        <span class="hljs-keyword">if</span> (
            <span class="hljs-built_in">this</span>.validate.ValidateName(<span class="hljs-built_in">this</span>.name) &amp;&amp;
            <span class="hljs-built_in">this</span>.validate.ValidateAge(<span class="hljs-built_in">this</span>.age)
        ) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Name: <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> and Age: <span class="hljs-subst">${<span class="hljs-built_in">this</span>.age}</span>`</span>);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Invalid'</span>);
        }
    }
}
</code></pre>
<p>With this, you will have fulfilled the single-responsibility principle, meaning our classes now have just one reason to change. If you want to change the <code>DisplayPerson</code> class, it won’t affect the <code>ValidatePerson</code> class.</p>
<h2 id="heading-what-is-the-open-closed-principle">What is the Open-Closed Principle?</h2>
<p>The open-closed principle can be confusing because it's a two-direction principle. According to <a target="_blank" href="https://en.wikipedia.org/wiki/Bertrand_Meyer">Bertrand Meyer's</a> definition on <a target="_blank" href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle">Wikipedia</a>, the <strong>open-closed principle (OCP)</strong> states that software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.</p>
<p>This definition can be confusing, but an example and further clarification will help you understand.</p>
<p>There are two primary attributes in the OCP:</p>
<ul>
<li><p>It is <strong>open</strong> for extension — This means you can extend what the module can do.</p>
</li>
<li><p>It is <strong>closed</strong> for modification — This means you cannot change the source code, even though you can extend the behavior of a module or entity.</p>
</li>
</ul>
<p>OCP means that a class, module, function, and other entities can extend their behavior without modifying their source code. In other words, an entity should be extendable without modifying the entity itself. How?</p>
<p>For example, suppose you have an array of <code>iceCreamFlavours</code>, which contains a list of possible flavors. In the <code>makeIceCream</code> class, a <code>make()</code> method will check if a particular flavor exists and logs a message.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> iceCreamFlavors = [<span class="hljs-string">'chocolate'</span>, <span class="hljs-string">'vanilla'</span>];

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">makeIceCream</span> </span>{
    <span class="hljs-keyword">constructor</span>(flavor) {
        <span class="hljs-built_in">this</span>.flavor = flavor;
    }

    make() {
        <span class="hljs-keyword">if</span> (iceCreamFlavors.indexOf(<span class="hljs-built_in">this</span>.flavor) &gt; <span class="hljs-number">-1</span>) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Great success. You now have ice cream.'</span>);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Epic fail. No ice cream for you.'</span>);
        }
    }
}
</code></pre>
<p>The code above fails the OCP principle. Why? Well, because the code above is not open to an extension, meaning for you to add new flavors, you would need to directly edit the <code>iceCreamFlavors</code> array. This means that the code is no longer closed to modification. Haha (that's a lot).</p>
<p>To fix this, you would need an extra class or entity to handle addition, so you no longer need to modify the code directly to make any extension.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> iceCreamFlavors = [<span class="hljs-string">'chocolate'</span>, <span class="hljs-string">'vanilla'</span>];

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">makeIceCream</span> </span>{
    <span class="hljs-keyword">constructor</span>(flavor) {
        <span class="hljs-built_in">this</span>.flavor = flavor;
    }
    make() {
        <span class="hljs-keyword">if</span> (iceCreamFlavors.indexOf(<span class="hljs-built_in">this</span>.flavor) &gt; <span class="hljs-number">-1</span>) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Great success. You now have ice cream.'</span>);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Epic fail. No ice cream for you.'</span>);
        }
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">addIceCream</span> </span>{
    <span class="hljs-keyword">constructor</span>(flavor) {
        <span class="hljs-built_in">this</span>.flavor = flavor;
    }
    add() {
        iceCreamFlavors.push(<span class="hljs-built_in">this</span>.flavor);
    }
}
</code></pre>
<p>Here, we've added a new class — <code>addIceCream</code> – to handle addition to the <code>iceCreamFlavors</code> array using the <code>add()</code> method. This means your code is closed to modification but open to an extension because you can add new flavors without directly affecting the array.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> addStrawberryFlavor = <span class="hljs-keyword">new</span> addIceCream(<span class="hljs-string">'strawberry'</span>);
addStrawberryFlavor.add();
makeStrawberryIceCream.make();
</code></pre>
<p>Also, notice that SRP is in place because you created a new class. 😊</p>
<h2 id="heading-what-is-the-liskov-substitution-principle">What is the Liskov Substitution Principle?</h2>
<p>In 1987, the Liskov Substitution Principle (LSP) was introduced by <a target="_blank" href="https://en.wikipedia.org/wiki/Barbara_Liskov">Barbara Liskov</a> in her conference keynote “Data abstraction”. A few years later, she defined the principle like this:</p>
<blockquote>
<p>“Let Φ(x) be a property provable about objects x of type T. Then Φ(y) should be true for objects y of type S where S is a subtype of T”.</p>
</blockquote>
<p>To be honest, that definition is not what many software developers want to see 😂 — so let me break it down into an OOP-related definition.</p>
<p>The principle defines that in an inheritance, objects of a superclass (or parent class) should be substitutable with objects of its subclasses (or child class) without breaking the application or causing any error.</p>
<p>In very plain terms, you want the objects of your subclasses to behave the same way as the objects of your superclass.</p>
<p>A very common example is the rectangle, square scenario. It’s clear that all squares are rectangles because they are quadrilaterals with all four angles being right angles. But not every rectangle is a square. To be a square, its sides must have the same length.</p>
<p>Bearing this in mind, suppose you have a rectangle class to calculate the area of a rectangle and perform other operations like set color:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Rectangle</span> </span>{
    setWidth(width) {
        <span class="hljs-built_in">this</span>.width = width;
    }

    setHeight(height) {
        <span class="hljs-built_in">this</span>.height = height;
    }

    setColor(color) {
        <span class="hljs-comment">// ...</span>
    }

    getArea() {
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.width * <span class="hljs-built_in">this</span>.height;
    }
}
</code></pre>
<p>Knowing fully well that all squares are rectangles, you can inherit the properties of the rectangle. Since the width and height has to be the same, then you can adjust it:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Square</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Rectangle</span> </span>{
    setWidth(width) {
        <span class="hljs-built_in">this</span>.width = width;
        <span class="hljs-built_in">this</span>.height = width;
    }
    setHeight(height) {
        <span class="hljs-built_in">this</span>.width = height;
        <span class="hljs-built_in">this</span>.height = height;
    }
}
</code></pre>
<p>Taking a look at the example, it should work properly:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> rectangle = <span class="hljs-keyword">new</span> Rectangle();
rectangle.setWidth(<span class="hljs-number">10</span>);
rectangle.setHeight(<span class="hljs-number">5</span>);
<span class="hljs-built_in">console</span>.log(rectangle.getArea()); <span class="hljs-comment">// 50</span>
</code></pre>
<p>In the above, you will notice that a rectangle is created, and the width and height are set. Then you can calculate the correct area.</p>
<p>But according to the LSP, you want the objects of your subclasses to behave the same way as the objects of your superclass. Meaning if you replace the <code>Rectangle</code> with <code>Square</code>, everything should still work well:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> square = <span class="hljs-keyword">new</span> Square();
square.setWidth(<span class="hljs-number">10</span>);
square.setHeight(<span class="hljs-number">5</span>);
</code></pre>
<p>You should get 100, because the <code>setWidth(10)</code> is supposed to set both the width and height to 10. But because of the <code>setHeight(5)</code>, this will return 25.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> square = <span class="hljs-keyword">new</span> Square();
square.setWidth(<span class="hljs-number">10</span>);
square.setHeight(<span class="hljs-number">5</span>);
<span class="hljs-built_in">console</span>.log(square.getArea()); <span class="hljs-comment">// 25</span>
</code></pre>
<p>This breaks the LSP. To fix this, there should be a general class for all shapes that will hold all generic methods that you want the objects of your subclasses to have access to. Then for individual methods, you create an individual class for rectangle and square.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Shape</span> </span>{
    setColor(color) {
        <span class="hljs-built_in">this</span>.color = color;
    }
    getColor() {
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.color;
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Rectangle</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Shape</span> </span>{
    setWidth(width) {
        <span class="hljs-built_in">this</span>.width = width;
    }
    setHeight(height) {
        <span class="hljs-built_in">this</span>.height = height;
    }
    getArea() {
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.width * <span class="hljs-built_in">this</span>.height;
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Square</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Shape</span> </span>{
    setSide(side) {
        <span class="hljs-built_in">this</span>.side = side;
    }
    getArea() {
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.side * <span class="hljs-built_in">this</span>.side;
    }
}
</code></pre>
<p>This way, you can set the color and get the color using either the super or subclasses:</p>
<pre><code class="lang-js"><span class="hljs-comment">// superclass</span>
<span class="hljs-keyword">let</span> shape = <span class="hljs-keyword">new</span> Shape();
shape.setColor(<span class="hljs-string">'red'</span>);
<span class="hljs-built_in">console</span>.log(shape.getColor()); <span class="hljs-comment">// red</span>

<span class="hljs-comment">// subclass</span>
<span class="hljs-keyword">let</span> rectangle = <span class="hljs-keyword">new</span> Rectangle();
rectangle.setColor(<span class="hljs-string">'red'</span>);
<span class="hljs-built_in">console</span>.log(rectangle.getColor()); <span class="hljs-comment">// red</span>

<span class="hljs-comment">// subclass</span>
<span class="hljs-keyword">let</span> square = <span class="hljs-keyword">new</span> Square();
square.setColor(<span class="hljs-string">'red'</span>);
<span class="hljs-built_in">console</span>.log(square.getColor()); <span class="hljs-comment">// red</span>
</code></pre>
<h2 id="heading-what-is-the-interface-segregation-principle">What is the Interface Segregation Principle?</h2>
<p>The Interface Segregation Principle (ISP) states that “a client should never be forced to implement an interface that it doesn’t use, or clients shouldn’t be forced to depend on methods they do not use”. What does this mean?</p>
<p>Just as the term segregation means — this is all about keeping things separated, meaning separating the interfaces.</p>
<p><strong>Note:</strong> By default, JavaScript does not have interfaces, but this principle still applies. So let’s explore this as if the interface exists, so you will know how it works for other programming languages like Java.</p>
<p>A typical interface will contain methods and properties. When you implement this interface into any class, then the class needs to define all its methods. For example, suppose you have an interface that defines methods to draw specific shapes.</p>
<pre><code class="lang-js">interface ShapeInterface {
    calculateArea();
    calculateVolume();
}
</code></pre>
<p>When any class implements this interface, all the methods must be defined even if you won't use them or if they don’t apply to that class.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Square</span> <span class="hljs-title">implements</span> <span class="hljs-title">ShapeInterface</span> </span>{
    calculateArea(){
        <span class="hljs-comment">//...</span>
    }
    calculateVolume(){
        <span class="hljs-comment">//...</span>
    }  
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cuboid</span> <span class="hljs-title">implements</span> <span class="hljs-title">ShapeInterface</span> </span>{
    calculateArea(){
        <span class="hljs-comment">//...</span>
    }
    calculateVolume(){
        <span class="hljs-comment">//...</span>
    }    
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Rectangle</span> <span class="hljs-title">implements</span> <span class="hljs-title">ShapeInterface</span> </span>{
    calculateArea(){
        <span class="hljs-comment">//...</span>
    }
    calculateVolume(){
        <span class="hljs-comment">//...</span>
    }   
}
</code></pre>
<p>Looking at the example above, you will notice that you cannot calculate the volume of a square or rectangle. Because the class implements the interface, you need to define all methods, even the ones you won’t use or need.</p>
<p>To fix this, you would need to segregate the interface.</p>
<pre><code class="lang-js">interface ShapeInterface {
    calculateArea();
}

interface ThreeDimensionalShapeInterface {
    calculateArea();
    calculateVolume();
}
</code></pre>
<p>You can now implement the specific interface that works with each class.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Square</span> <span class="hljs-title">implements</span> <span class="hljs-title">ShapeInterface</span> </span>{
    calculateArea(){
        <span class="hljs-comment">//...</span>
    } 
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cuboid</span> <span class="hljs-title">implements</span> <span class="hljs-title">ThreeDimensionalShapeInterface</span> </span>{
    calculateArea(){
        <span class="hljs-comment">//...</span>
    }
    calculateVolume(){
        <span class="hljs-comment">//...</span>
    }    
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Rectangle</span> <span class="hljs-title">implements</span> <span class="hljs-title">ShapeInterface</span> </span>{
    calculateArea(){
        <span class="hljs-comment">//...</span>
    }  
}
</code></pre>
<h2 id="heading-what-is-the-dependency-inversion-principle">What is the Dependency Inversion Principle?</h2>
<p>This principle is targeted towards loosely coupling software modules so that high-level modules (which provide complex logic) are easily reusable and unaffected by changes in low-level modules (which provide utility features).</p>
<p>According to <a target="_blank" href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Wikipedia</a>, this principle states that:</p>
<ol>
<li><p>High-level modules should not import anything from low-level modules. Both should depend on abstractions (for example, interfaces).</p>
</li>
<li><p>Abstractions should be independent of details. Details (concrete implementations) should depend on abstractions.</p>
</li>
</ol>
<p>In plain terms, this principle states that your classes should depend upon interfaces or abstract classes instead of concrete classes and functions. This makes your classes open to extension, following the open-closed principle.</p>
<p>Let's look at an example. When building a store, you would want your store to make use of a payment gateway like stripe or any other preferred payment method. You might write your code tightly coupled to that API without thinking of the future.</p>
<p>But then what if you discover another payment gateway that offers far better service, let’s say PayPal? Then it becomes a struggle to switch from Stripe to Paypal, which should not be an issue in programming and software design.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
    <span class="hljs-keyword">constructor</span>(user) {
        <span class="hljs-built_in">this</span>.stripe = <span class="hljs-keyword">new</span> Stripe(user);
    }

    purchaseBook(quantity, price) {
        <span class="hljs-built_in">this</span>.stripe.makePayment(price * quantity);
    }

    purchaseCourse(quantity, price) {
        <span class="hljs-built_in">this</span>.stripe.makePayment(price * quantity);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stripe</span> </span>{
    <span class="hljs-keyword">constructor</span>(user) {
        <span class="hljs-built_in">this</span>.user = user;
    }

    makePayment(amountInDollars) {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.user}</span> made payment of <span class="hljs-subst">${amountInDollars}</span>`</span>);
    }
}
</code></pre>
<p>Considering the example above, you'll notice that if you change the payment gateway, you won't just need to add the class – you'll also need to make changes to the <code>Store</code> class. This does not just go against the Dependency Inversion Principle but also against the open-closed principle.</p>
<p>To fix this, you must ensure that your classes depend upon interfaces or abstract classes instead of concrete classes and functions. For this example, this interface will contain all the behavior you want your API to have and doesn't depend on anything. It serves as an intermediary between the high-level and low-level modules.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
    <span class="hljs-keyword">constructor</span>(paymentProcessor) {
        <span class="hljs-built_in">this</span>.paymentProcessor = paymentProcessor;
    }

    purchaseBook(quantity, price) {
        <span class="hljs-built_in">this</span>.paymentProcessor.pay(quantity * price);
    }

    purchaseCourse(quantity, price) {
        <span class="hljs-built_in">this</span>.paymentProcessor.pay(quantity * price);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StripePaymentProcessor</span> </span>{
    <span class="hljs-keyword">constructor</span>(user) {
        <span class="hljs-built_in">this</span>.stripe = <span class="hljs-keyword">new</span> Stripe(user);
    }

    pay(amountInDollars) {
        <span class="hljs-built_in">this</span>.stripe.makePayment(amountInDollars);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stripe</span> </span>{
    <span class="hljs-keyword">constructor</span>(user) {
        <span class="hljs-built_in">this</span>.user = user;
    }

    makePayment(amountInDollars) {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.user}</span> made payment of <span class="hljs-subst">${amountInDollars}</span>`</span>);
    }
}

<span class="hljs-keyword">let</span> store = <span class="hljs-keyword">new</span> Store(<span class="hljs-keyword">new</span> StripePaymentProcessor(<span class="hljs-string">'John Doe'</span>));
store.purchaseBook(<span class="hljs-number">2</span>, <span class="hljs-number">10</span>);
store.purchaseCourse(<span class="hljs-number">1</span>, <span class="hljs-number">15</span>);
</code></pre>
<p>In the code above, you will notice that the <code>StripePaymentProcessor</code> class is an interface between the <code>Store</code> class and the <code>Stripe</code> class. In a situation where you need to make use of PayPal, all you have to do is create a <code>PayPalPaymentProcessor</code> which would work with the <code>PayPal</code> class, and everything will work without affecting the <code>Store</code> class.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
    <span class="hljs-keyword">constructor</span>(paymentProcessor) {
        <span class="hljs-built_in">this</span>.paymentProcessor = paymentProcessor;
    }

    purchaseBook(quantity, price) {
        <span class="hljs-built_in">this</span>.paymentProcessor.pay(quantity * price);
    }

    purchaseCourse(quantity, price) {
        <span class="hljs-built_in">this</span>.paymentProcessor.pay(quantity * price);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PayPalPaymentProcessor</span> </span>{
    <span class="hljs-keyword">constructor</span>(user) {
        <span class="hljs-built_in">this</span>.user = user;
        <span class="hljs-built_in">this</span>.paypal = <span class="hljs-keyword">new</span> PayPal();
    }

    pay(amountInDollars) {
        <span class="hljs-built_in">this</span>.paypal.makePayment(<span class="hljs-built_in">this</span>.user, amountInDollars);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PayPal</span> </span>{
    makePayment(user, amountInDollars) {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${user}</span> made payment of <span class="hljs-subst">${amountInDollars}</span>`</span>);
    }
}

<span class="hljs-keyword">let</span> store = <span class="hljs-keyword">new</span> Store(<span class="hljs-keyword">new</span> PayPalPaymentProcessor(<span class="hljs-string">'John Doe'</span>));
store.purchaseBook(<span class="hljs-number">2</span>, <span class="hljs-number">10</span>);
store.purchaseCourse(<span class="hljs-number">1</span>, <span class="hljs-number">15</span>);
</code></pre>
<p>You will also notice that this follows the Liskov Substitution Principle because you can replace it with other implementations of the same interface without breaking your application.</p>
<h2 id="heading-ta-da">Ta-Da 😇</h2>
<p>It's been an adventure🙃. I hope you noticed that each of these principles are related to the others in some way.</p>
<p>In an attempt to correct one principle, say the dependency inversion principle, you indirectly ensure that your classes are open to extension but closed to modification, for example.</p>
<p>You should keep these principles in mind when writing code, because they make it easier for many people to collaborate on your project. They simplify the process of extending, modifying, testing, and refactoring your code. So make sure you understand their definitions, what they do, and why you need them beyond OOP.</p>
<p>For more understanding, you can watch <a target="_blank" href="https://www.youtube.com/watch?v=XzdhzyAukMM">this video</a> by <a target="_blank" href="https://www.freecodecamp.org/news/author/beau/">Beau Carnes</a> on the <a target="_blank" href="https://www.youtube.com/c/Freecodecamp">freeCodeCamp YouTube channel</a> or read <a target="_blank" href="https://www.freecodecamp.org/news/solid-principles-explained-in-plain-english/">this article</a> by <a target="_blank" href="https://www.freecodecamp.org/news/author/erinc/">Yiğit Kemal Erinç</a>.</p>
<p>Have fun coding!</p>
<p>You can access over 200 of my articles by <a target="_blank" href="https://joelolawanle.com/contents">visiting my website</a>. You can also use the search field to see if I've written a specific article.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Design Principles – A List of the Principles of Design ]]>
                </title>
                <description>
                    <![CDATA[ When you start learning graphic design theory, you may be surprised to find out that there are specific rules you need to follow when designing. Those rules are known as design principles, and in this article, you will learn the basics of the 13 desi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/design-principles-a-list-of-the-principles-of-design/</link>
                <guid isPermaLink="false">66b1e3f296a9e0a75592bbb2</guid>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Dionysia Lemonaki ]]>
                </dc:creator>
                <pubDate>Mon, 02 May 2022 22:41:41 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/05/hal-gatewood-tZc3vjPCk-Q-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When you start learning graphic design theory, you may be surprised to find out that there are specific rules you need to follow when designing.</p>
<p>Those rules are known as design principles, and in this article, you will learn the basics of the 13 design principles.</p>
<p>Knowing what design principles are will give you a better understanding of how to go about creating more harmonious designs and better user experiences. </p>
<p>Here is what we will cover in this guide:</p>
<ol>
<li><a class="post-section-overview" href="#intro">What are design principles?</a></li>
<li><a class="post-section-overview" href="#list">The 13 principles of design</a><ol>
<li><a class="post-section-overview" href="#balance">Balance</a></li>
<li><a class="post-section-overview" href="#variety">Variety</a></li>
<li><a class="post-section-overview" href="#emphasis">Emphasis</a></li>
<li><a class="post-section-overview" href="#contrast">Contrast</a></li>
<li><a class="post-section-overview" href="#hierarchy">Hierarchy</a></li>
<li><a class="post-section-overview" href="#repetition">Repetition</a></li>
<li><a class="post-section-overview" href="#pattern">Pattern</a></li>
<li><a class="post-section-overview" href="#movement">Movement</a></li>
<li><a class="post-section-overview" href="#rhythm">Rhythm</a></li>
<li><a class="post-section-overview" href="#proportion">Proportion</a></li>
<li><a class="post-section-overview" href="#alignment">Alignment</a></li>
<li><a class="post-section-overview" href="#unity">Unity</a></li>
<li><a class="post-section-overview" href="#white-space">White space</a></li>
</ol>
</li>
</ol>
<h2 id="heading-what-are-design-principles">What Are Design Principles? <a></a></h2>
<p>Design principles are a strict set of rules. </p>
<p>Designers adhere to those rules to create pleasant user experiences and visually appealing end products.</p>
<p>These rules are tools and guidelines that help the designer create a sense of harmony and balance in their designs. </p>
<p>They guarantee usability and an overall pleasing effect for viewers and users.</p>
<h2 id="heading-the-13-principles-of-design">The 13 Principles Of Design <a></a></h2>
<h3 id="heading-balance">Balance <a></a></h3>
<p>Every design element on a page has a different weight, depending on its size, shape, or color. </p>
<p>That weight is known as <em>visual weight</em>.</p>
<p>Balance in design is how you arrange and position elements in a composition,  and it's about distributing the weight of those elements.</p>
<p>A composition lacking in balance means that one element overpowers all the rest.</p>
<p>To create balance, you need to position elements properly.</p>
<p>For example, this could be that an element on one side is much 'heavier' than the rest and is overpowering, thus making the design look unstable.</p>
<p>There are two types of balance:</p>
<ul>
<li>Symmetrical balance</li>
<li>Asymmetrical balance</li>
</ul>
<p>With <strong>Symmetrical balance</strong>, think of drawing an invisible, vertical line down the center of the page and splitting the page into two sides.</p>
<p>The items on both sides of the line have evenly distributed visual weight and create a mirrored image.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot-2022-04-27-at-7.10.01-PM.png" alt="Screenshot-2022-04-27-at-7.10.01-PM" width="600" height="400" loading="lazy"></p>
<p>The order, the position, and the alignment of elements are equal on both sides, creating consistency in the design.</p>
<p><strong>Asymmetrical balance</strong> is the opposite of symmetrical balance.</p>
<p>Elements on both sides have different arrangements, as they also have an order and positioning that varies in the composition. </p>
<p>Even though each side has a different visual weight, the overall design maintains an equal visual weight on both sides.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot-2022-04-27-at-7.31.01-PM.png" alt="Screenshot-2022-04-27-at-7.31.01-PM" width="600" height="400" loading="lazy"></p>
<p>There is no mirrored image, and both sides look different, but the design is still stable.</p>
<p>For example, asymmetrical design can be when three lighter elements stacked on top of one another on one side balance out one single heavier item on the opposite side.</p>
<p>Asymmetrical balance creates visual interest and adds a modern feel to the design.</p>
<h3 id="heading-variety">Variety <a></a></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot-2022-04-27-at-8.23.16-PM.png" alt="Screenshot-2022-04-27-at-8.23.16-PM" width="600" height="400" loading="lazy"></p>
<p>Variety creates visual interest and prevents the design from becoming monotonous and predictable. </p>
<p>Variety is created by using elements that are not similar to one another.</p>
<p>With the use of the variety, you have a good chance of maintaining the interest and engagement of viewers.</p>
<p>Variety in design is achieved with the use of many different things, a few of which are:</p>
<ul>
<li>Varying sizes,</li>
<li>Varying shapes,</li>
<li>Varying colors,</li>
<li>Varying textures,</li>
<li>Varying typography.</li>
</ul>
<h3 id="heading-emphasis">Emphasis <a></a></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot-2022-04-27-at-8.45.46-PM.png" alt="Screenshot-2022-04-27-at-8.45.46-PM" width="600" height="400" loading="lazy"></p>
<p>The purpose of emphasis is to create a focal point.</p>
<p>A focal point is an object that stands out instantly and grabs the viewer's or user's attention at first sight.</p>
<p>When there is an emphasis on a design element, it means that the specific object is highlighted from the rest and is therefore of great significance and importance.</p>
<p>For example, you can think of emphasis as some text with all-caps and a bold type.</p>
<p>Emphasis can be the main heading on a website. </p>
<p>It can also be a message of some kind. </p>
<p>You may want to convey something crucial or cautionary to your viewers and need to make sure that your audience is aware of it and focuses on that first. </p>
<p>Emphasis can also be a large button with a bright color under an item for purchase - this can act as a call to action for visitors.</p>
<p>It's what you want others to notice first - the essential information someone needs to be aware of and pay attention to upon first viewing your work.</p>
<p>It's a specific piece of content that needs to stand out from the rest of the design.</p>
<p>Besides text and color, emphasis is achieved with size, shape, weight, texture, and position, to name a few.</p>
<p>When creating emphasis, make sure that you do it without disturbing the overall balance of the composition and without creating an overpowering and jarring effect. </p>
<h3 id="heading-contrast">Contrast <a></a></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot-2022-04-28-at-10.46.00-AM.png" alt="Screenshot-2022-04-28-at-10.46.00-AM" width="600" height="400" loading="lazy"></p>
<p>While emphasis is about accentuating one single element, contrast has to do with the apparent, stand-out degree of difference between two or more design elements that are close together.</p>
<p>This difference can be that one element has a dark background color, and the other has a light one. </p>
<p>It can also be that one element has a cooler tone, whereas the other has a warmer tone. Or that one element is larger and the other is smaller in size. Or using a serif font on some text and a sans-serif text on another piece of text.</p>
<p>For example, take this webpage.</p>
<p>When browsing the page from a desktop computer or a laptop, you will see that at the top right corner, there are two buttons you can click on:</p>
<ul>
<li>the 'Forum' button has a dark background color that is the same as the rest of the navigation bar, <ul>
<li>the 'Donate' button has a bright yellow background color that makes it stand out. </li>
</ul>
</li>
</ul>
<p>That is considered contrast. There are two very different elements next to one another, but one catches the eye the most and demands your attention.</p>
<p>All-in-all, contrast highlights two totally opposing elements with highly different characteristics. The difference has to be a noticeable one.</p>
<p>There are different types of contrast, such as color contrast or size, shape, or texture contrast. </p>
<p>The purpose is to create variation and interest and therefore create focus and emphasis while maintaining balance in the design.</p>
<p>Good contrast goes hand in hand with accessibility best practices and creating usable products and services for everyone. It's necassary to take into consideration people with visual impairments.</p>
<p>Think of another example. </p>
<p>Say there is an element with a light grey background and some dark grey text. Then, there is another element with the same background color, but there is some black text. </p>
<p>Which one is easier to read? The second one with the black text.</p>
<p>There is a higher color contrast between the background color and  foreground (text) color. </p>
<p>There is a lack of contrast in the first element - this makes reading the text much harder.</p>
<h3 id="heading-hierarchy">Hierarchy <a></a></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot-2022-04-28-at-11.00.40-AM.png" alt="Screenshot-2022-04-28-at-11.00.40-AM" width="600" height="400" loading="lazy"></p>
<p>Hierarchy organizes visual elements in order of importance.</p>
<p>The role of hierarchy in design is to create a visual ranking system according to the logical priority of content. It helps guide viewers from the most important information to the least important by creating a logical flow and arrangement of that content.</p>
<p>Think of the typical order of elements on a webpage.</p>
<p>We read from top to bottom, so the viewer's eye must be first drawn immediately to essential information before they start scrolling down the page.</p>
<p>So this means that the crucial information needs to be at the top of the page - it needs to be the most prominent and rank the highest on the page.</p>
<p>Take the following example.</p>
<p>At the top of a  webpage, there is typically the company logo first.</p>
<p>Then, there is a navigation bar or dropdown menu, which helps users decide the area of the site they want to interact with. </p>
<p>There can also be a search bar for users to enter keywords to search for a specific topic and save time.</p>
<p>Then, there can be a call to action or the main heading that reinforces the purpose of the page and its content.</p>
<p>Then, there can be the main area that would contain a subheading with some text, then another subheading with more text, and so on. </p>
<p>This order creates visual organization and helps viewers distinguish what content appears to be the most important and deserves their attention. </p>
<p>It guides viewers from the start of the content to the end - from highest priority to least priority.</p>
<p>The position of elements signifies importance - the most important information is always higher on a page, whereas if something is at the bottom, it is not as important.</p>
<p>Other ways to create hierarchy in design are using colors to create contrast and alternate the sizing of elements in different ways.</p>
<p>Without hierarchy, all content would appear the same, and nothing would stand out and signal importance, which would lead to confusion for viewers.</p>
<h3 id="heading-repetition">Repetition <a></a></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot-2022-04-27-at-8.18.16-PM.png" alt="Screenshot-2022-04-27-at-8.18.16-PM" width="600" height="400" loading="lazy"></p>
<p>Repetition is when a specific element is repeated multiple times throughout the design.</p>
<p>The role of repetition in design is to create consistency and unity.</p>
<p>Repetition creates relationships and associations between seemingly separate and different elements and creates a bond between them - a common link that ties everything together.</p>
<p>To achieve repetition, you use the same particular color or the same color scheme multiple times throughout the design. </p>
<p>Or stick to a specific font type or use a recurring phrase throughout the page.</p>
<p>A commonly repeated element in designs is a logo, which plays a critical part in creating a brand identity. </p>
<p>A logo will make viewers and users familiar with the brand. They will recognize and distinguish its voice and tone from other brands. </p>
<p>Users will memorize and identify the logo with the company's vision and mission. </p>
<p>They will know what the brand is all about.</p>
<h3 id="heading-pattern">Pattern <a></a></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot-2022-04-28-at-3.25.07-PM.png" alt="Screenshot-2022-04-28-at-3.25.07-PM" width="600" height="400" loading="lazy"></p>
<p>Pattern at first glance appears to be very similar to repetition since it implies that elements reoccur multiple times throughout the page.</p>
<p>However, they have significant differences.</p>
<p>While repetition deals with the same element repeating throughout the design, a pattern focuses on multiple and different design elements repeating in the same way throughout the composition.</p>
<p>A pattern in design is all about the repetition of more than one element.</p>
<p>An example of a pattern in everyday life is floor tiles and wallpapers. </p>
<p>An example of a pattern on the web is the use of backgrounds in websites and applications to create harmony and a cohesive feel.</p>
<h3 id="heading-movement">Movement <a></a></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot-2022-04-28-at-11.24.24-AM.png" alt="Screenshot-2022-04-28-at-11.24.24-AM" width="600" height="400" loading="lazy">
Movement is how the eyes move when viewing and interacting with a composition.</p>
<p>Movement refers to the way the viewer's eye travels and the path it takes throughout a design.</p>
<p>The designer uses movement to guide the viewer around different design elements.</p>
<p>They create different focal areas for each point in time to effectively capture the viewer's attention, moving from one element to another in a well-thought-out directed sequence. </p>
<p>Typically, the viewer's eye first sees the most important element, then the second most important, then the third one, and so on.</p>
<p>An example of movement can be viewing a spiraling staircase when you are standing at the top - your eye will move along the different lines and edges.</p>
<p>Movement on the web can be created by:</p>
<ul>
<li>The use of animated effects, </li>
<li>The use of blurring effects,</li>
<li>The use of spiraling effects,</li>
<li>The use of lines and edges,</li>
<li>The use of different direction signs that provide guidance, indicating to the viewer to move their focus to the left, right, or look downwards or upwards.</li>
</ul>
<h3 id="heading-rhythm">Rhythm <a></a></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/04/Screenshot-2022-04-28-at-4.21.48-PM.png" alt="Screenshot-2022-04-28-at-4.21.48-PM" width="600" height="400" loading="lazy"></p>
<p>Rhythm involves the combination of repetition, variety, and movement.</p>
<p>Rhythm is how multiple design elements that are different from each other repeat in a particular order. </p>
<p>Repeating or alternating a group of different elements in the same order and at specific intervals is a way to create rhythm in design.</p>
<p>There are five different types of rhythm in design, depending on the type of interval:</p>
<ul>
<li>Random rhythm,</li>
<li>Regular rhythm,</li>
<li>Flowing rhythm,</li>
<li>Progressing rhythm,</li>
<li>Alternating rhythm.</li>
</ul>
<p>The elements follow a tempo and move and flow in an organized way.</p>
<p>It resembles the feeling of following a dance choreography or moving to the beat of some music.</p>
<p>Instead of bringing the attention to only one area of the design or guiding the viewer from one different part to another, rhythm focuses on moving the viewer's eyes across the whole composition.</p>
<h3 id="heading-proportion">Proportion <a></a></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Screenshot-2022-04-28-at-10.53.01-AM.png" alt="Screenshot-2022-04-28-at-10.53.01-AM" width="600" height="400" loading="lazy"></p>
<p>Proportion in design refers to the size and visual weight of two or more visual elements. </p>
<p>Proportion is also the relationship between those visual elements.</p>
<p>The relationship is based on size. It's how the size of one object compares and is correlated to the size of the other object.</p>
<p>Essentially, it is how elements scale in size in relation to each other.</p>
<p>For example, proportion compares and measures the importance of elements to one another.</p>
<p>Say there are two objects - one is bigger and the other is much smaller.</p>
<p>The bigger element will be more noticeable, which indicates that it is more important than the smaller one.</p>
<p>A well-proportioned design means that the size of all the elements preserves balance, unity, and harmony for the whole design.</p>
<p>Good proportion means that all elements relate well to each other.</p>
<h3 id="heading-alignment">Alignment <a></a></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Screenshot-2022-04-28-at-2.55.47-PM.png" alt="Screenshot-2022-04-28-at-2.55.47-PM" width="600" height="400" loading="lazy"></p>
<p>Alignment refers to how visual elements are lined up, ordered, and structured in comparison to one another and in comparison to the whole design.</p>
<p>It is a way to create a connection and visual flow between related objects and create a more unified result in the design.</p>
<p>By aligning the different visual objects, you help guide your viewer throughout the design. </p>
<p>The most common forms of alignment are left-aligned, right-aligned, and center-aligned. </p>
<h3 id="heading-unity">Unity <a></a></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Screenshot-2022-04-28-at-11.33.04-AM.png" alt="Screenshot-2022-04-28-at-11.33.04-AM" width="600" height="400" loading="lazy"></p>
<p>Unity in design is how different visual elements come together to create cohesion and completeness in the design and a harmonious effect.</p>
<p>With unity, seemingly different items create a sense of 'oneness'. This can be achieved in a few different ways.</p>
<p>For example, elements of different sizes can all have the same color and be near one another. </p>
<p>This makes them appear as if they belong together or as if they are related and are similar in some way.</p>
<h3 id="heading-white-space">White Space <a></a></h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/Screenshot-2022-04-28-at-2.22.45-PM.png" alt="Screenshot-2022-04-28-at-2.22.45-PM" width="600" height="400" loading="lazy"></p>
<p>White space is also known as <em>negative space</em>.</p>
<p>Essentially, white space refers to areas that <em>lack</em> visual elements, and areas with unused, empty space around already existing elements in a design.</p>
<p>White space doesn't necessarily mean that the empty space is white in color - it can be any color. It more so refers to the emptiness and available room in your design and the fact that some areas don't contain anything.</p>
<p>White space is about <em>not</em> adding any elements to the composition and takes a more minimalistic and simplistic approach to design. Sometimes, less is indeed more.</p>
<p>White space creates breathing room in the design.</p>
<p>When a lot is going on on a page, viewers can easily become overwhelmed with all the information they need to take in. White space helps to prevent that from happening. It makes any available text more readable and creates an all-around better user experience.</p>
<p>White space eliminates any unnecessary clutter and creates a focal point. So, use white space around important elements to make them stand out.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Hopefully, now you have a high-level understanding of design principles and have a better idea of how to implement them in your future designs.</p>
<p>Thanks for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Open-Closed Principle – The Software Development Concept Explained in Plain English ]]>
                </title>
                <description>
                    <![CDATA[ There are many articles about the Open-Closed Principle, but I can never find one that explains it in a way that really works for me.  So here, hopefully, is a good one – with a non trivial and real life example, what changes to support, and a descri... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/open-closed-principle/</link>
                <guid isPermaLink="false">66bb926e0eaca026d8cfa5f4</guid>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design patterns ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Cedd Burge ]]>
                </dc:creator>
                <pubDate>Mon, 27 Sep 2021 19:43:06 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/09/IMG_8905.JPG" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>There are many articles about the Open-Closed Principle, but I can never find one that explains it in a way that really works for me. </p>
<p>So here, hopefully, is a good one – with a non trivial and real life example, what changes to support, and a description of the trade offs.</p>
<p>The Open-Closed principle states that code should be "Open for extension" and "Closed for modification". </p>
<p>There is <a target="_blank" href="https://codeblog.jonskeet.uk/2013/03/15/the-open-closed-principle-in-review/">quite a lot of confusion about the term</a>, but essentially it means that if you want to implement a <em>supported</em> change, you should be able to do it without changing the code in a large number of places. Ideally, you can implement the new feature just by adding new code, and changing little or no old code, which makes the code easier to develop and maintain. </p>
<p>Open is the 'O' in the <a target="_blank" href="https://www.freecodecamp.org/news/solid-principles-explained-in-plain-english/">SOLID design principles</a>, which are probably the most famous guides for writing high quality code.</p>
<p>No useful code can ever be completely open to all possible changes, so we have to decide which changes we are going to <em>support</em>. When writing our code we can think about what the potential changes might be, decide which ones to <em>support</em>, and then make the code 'open' to these. </p>
<p>We can create a list of these potential changes by:</p>
<ul>
<li>Analysing the code</li>
<li>Looking at previous changes to the code</li>
<li>Using our experience of commonly requested changes</li>
<li>Using any knowledge of upcoming feature requests</li>
</ul>
<p>Take a minute to look at the code below (<a target="_blank" href="https://github.com/ceddlyburge/open-closed-principle/blob/master/OpenClosedPrinciple/Original/GrossToNetCalculator.cs">and on GitHub</a>) and think about what changes we might expect. You don't have access to the commit history, or any knowledge of upcoming feature requests, but you can still probably come up with some likely candidates.</p>
<pre><code class="lang-csharp=">public class GrossToNetCalculator
{
    public GrossToNetCalculator(
        IGrossEnergyYield grossYield,
        double grossEnergy,
        double hysteresisLoss,
        double curtailmentLossGrid,
        double turbineLossTurbulence,
        double electricalLoss,
        double turbineLossShear,
        double turbinePerformanceExperience,
        double operationalExperienceLoss)
    {
        double dependentLoss = 
            CombinePercentages(
                grossYield.TurbineAvailability,
                grossYield.BalanceAvailability,
                grossYield.AccessibilityAvailability,
                hysteresisLoss,
                electricalLoss,
                grossYield.EnvironmentalShutdownWeather,
                grossYield.EnvironmentalSiteAccess,
                grossYield.EnvironmentTreeGrowth);

        double independentLoss = 
            CombinePercentages(
                grossYield.GridAvailability,
                turbinePerformanceExperience,
                turbineLossTurbulence,
                grossYield.EnvironmentalPerformanceDegradationIcing,
                grossYield.CurtailmentPowerPurchase,
                grossYield.SubOptimalPerformance,
                turbineLossShear,
                operationalExperienceLoss);

        GrossToNet = 
            1 - 
            (1 - (dependentLoss + curtailmentLossGrid))
            * (1 - independentLoss);
    }

    double CombinePercentages(params double[] percentages)
    {
        double combination = 1;
        foreach (var percentage in percentages)
            combination *= 1 - percentage;
        return 1 - combination;
    }

    public double GrossToNet { get; private set; }
}
</code></pre>
<p>This code is relatively simple, and when I look at it these are the potential changes that I see:</p>
<ul>
<li>Items could be added or removed from the <code>dependentLoss</code> and <code>independentLoss</code> calculations. Items could be also be moved between <code>dependentLoss</code> and <code>independentLoss</code>, but this is essentially the same thing</li>
<li>The calculation of <code>GrossToNet</code> could change</li>
<li>The <code>CombinePercentages</code> calculation could change</li>
</ul>
<p>As with most things in computer programming, there is a tension when applying the Open-Closed Principle. </p>
<p>On the one hand, making the code more easily extensible is good. On the other hand, doing this often breaks encapsulation, adds complication, and adds unnecessary levels of abstraction. </p>
<p>So again, we need to make a decision about which of these changes we want to support and make the code 'open to'<em>.</em> We can then avoid adding unnecessary complication to the code for unsuitable changes. </p>
<p>It is worth remembering that the work can always be done later, when it will be easier, as we will know exactly what is required.</p>
<p>To make a decision about what changes we should support and make the code 'open to',  we need to estimate how likely the change is to occur, think about design solutions, and then think about the trade offs.</p>
<h2 id="heading-we-could-add-or-remove-items-from-the-dependentloss-and-independentloss-calculations">We Could Add or Remove Items from the dependentLoss and independentLoss Calculations</h2>
<h3 id="heading-ia"> </h3>
<p>Very likely to change</p>
<p>The calculation of <code>dependentLoss</code> and <code>independentLoss</code> (for example <code>double dependentLoss = CombinePercentages(...)</code>) each use 8 parameters (<code>electricalLoss</code>, <code>TurbineAvailability</code> and so on).</p>
<p>These 16 make up the majority of the 17 total inputs to the entire calculation. So, from a purely statistical point of view, a change to one of these has a 16/17 (94%) chance of affecting these calculations.</p>
<p>It's also easy to imagine that we might want to add another "Loss" or "Availability" or similar in the future, or that a current one is no longer relevant, or that different combinations will be required in different circumstances.</p>
<h3 id="heading-possible-solution">Possible solution</h3>
<p>Take a list of dependent and independent losses in the constructor, instead of taking each loss individually. So the existing constructor:</p>
<pre><code class="lang-csharp=">public GrossToNetCalculator(
    ...
    double hysteresisLoss,
    double curtailmentLossGrid,
    ...)
</code></pre>
<p>is replaced with this:</p>
<pre><code class="lang-csharp=">public GrossToNetCalculator(
    IReadOnlyList&lt;double&gt; dependentLosses
    IReadOnlyList&lt;double&gt; independentLosses)
</code></pre>
<p>This means that if the change is requested, we can implement it without changing the class (and instead just changing the parameters we pass to the constructor). </p>
<p>For example, if another 'dependentLoss' is requested, we can just add this to the <code>dependentLosses</code> list.</p>
<p>(You can see the <a target="_blank" href="https://github.com/ceddlyburge/open-closed-principle/tree/master/OpenClosedPrinciple/ListParameters">code on GitHub here</a>)</p>
<h3 id="heading-trade-offs">Trade offs</h3>
<p>A small amount of encapsulation is lost, and the calling code would now be in charge of deciding which losses to pass in.</p>
<p>The code adheres much better to the Open-Closed Principle and becomes much more easily extendable and reusable. If you need to make a change, you won't need to modify the tests, which is useful as they are complicated. </p>
<p>Tests for the calling code would have to modified, but only to verify that they pass the correct parameters, which is much simpler. </p>
<p>It is possible that the constructor parameters are passed around in the code base, and now there are only two parameters, as opposed to the previous nine.</p>
<h3 id="heading-decision">Decision</h3>
<p>We should implement this solution to support this change and make the code 'open' to it. </p>
<h2 id="heading-the-grosstonet-calculation-could-change">The GrossToNet Calculation Could Change</h2>
<h3 id="heading-ia-1"> </h3>
<p>Unlikely to change</p>
<p>The GrossToNet calculation is <code>GrossToNet = 1 - (1 - (dependentLoss + curtailmentLossGrid)) * (1 - independentLoss);</code></p>
<p>Only the <code>curtailmentLossGrid</code> parameter is used, aside from the <code>dependentLoss</code> and <code>independentLoss</code> which are covered earlier.</p>
<p>This 1 parameter is a small minority of the 17 total inputs to the entire calculation. So, from a purely statistical point of view, a change to one of these has a 1/17 (6%) chance of affecting this calculation.</p>
<h3 id="heading-possible-solutions">Possible solutions</h3>
<ol>
<li>Take a lambda parameter in the constructor to calculate <code>GrossToNet</code> and pass it <code>dependentLoss</code> and <code>independentLoss</code>, so that the calculation becomes <code>GrossToNet = grossToNetCalculatorLambda(dependentLoss, independentLoss)</code>(<a target="_blank" href="https://github.com/ceddlyburge/open-closed-principle/tree/master/OpenClosedPrinciple/GrossToNetLambda">code on GitHub</a>)</li>
<li>Remove <code>curtailmentLossGrid</code> from the calculation, which then becomes completely generic and can be renamed to <code>PercentageCombiner</code>. Require that the calling code applies this adjustment (this adjustment is too complicated for useful example code)</li>
<li>Remove <code>curtailmentLossGrid</code> from the calculation as above, then recreate the original <code>GrossToNetCalculator</code>, using the <code>PercentageCombiner</code> and adding <code>curtailmentLossGrid</code> to the calculation<br>(<a target="_blank" href="https://github.com/ceddlyburge/open-closed-principle/tree/master/OpenClosedPrinciple/PercentageCombiner">code on GitHub</a>)</li>
</ol>
<h3 id="heading-trade-offs-1">Trade Offs</h3>
<p>A large amount of encapsulation is lost for options 1 and 2. Option 3 is a reasonable amount of work, and adds a layer of abstraction.</p>
<h3 id="heading-decision-1">Decision</h3>
<p>This change isn't likely to happen, so it probably isn't worth the effort involved to support it and make the code 'open' to it. But if we had another use for the new <code>PercentageCombiner</code> then it would definitely be worthwhile.</p>
<h2 id="heading-the-combinepercentages-calculation-could-change">The CombinePercentages Calculation Could Change</h2>
<h3 id="heading-ia-2"> </h3>
<p>Very unlikely to change</p>
<pre><code class="lang-csharp=">CombinePercentages(params double[] percentages)
{
    double combination = 1;
    foreach (var percentage in percentages)
    combination *= 1 - percentage;
    return 1 - combination;
}
</code></pre>
<p>The CombinePercentages calculation implements some standard laws of math / statistics, which do not change.</p>
<h3 id="heading-possible-solutions-1">Possible solutions</h3>
<ol>
<li>Take a lambda parameter in the constructor to combine the percentages, and use this instead of the CombinePercentages function. So instead of having <code>double dependentLoss = CombinePercentages(...)</code>, you would have  <code>double dependentLoss = combinePercentagesLambda(...)</code>.<br>(<a target="_blank" href="https://github.com/ceddlyburge/open-closed-principle/tree/master/OpenClosedPrinciple/CombinePercentagesLambda">code on GitHub</a>)</li>
<li>Create a <code>PercentageCombiner</code> abstraction, take this in the constructor to combine the percentages, and use this instead of the CombinePercentages function. So instead of having <code>double dependentLoss = CombinePercentages(...)</code>, you would have <code>double dependentLoss = percentageCombiner.CombinePercentages(...)</code>.<br>(<a target="_blank" href="https://github.com/ceddlyburge/open-closed-principle/tree/master/OpenClosedPrinciple/PercentageCombinerAbstraction">code on GitHub</a>)</li>
</ol>
<h3 id="heading-trade-offs-2">Trade offs</h3>
<p>Combining percentages is at the heart of what this code does, so removing this logic makes the code mostly useless. </p>
<p>Option 1 passes all the responsibility for this on to the caller, whereas option 2 at least allows for predefined implementations of the abstraction.</p>
<h3 id="heading-decision-2">Decision</h3>
<p>This change is very unlikely, and the only reasonable solution (option 2) requires a lot of work and adds complexity and abstraction. </p>
<p>This means that it would only make sense to do it when the change is actually required, and even then only if multiple algorithms are required. Note that if a change is required to the algorithm, it will make more sense to simply change the implementation of the CombinePercentages function.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Deciding whether code adheres to the Open-Closed Principle is almost always a judgement call, and there are usually trade offs involved with encapsulation, complexity and abstraction. </p>
<p>It is worth thinking about likely changes and extensions, and using these to guide your decisions.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Model View Controller Pattern – MVC Architecture and Frameworks Explained ]]>
                </title>
                <description>
                    <![CDATA[ The MVC architecture pattern turns complex application development into a much more manageable process. It allows several developers to simultaneously work on the application. When I first learned about MVC patterns, I was intimidated by all the jarg... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-model-view-controller-pattern-mvc-architecture-and-frameworks-explained/</link>
                <guid isPermaLink="false">66bae5f5fea3aa95c7620fad</guid>
                
                    <category>
                        <![CDATA[ design patterns ]]>
                    </category>
                
                    <category>
                        <![CDATA[ programing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design patterns ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Rafael D. Hernandez ]]>
                </dc:creator>
                <pubDate>Mon, 19 Apr 2021 14:13:49 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/04/BG.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The MVC architecture pattern turns complex application development into a much more manageable process. It allows several developers to simultaneously work on the application.</p>
<p>When I first learned about MVC patterns, I was intimidated by all the jargon. And even more so when I started applying these concepts to an actual application.</p>
<p>By taking a step back to focus on what MVC is and what it can accomplish, it's much easier to understand and apply the pattern to any web application.</p>
<h2 id="heading-what-is-mvc">What is MVC?</h2>
<p>MVC stands for model-view-controller. Here's what each of those components mean:</p>
<ul>
<li><strong>Model</strong>: The backend that contains all the data logic</li>
<li><strong>View</strong>: The frontend or graphical user interface (GUI)</li>
<li><strong>Controller</strong>: The brains of the application that controls how data is displayed</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/MVC3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The concept of MVCs was first introduced by Trygve Reenskaug, who proposed it as a way to develop desktop application GUIs.</p>
<p>Today the MVC pattern is used for modern web applications because it allows the application to be scalable, maintainable, and easy to expand.</p>
<h2 id="heading-why-should-you-use-mvc">Why Should You Use MVC?</h2>
<p>Three words: <strong>separation of concerns</strong>, or SoC for short.</p>
<p>The MVC pattern helps you break up the frontend and backend code into separate components. This way, it's much easier to manage and make changes to either side without them interfering with each other. </p>
<p>But this is easier said than done, especially when several developers need to update, modify, or debug a full-blown application simultaneously.</p>
<h2 id="heading-how-to-use-mvc">How to Use MVC</h2>
<p>To better illustrate the MVC pattern, I've included a web application that shows how these concepts all work.</p>
<p>My Car Clicker application is a variation of a well-known Cat Clicker app.</p>
<p>Here are some of the major differences in my app:</p>
<ol>
<li>No cats, <strong>only</strong> muscle cars images (sorry cat lovers!)</li>
<li>Multiple car models are listed</li>
<li>There are multiple click counters</li>
<li>It only displays the selected car</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/Screen-Recording-2021-04-11-at-11.31.27.07-PM.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now let's dive into these three components that make up the MVC architecture pattern.</p>
<h3 id="heading-model-data">Model (data)</h3>
<p>The model's job is to simply manage the data. Whether the data is from a database, API, or a JSON object, the model is responsible for managing it.</p>
<p>In the Car Clicker application, the model object contains an array of car objects with all the information (data) needed for the app.</p>
<p>It also manages the current car being displayed with a variable that's initially set to <code>null</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> model = {
    <span class="hljs-attr">currentCar</span>: <span class="hljs-literal">null</span>,
    <span class="hljs-attr">cars</span>: [
        {
            <span class="hljs-attr">clickCount</span>: <span class="hljs-number">0</span>,
            <span class="hljs-attr">name</span>: <span class="hljs-string">'Coupe Maserati'</span>,
            <span class="hljs-attr">imgSrc</span>: <span class="hljs-string">'img/black-convertible-coupe.jpg'</span>,
        },
        {
            <span class="hljs-attr">clickCount</span>: <span class="hljs-number">0</span>,
            <span class="hljs-attr">name</span>: <span class="hljs-string">'Camaro SS 1LE'</span>,
            <span class="hljs-attr">imgSrc</span>: <span class="hljs-string">'img/chevrolet-camaro.jpg'</span>,
        },
        {
            <span class="hljs-attr">clickCount</span>: <span class="hljs-number">0</span>,
            <span class="hljs-attr">name</span>: <span class="hljs-string">'Dodger Charger 1970'</span>,
            <span class="hljs-attr">imgSrc</span>: <span class="hljs-string">'img/dodge-charger.jpg'</span>,
        },
        {
            <span class="hljs-attr">clickCount</span>: <span class="hljs-number">0</span>,
            <span class="hljs-attr">name</span>: <span class="hljs-string">'Ford Mustang 1966'</span>,
            <span class="hljs-attr">imgSrc</span>: <span class="hljs-string">'img/ford-mustang.jpg'</span>,
        },
        {
            <span class="hljs-attr">clickCount</span>: <span class="hljs-number">0</span>,
            <span class="hljs-attr">name</span>: <span class="hljs-string">'190 SL Roadster 1962'</span>,
            <span class="hljs-attr">imgSrc</span>: <span class="hljs-string">'img/mercedes-benz.jpg'</span>,
        },
    ],
};
</code></pre>
<h3 id="heading-views-ui">Views (UI)</h3>
<p>The view's job is to decide what the user will see on their screen, and how.</p>
<p>The Car Clicker app has two views: <code>carListView</code> and <code>CarView</code>.</p>
<p>Both views have two critical functions that define what each view wants to initialize and render.</p>
<p>These functions are where the app decides what the user will see and how.</p>
<h4 id="heading-carlistview">carListView</h4>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> carListView = {
    init() {
        <span class="hljs-comment">// store the DOM element for easy access later</span>
        <span class="hljs-built_in">this</span>.carListElem = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'car-list'</span>);

        <span class="hljs-comment">// render this view (update the DOM elements with the right values)</span>
        <span class="hljs-built_in">this</span>.render();
    },

    render() {
        <span class="hljs-keyword">let</span> car;
        <span class="hljs-keyword">let</span> elem;
        <span class="hljs-keyword">let</span> i;
        <span class="hljs-comment">// get the cars to be render from the controller</span>
        <span class="hljs-keyword">const</span> cars = controller.getCars();

        <span class="hljs-comment">// to make sure the list is empty before rendering</span>
        <span class="hljs-built_in">this</span>.carListElem.innerHTML = <span class="hljs-string">''</span>;

        <span class="hljs-comment">// loop over the cars array</span>
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; cars.length; i++) {
            <span class="hljs-comment">// this is the car we've currently looping over</span>
            car = cars[i];

            <span class="hljs-comment">// make a new car list item and set its text</span>
            elem = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'li'</span>);
            elem.className = <span class="hljs-string">'list-group-item d-flex justify-content-between lh-condensed'</span>;
            elem.style.cursor = <span class="hljs-string">'pointer'</span>;
            elem.textContent = car.name;
            elem.addEventListener(
                <span class="hljs-string">'click'</span>,
                (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">carCopy</span>) </span>{
                    <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
                        controller.setCurrentCar(carCopy);
                        carView.render();
                    };
                })(car)
            );
            <span class="hljs-comment">// finally, add the element to the list</span>
            <span class="hljs-built_in">this</span>.carListElem.appendChild(elem);
        }
    },
};
</code></pre>
<h4 id="heading-carview">CarView</h4>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> carView = {
    init() {
        <span class="hljs-comment">// store pointers to the DOM elements for easy access later</span>
        <span class="hljs-built_in">this</span>.carElem = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'car'</span>);
        <span class="hljs-built_in">this</span>.carNameElem = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'car-name'</span>);
        <span class="hljs-built_in">this</span>.carImageElem = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'car-img'</span>);
        <span class="hljs-built_in">this</span>.countElem = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'car-count'</span>);
        <span class="hljs-built_in">this</span>.elCount = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'elCount'</span>);


        <span class="hljs-comment">// on click, increment the current car's counter</span>
        <span class="hljs-built_in">this</span>.carImageElem.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-built_in">this</span>.handleClick);

        <span class="hljs-comment">// render this view (update the DOM elements with the right values)</span>
        <span class="hljs-built_in">this</span>.render();
    },

    handleClick() {
        <span class="hljs-keyword">return</span> controller.incrementCounter();
    },

    render() {
        <span class="hljs-comment">// update the DOM elements with values from the current car</span>
        <span class="hljs-keyword">const</span> currentCar = controller.getCurrentCar();
        <span class="hljs-built_in">this</span>.countElem.textContent = currentCar.clickCount;
        <span class="hljs-built_in">this</span>.carNameElem.textContent = currentCar.name;
        <span class="hljs-built_in">this</span>.carImageElem.src = currentCar.imgSrc;
        <span class="hljs-built_in">this</span>.carImageElem.style.cursor = <span class="hljs-string">'pointer'</span>;
    },
};
</code></pre>
<h3 id="heading-controller-brain">Controller (Brain)</h3>
<p>The controller's responsibility is to pull, modify, and provide data to the user. Essentially, the controller is the link between the view and model.</p>
<p>Through getter and setter functions, the controller pulls data from the model and initializes the views.</p>
<p>If there are any updates from the views, it modifies the data with a setter function.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> controller = {
    init() {
        <span class="hljs-comment">// set the current car to the first one in the list</span>
        model.currentCar = model.cars[<span class="hljs-number">0</span>];

        <span class="hljs-comment">// tell the views to initialize</span>
        carListView.init();
        carView.init();
    },

    getCurrentCar() {
        <span class="hljs-keyword">return</span> model.currentCar;
    },

    getCars() {
        <span class="hljs-keyword">return</span> model.cars;
    },

    <span class="hljs-comment">// set the currently selected car to the object that's passed in</span>
    setCurrentCar(car) {
        model.currentCar = car;
    },

    <span class="hljs-comment">// increment the counter for the currently-selected car</span>
    incrementCounter() {
        model.currentCar.clickCount++;
        carView.render();
    },
};

<span class="hljs-comment">// Let's goooo!</span>
controller.init();
</code></pre>
<h2 id="heading-mvc-frameworks">MVC Frameworks</h2>
<p>JavaScript has grown in popularity, and it's taken over the backend in recent years. More and more full-blown JavaScript applications have opted for the MVC architecture pattern in one way or another.</p>
<p>Frameworks come and go, but what has been constant are the concepts borrowed from the MVC architecture pattern.</p>
<p>Some of the early frameworks that applied these concepts were <strong>KnockoutJS</strong>, <strong>Django</strong>, and <strong>Ruby on Rails.</strong></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The most attractive concept of the MVC pattern is separation of concerns.</p>
<p>Modern web applications are very complex, and making a change can sometimes be a big headache.</p>
<p>Managing the frontend and backend in smaller, separate components allows for the application to be scalable, maintainable, and easy to expand.</p>
<p><em><strong>If you want to take a look at the Car Clicker app, the code is available on <a target="_blank" href="https://github.com/RafaelDavisH/car-clicker/blob/main/README.md">GitHub</a> or checkout the live version <a target="_blank" href="https://rafaeldavish.github.io/car-clicker/">here</a>.</strong></em> </p>
<p>🌟Thank you for reading this far!🌟</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How I Redesigned Clubhouse, Silicon Valley’s Buzziest app ]]>
                </title>
                <description>
                    <![CDATA[ By Amy Lima I wanted to test my limits as a young designer by improving the user experience of Clubhouse, the hottest new audio conversation app on the social media scene.  After speaking with both power users and novices on the app, I uncovered some... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-i-redesigned-clubhouse/</link>
                <guid isPermaLink="false">66d45d9836c45a88f96b7caf</guid>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ designer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ux design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 02 Feb 2021 22:03:37 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/02/clubhouse-product-image-work.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Amy Lima</p>
<p>I wanted to test my limits as a young designer by improving the user experience of Clubhouse, the hottest new audio conversation app on the social media scene. </p>
<p>After speaking with both power users and novices on the app, I uncovered some specific pain points with wayfinding and discoverability in the app. These became the primary design challenges that guided my work throughout this project.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/onboarding-mockups.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Onboarding Mockups</em></p>
<p><strong>Disclaimer</strong>: I do not work for Clubhouse, and the views in this case study are strictly my own. </p>
<p>As a budding designer, I acknowledge that my vision for this project may be overly ambitious and at times reliant on assumptions of business goals and user data. </p>
<p>In a perfect world, I’d be working alongside the Clubhouse team with direct access to these resources to guide my work. Until then, this case study is meant to be an exploratory learning experience on a product I deeply admire.</p>
<h2 id="heading-the-brief">The Brief</h2>
<p>It’s difficult to understate the excitement around <strong>Clubhouse,</strong> the audio chat app where members can move around virtual rooms discussing topics ranging from culture to politics. </p>
<p>The app raised its first <a target="_blank" href="https://www.forbes.com/sites/alexkonrad/2020/05/15/andreessen-horowitz-wins-vc-sweepstakes-to-back-clubhouse-voice-app/?sh=57e5f3bd6f2a">$100 million</a> with only 1,500 users a month after its beta release. And at the time of this writing, Silicon Valley’s buzziest app has just been valued at <a target="_blank" href="https://fortune.com/2021/01/25/clubhouse-reaches-a-1-billion-after-taking-off-some-nine-months-ago/">$1 billion</a> dollars, a mere 9 months after taking off and before even launching to the public.</p>
<p>Beyond its success with investors, Clubhouse has amassed a fiercely loyal user base, whose creativity has spanned from a 24-hour continuous room dedicated to new user onboarding to a live production of <a target="_blank" href="https://www.complex.com/pop-culture/2020/12/clubhouse-users-organize-live-production-the-lion-king">The Lion King.</a></p>
<p>As an early beta user on the invite-only platform, I had the unique perspective of following the product’s updates (and exponential success) in real-time. And I sought to challenge myself with my most ambitious project yet: redesigning Silicon Valley’s most exciting app in recent memory. <em>No pressure.</em></p>
<p>The high-level goals of this project were:</p>
<ul>
<li><strong>Improving discoverability within Clubhouse</strong>, allowing users to more easily find new rooms, people, and clubs to engage with</li>
<li><strong>Creating a more seamless Hallway experience,</strong> where users can filter and find the most relevant rooms to them</li>
</ul>
<h2 id="heading-ux-challenges-simplifying-a-complex-information-hierarchy">UX Challenges: Simplifying a complex information hierarchy</h2>
<p>One of the main considerations I had to take into account was the hierarchy of the main components users can interact with inside the app:</p>
<ul>
<li><strong>People</strong> (other users of the app)</li>
<li><strong>Rooms</strong> (a virtual meeting place for audio conversations), and</li>
<li><strong>Clubs</strong> (interest-based groups that rooms can be hosted under).</li>
</ul>
<p>Beyond this, <strong>I had to consider how each of these components were connected,</strong> both interpersonally and through time. </p>
<p>Currently, a Clubhouse user’s Hallway (home screen) shows <em>live</em> rooms connected to the people and clubs they follow (which I’ll refer to throughout this case study as “in-network”). This makes it difficult for users to easily keep track of upcoming rooms in their network, as well as join new, out-of-network rooms.</p>
<p><strong>This became a major dichotomy throughout my work:</strong> I needed to find a balance between making each of these individual parts of Clubhouse easily discoverable while maintaining – and simplifying – the web that weaves them together.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/ch-task-flow.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Discovery task flow</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/ch-sketch.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Mind map of the relationship between Clubhouse components</em></p>
<h2 id="heading-research-planning-a-ux-researchers-dream">Research + Planning: A UX Researcher’s Dream</h2>
<p>Another unique aspect of this project was the <strong>direct access beta users have to the Clubhouse founders,</strong> Paul Davison and Rohan Seth. Every Sunday, the pair host Clubhouse Townhall, an open forum where they share the week’s latest product updates, their upcoming roadmap, business goals, and top priorities, as well as holding space for user-submitted Q&amp;As.</p>
<p>And thanks to Clubhouse’s enthusiastic user base, the official Townhalls are regularly followed by Townhall recap rooms (shoutout to Community Club), where power users would deep dive into the week’s updates and what features they’re most excited for.</p>
<p>Between Clubhouse Townhalls, recap rooms, and both official and community-run new member onboarding rooms (including FAQs, Q&amp;As, and discussions), <strong>I spent on average 5 hours a week for 6 weeks gaining as many business insights and goals as I possibly could</strong> from my limited vantage point.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/clubhouse-research-screenshots.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>A compilation of some of the rooms that became a regular part of my UX Research</em></p>
<p>From these discussions, the overarching goals of the Clubhouse team are:</p>
<ul>
<li><strong>Making Clubhouse accessible for everyone:</strong> Paul always made it clear that the team’s top priority was to scale Clubhouse as quickly as possible while not sacrificing quality</li>
<li><strong>Putting creators first:</strong> another point Paul never understated was the team’s prioritization of the platform’s creators, building tools that would allow for creator monetization</li>
<li><strong>Improving discoverability and suggested content:</strong> at the time of this project, Clubhouse was actively building out their topics directory and algorithms that would make finding relevant rooms progressively easier</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/clubhouse-sketches.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Early sketches of how different screens might behave</em></p>
<h2 id="heading-user-interviews-from-power-users-to-newbies">User Interviews, from power users to newbies</h2>
<p>I spoke with Clubhouse users — both power users and more casual community members — to uncover friction points they currently had with the app’s discovery experience. These interviews showed gave me the following insights:</p>
<ul>
<li><strong>Keep it lightweight:</strong> most users preferred room discovery to be a spontaneous experience, not necessarily wanting to schedule upcoming rooms in their personal calendars</li>
<li><strong>Cluttered Hallway:</strong> most users were confused by how the hallway was currently curated, and who of the people they followed were in any given room present</li>
<li><strong>Hallway as a source of discovery:</strong> despite the cluttered hallway experience, most users still relied on the hallway to find new rooms, despite there being an existing (but not yet robust) “Explore” tab</li>
<li><strong>Friends first:</strong> when deciding which rooms to join in the hallway, users unanimously wanted to see which of their friends were in any given room</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/affinity-map--1-.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Affinity map of my user interviews (made using Evolve)</em></p>
<p>So how might we make the Hallway a clear and concise place for spontaneous interaction, while facilitating lightweight out-of-network discovery?</p>
<h2 id="heading-ux-solution-streamlining-the-discovery-to-hallway-pipeline">UX Solution: Streamlining the Discovery-to-Hallway pipeline</h2>
<p>I developed a simple yet powerful UI that makes wayfinding within your hallway and rooms easier. It also makes bringing rooms found through the discover page into your hallway a breeze.</p>
<p>In order for this solution to feel cohesive and not siloed, <strong>I needed to implement a near-full redesign of Clubhouse,</strong> broken up into 5 main experiences.</p>
<p><em>Play with the final prototype</em> <a target="_blank" href="https://www.figma.com/proto/zZ7KUnIt9Hrw27IKiXJfEo/CH-wireframes?node-id=263%3A257&amp;scaling=scale-down"><em>here</em></a><em>.</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/clubhouse-wireframes.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Early Wireframes</em></p>
<h2 id="heading-experience-1-the-hallway">Experience 1: The Hallway</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/ch-hallway-before-after.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>The Clubhouse Hallway currently (left), and reoptimized for more functionalities and access to controls (right)</em></p>
<p>Users wanted their hallway experience to feel more intentional and within their control. To achieve this, I established a top-level hierarchy of:</p>
<ul>
<li><strong>ongoing vs. upcoming</strong>, to allow users to not only see active rooms but get a quick overview of scheduled rooms within their network</li>
<li><strong>filters by topics of interest,</strong> selected by the user during onboarding, and</li>
<li><strong>sort rooms in your hallway</strong> by people vs clubs you follow</li>
</ul>
<p>An additional UI decision was to only present people you follow within the rooms in your hallway. This would alleviate the current issue of ambiguity surrounding the names users currently see in the room cards in their hallways.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/hallway-recording-1-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Navigating the reimagined Hallway</em></p>
<h2 id="heading-experience-2-room-preview">Experience 2: Room preview</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/room-preview-recording-2-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Room preview in action, where users can see a full list of which friends are inside any given room</em></p>
<p>Currently in Clubhouse, clicking on a room in a hallway immediately drops you into that room’s conversation.</p>
<p>Since identifying friends in any given room was a high decision factor for users joining a room, I wanted to design a way for users to see whom they know inside before committing to join.</p>
<h2 id="heading-experience-3-discovery">Experience 3: Discovery</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/ch-explore-page-before-and-after--1-.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Clubhouse’s Explore tab currently (left), and redesigned as an immersive discovery experience (right)</em></p>
<p><strong>Currently, discovery in Clubhouse is siphoned:</strong> users go to the Explore tab to discover people and clubs by categories and keywords, and they go to the calendar tab to discover both active and upcoming rooms across all of Clubhouse.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/ch-save-room-page-after.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Bringing a room to your hallway via Clubhouse’s Calendar tab currently (left), and reimagined as a simple bottom sheet function (right)</em></p>
<p><strong>Most participants actually didn’t use these tabs to achieve their primary goal of discovery</strong>. Instead, they adopted workarounds such as discovering clubs through user profiles, discovering people through rooms, and discovering rooms primarily through their hallway, limiting the scope of content they were being exposed to.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/discovery-filter-recording-1-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>An immersive discovery experience with rich filter and sort options</em></p>
<p>While I designed UI solutions to make these workarounds more seamless, I wanted the discover page to be the go-to destination to accommodate for all these use cases, allowing users to search for people, clubs, and rooms by Clubhouse’s growing topics directory, in addition to keywords.</p>
<p>I also integrated an additional sort functionality to further facilitate discovery.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/discovery-recording-1-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Sending an out-of-network room to your Hallway</em></p>
<p>Users also wanted an easy, lightweight solution to discover and access out-of-network rooms.</p>
<p>The ability to send a room from the discover feed to your hallway without committing to following that room’s moderators, corresponding club, or scheduling in your personal calendar was the biggest challenge of this project, involving many iterations in order to feel intuitive.</p>
<h2 id="heading-experience-4-active-users">Experience 4: Active Users</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/ch-active-users-before-after.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Clubhouse “Available to Chat” flyout currently (left), and reimagined as an “Online Now” tab (right)</em></p>
<p>A close cousin to the hallway, your active users screen is where all your Clubhouse people and clubs that are currently online live. <strong>83% of users interviewed mentioned scanning this screen to quickly identify what rooms their friends were in.</strong></p>
<p>I added a much-requested search bar to further facilitate friend-finding, as well as a sort drop-down menu to reach an even more important distinction: who’s actively participating in a room vs. just listening in.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/active-users-recording-1-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Discovering active users by different sort options</em></p>
<h2 id="heading-experience-5-user-and-club-profiles">Experience 5: User and Club Profiles</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/club-prof-before-after.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Clubhouse User Profiles currently (left), and after consolidating clubs as one metric (right)</em></p>
<p><strong>87% of users discover suitable clubs to follow via user profiles directly.</strong> There exists a further hierarchy within clubs: followers (who receive notifications and see club-branded rooms in their hallway), and members (who, in addition to the above, can also start club-branded rooms themselves).</p>
<p>In Clubhouse’s current design, <strong>the clubs a user follows vs. clubs a user is a member of are in disparate locations:</strong> in the user’s following list and at the bottom of their user profile, respectively. This was confusing to users wanting scan all the clubs associated with a particular person.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/user-club-profile-recording-1-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Navigating both User and Club Profiles</em></p>
<p>By making clubs associated with a user a consolidated metric, users visiting that profile <strong>can more easily see what clubs that person belongs to,</strong> and immediately follow without visiting a new screen.</p>
<p>On the club level, <strong>being able to access metadata</strong> such as previously held rooms, upcoming rooms, and club admins can help a user get a more effective overview of the club.</p>
<h2 id="heading-ui-amp-branding-a-case-for-dark-ui">UI &amp; Branding: A Case for Dark UI</h2>
<p>In bringing all the pieces of this experience together, it became clear that adding too many visual elements would disrupt the visual hierarchy needed to move through the app with ease.</p>
<p>Additionally, the typical user experience on Clubhouse is already so immersive and emotive, often spanning all hours of the night — I wanted to take advantage of this use case and implement an elegant UI that emphasized Clubhouse’s few content types harmoniously.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/CH-style-tile.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>A snippet of the Style Guide that guided my work</em></p>
<h2 id="heading-usability-testing-how-effectively-is-findability-and-discoverability-throughout-the-app">Usability Testing: How effectively is findability and discoverability throughout the app?</h2>
<p>After conducting my usability tests, I created an affinity map with insights, behaviors, and findings during the tests. </p>
<p>Most users moved through the app with little to no missteps, but for many participants, there was one main point of friction that disrupted a key pillar of this redesign:</p>
<p><strong>It was still unclear how to access a room you saved from the Discovery page to your Hallway.</strong></p>
<h2 id="heading-usability-testing-insights-amp-priority-changes">Usability Testing Insights &amp; Priority Changes</h2>
<p>Initially, I designed for upcoming out-of-network rooms found in the discover tab to appear in the hallway by the user starring the room. These would then appear in your hallway algorithmically, further discoverable via the “sort by” drop-down menu. There were a few problems with this:</p>
<ul>
<li><strong>The original design essentially treated these rooms as saved items,</strong> which inadvertently (and incorrectly) prioritized these rooms over other rooms found in your hallway</li>
<li><strong>This treatment could have greater implications of disincentivizing spontaneous room creation,</strong> or unfairly prioritizing out-of-network rooms in general</li>
<li>Beyond this, <strong>embedding a saved item in a sort drop-down wasn’t intuitive</strong> or an expected place to find this type of content</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/set-notifications-flow-recording-2-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Setting notifications on the room, club, and user level</em></p>
<h2 id="heading-ia"> </h2>
<p>Conclusion: Lessons learned &amp; where we go from here</p>
<p>Going into this project, I knew this would be an ambitious challenge for a young designer. What I didn’t know was just how intricate and all-encompassing that challenge would be.</p>
<p>I learned that <strong>working on a highly publicized and highly beloved product</strong> comes with a lot of external pressure and internal emotions to <strong>do right by (seemingly) everyone</strong>. </p>
<p>There are the power users with fierce attachment to existing structures, and new users who can’t fully experience the nuance of an audio app as a static prototype.</p>
<p>Then there's the small but mighty Clubhouse team, who are actively iterating their product on a weekly basis, potentially launching imaginative solutions themselves for the same challenges I’m working on. And even others I haven’t imagined yet. </p>
<p>Against a constant stream of public conversation over an exciting product that felt almost ethereal, I’ll humbly admit that there were times where this pressure got the best of me and I felt like a total imposter who bit off way more than she could ever chew.</p>
<p>The biggest lessons this project taught me were the delicate balance between perseverance when faced with complex challenges, grace in the wake of perceived failure, and when to be okay with “good enough” (for this iteration, of course).</p>
<p>In the end, I’m extremely proud of what I was able to accomplish with this project at this stage in my design journey. And I often reminded myself of my favorite mantra that led me to product design in the first place:</p>
<blockquote>
<p><em>“All I wanted was a job like a book so good I’d be finishing it for the rest of my life.”</em></p>
</blockquote>
<p>Product design is that job for me, and I’m proud to say that while this project (and all my others) will never be fully finished, I breathed as much life into it as I could — I hope you enjoyed it!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Adobe XD vs Sketch vs Figma vs InVision - How to Pick the Best Design Software ]]>
                </title>
                <description>
                    <![CDATA[ Comparing Adobe XD vs Sketch vs Figma vs InVision studio is a very common topic among designers who are looking for the best design software. Sketch has long been the application of choice for UX and UI designers. But in the last four years, we have ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/adobe-xd-vs-sketch-vs-figma-vs-invision/</link>
                <guid isPermaLink="false">66c375a2e912451bdfbe18cf</guid>
                
                    <category>
                        <![CDATA[ Design Process ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Design Tools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ designer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ graphic design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Product Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Applications ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ website development, ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alexandru Paduraru ]]>
                </dc:creator>
                <pubDate>Wed, 05 Feb 2020 08:21:51 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/02/Adobe-xd-vs-Sketch-1024x576.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Comparing <strong>Adobe XD vs Sketch vs Figma vs InVision studio</strong> is a very common topic among designers who are looking for the best design software.</p>
<p>Sketch has long been the application of choice for UX and UI designers. But in the last four years, we have seen many new contenders for Sketch’s crown. Three of them that have made the biggest strides are Figma, Adobe XD, and InVision Studio.</p>
<p>These four tools have many pros in common but there are some differences too. For example, the first comparison, Adobe XD vs Sketch, makes sense especially since both have a similar interface which is user-friendly and has a minimalistic style.</p>
<p>In this article, I analyze how the most used design apps compete and what their unique features are using my experience acquired while working at <a target="_blank" href="https://www.creative-tim.com/?ref=freecodecamp">Creative Tim</a>.</p>
<p><img src="https://creativetimblog.com/blog/wp-content/uploads/2020/01/adobe-xd.png" alt="adobe xd" width="600" height="400" loading="lazy"></p>
<h3 id="heading-adobe-xdhttpswwwadobecomproductsxddetailshtml"><a target="_blank" href="https://www.adobe.com/products/xd/details.html"><strong>Adobe XD</strong></a></h3>
<p>Adobe XD was developed and published by Adobe Inc. XD, released on 18 October 2017. It is a vector-based user experience design tool for web apps, mobile apps, and voice apps available for macOS and Windows. There are versions for iOS and Android as well that help you preview the result of your work directly on mobile devices.</p>
<p>XD also support website wireframing and creating simple interactive click-through prototypes. With the character and layout tools of Adobe XD, Elements can be easily created and individual objects can be exported.</p>
<p>The interface is kept relatively simple, with a toolbar that is aligned at the side, as well as the large artboard area.</p>
<p>Comparing Adobe XD vs Sketch makes sense especially because of this similar interface which is user-friendly and has a minimalistic style.</p>
<p><img src="https://creativetimblog.com/blog/wp-content/uploads/2020/01/sketch.png" alt="sketch" width="600" height="400" loading="lazy"></p>
<h3 id="heading-sketchhttpswwwsketchcom"><a target="_blank" href="https://www.sketch.com/"><strong>Sketch</strong></a></h3>
<p>Sketch is a <a target="_blank" href="https://en.wikipedia.org/wiki/Vector_graphics_editor">vector graphics editor</a>, developed by the <a target="_blank" href="https://en.wikipedia.org/wiki/Netherlands">Dutch</a> company Bohemian Coding. Sketch was first released on 7 September 2010 for <a target="_blank" href="https://en.wikipedia.org/wiki/MacOS">macOS</a>. It won an <a target="_blank" href="https://en.wikipedia.org/wiki/Apple_Design_Awards">Apple Design Award</a> in 2012.</p>
<p>A key difference between Sketch and other vector graphics editors is that Sketch does not include print design features. Sketch is only available on macOS. This problem is partially solved by third party and handoff tools.</p>
<p>When Sketch first came out it completely disrupted the interface design space, but Adobe XD and Figma have recently come forward as new challengers. They offer unique functionality like prototyping and live collaboration.</p>
<p>I’ve recently been researching these tools for my side project, <a target="_blank" href="http://uxtools.co/">uxtools.co</a>, and wanted to share what I believe the be the most noteworthy decision points. Also, from my point of view, <a target="_blank" href="https://ahrefs.com/keywords-explorer/google/us/overview?keyword=learning%20to%20sketch">learning to sketch</a> is very useful and it does not take to much to become a Pro.</p>
<p><img src="https://creativetimblog.com/blog/wp-content/uploads/2020/01/figma.png" alt="figma" width="600" height="400" loading="lazy"></p>
<h3 id="heading-figmahttpswwwfigmacom"><a target="_blank" href="https://www.figma.com/"><strong>Figma</strong></a></h3>
<p>Figma came to the stage in 2016 <a target="_blank" href="https://techcrunch.com/2015/12/03/figma-vs-goliath/">with initial funding of $14M</a>.</p>
<p>With its seamless user interface and sleek feature palette, the tool quickly became a notorious competitor to similar solutions in the field.</p>
<p>Designers from brands like Twitter, Microsoft, GitHub, and Dropbox swear by Figma as the ultimate UI design tool.</p>
<p><img src="https://creativetimblog.com/blog/wp-content/uploads/2020/01/invision.png" alt="InVision Studio" width="600" height="400" loading="lazy"></p>
<h3 id="heading-invision-studiohttpswwwinvisionappcomstudio"><a target="_blank" href="https://www.invisionapp.com/studio"><strong>InVision Studio</strong></a></h3>
<p>InVision Studio is a new piece of software, released in 2019, that allows designers to build more advanced animation and micro-interactions. Studio also integrated with InVision’s link to Sketch via its Craft plugin.</p>
<p><strong>InVision Studio has got a nice dark UI by default</strong>, that helps developers focus on the work to be done in the evening. However, with macOS Mojave, every app can look like this quite easily. When they created it, they were inspired by another design tool - I am thinking about the Sketch app.</p>
<h2 id="heading-apps-comparison"><strong>Apps Comparison</strong></h2>
<h3 id="heading-1-pricing"><strong>1. Pricing</strong></h3>
<p>Budget can be a big deal when you’re working with your own resources. Some of these licenses have educational and promotional pricing (often 50% off), so don’t miss that part. For example, Figma will get you there for free as long as you're not working on a team.</p>
<ul>
<li><p><strong>Figma</strong>: Free for individuals! You can have 3 projects for free, or you can upgrade to unlimited projects and team functionality for $12/month (billed annually).</p>
</li>
<li><p><strong>Sketch</strong>: $99 per license that gets you the Mac App for life and access to the next production versions of the app.</p>
</li>
<li><p><strong>Adobe XD</strong>: It offers free and paid plans, depending on an individual's or team's needs. Paid plans start at $9.99/month.</p>
</li>
<li><p><strong>InVision Studio:</strong> Free right now.</p>
</li>
</ul>
<h3 id="heading-2-platform"><strong>2. Platform</strong></h3>
<p>Though Sketch has been immensely popular, it forces designers to only use Mac, which alienates developers from accessing design files.</p>
<ul>
<li><p><strong>Figma</strong>: Browser! Figma recently released a <a target="_blank" href="http://figma.com/downloads">Mac app</a> and <a target="_blank" href="https://www.figma.com/downloads">Windows app</a> (not offline-capable, though).</p>
</li>
<li><p><strong>Sketch</strong>: Mac only.</p>
</li>
<li><p><strong>Adobe XD</strong>: Mac and Windows. Subject to the same limitations as the CC suite.</p>
</li>
<li><p><strong>InVision Studio:</strong> Mac and Windows.</p>
</li>
</ul>
<h3 id="heading-3-live-collaboration"><strong>3. Live Collaboration</strong></h3>
<p>Nobody likes to send at the end of the day “version 3.0”, “version3.0.final”, “version3.0.final.final”. Live Collaboration can help us, especially live comments.</p>
<p>I imagine these were the same concerns that surrounded the release of the highly innovative Google Docs suite. Google Docs, however, turned the Microsoft Suite on its head with live collaboration, and now Figma is seeking to do the same thing with UI design.</p>
<ul>
<li><p><strong>Figma</strong>: Yes! Not to mention being browser-based, it allows Windows and even Linux users to have a very polished design tool.</p>
</li>
<li><p><strong>Sketch</strong>: Not natively, but a plugin, <a target="_blank" href="http://picnic.design/">Picnic</a>, is looking to change that. Also, they have <a target="_blank" href="https://www.sketch.com/teams/">Sketch for Teams</a>.</p>
</li>
<li><p><strong>Adobe XD</strong>: It offers real-time Coediting, launched at Adobe MAX 2019.</p>
</li>
<li><p><strong>InVision Studio:</strong> Not currently possible, but can generate share links.</p>
</li>
</ul>
<p><img src="https://i.imgur.com/Sy3UzVS.png" alt="Live Collaboration" width="2864" height="1594" loading="lazy"></p>
<p><em>Image: Figma -</em> <a target="_blank" href="https://www.creative-tim.com/product/argon-design-system-pro?ref=freecodecamp"><em>Argon Design System Pro</em></a></p>
<h3 id="heading-4-handoff"><strong>4. Handoff</strong></h3>
<p>Recently a few apps have been developed specifically to deliver specs (sizing, spacing, color) to developers, but design tools are starting to integrate this functionality natively.</p>
<ul>
<li><p><strong>Figma</strong>: Because of live collaboration, developers can easily jump in (regardless of OS) and access the designs. Figma now neatly prints the handoff code for CSS, iOS, or Android in the right panel.</p>
</li>
<li><p><strong>Sketch</strong>: They've recently launched their own native developer handoff feature — Cloud Inspector. There’s even an entirely free alternative called Sketch measure that works just as well.</p>
</li>
<li><p><strong>Adobe XD</strong>: It offers design specs that allow a designer to create a shared link that contains measurements, assets, and automatically-generated CSS code snippets.</p>
</li>
<li><p><strong>InVision Studio:</strong> They have “Inspect Now”.</p>
</li>
</ul>
<p><img src="https://i.imgur.com/5zY7ixi.png" alt="Handoff" width="2870" height="1494" loading="lazy"></p>
<p><em>Image: Figma -</em> <a target="_blank" href="https://www.creative-tim.com/product/argon-design-system-pro?ref=freecodecamp"><em>Argon Design System Pro</em></a></p>
<h3 id="heading-5-offline"><strong>5. Offline</strong></h3>
<p>This is so important. Some online apps can protect your information when Wifi goes down, but you need full access to open, use, and save from the app offline.</p>
<ul>
<li><p><strong>Figma</strong>: No, in an AMA they stated they don't have any current plans to add it.</p>
</li>
<li><p><strong>Sketch</strong>: Sure.</p>
</li>
<li><p><strong>Adobe XD</strong>: Yep.</p>
</li>
<li><p><strong>InVision Studio:</strong> Yes.</p>
</li>
</ul>
<p><img src="https://i.imgur.com/PY9NsKh.png" alt="Offline" width="2866" height="1596" loading="lazy"></p>
<p><em>Image: AdobeXD -</em> <a target="_blank" href="https://www.creative-tim.com/product/argon-dashboard?ref=freecodecamp"><em>Argon Dashboard Free</em></a></p>
<h3 id="heading-6-prototyping"><strong>6. Prototyping</strong></h3>
<p>There are literally dozens of these apps nowadays, but they might become extinct as Adobe XD brings prototyping directly to the design tool. Keep your eye on these.</p>
<ul>
<li><p><strong>Figma</strong>: Yes! It's very basic but feels like Adobe XD without the transitions. Also, there's a nice <a target="_blank" href="https://medium.com/figma-design/introducing-figmas-integration-with-framer-c69a747aeee2">Framer</a> integration.</p>
</li>
<li><p><strong>Sketch</strong>: Yes!</p>
</li>
<li><p><strong>Adobe XD</strong>: Yes, native prototyping within the app. Adobe XD also supports voice prototyping and keyboard/gamepad support.</p>
</li>
<li><p><strong>InVision Studio:</strong> Yes, you can create prototypes and animations.</p>
</li>
</ul>
<p><img src="https://i.imgur.com/5QZ8Rt1.png" alt="Prototyping" width="2812" height="1522" loading="lazy"></p>
<p><em>Image: InVision Studio -</em> <a target="_blank" href="https://www.creative-tim.com/product/argon-react-native?ref=freecodecamp"><em>Argon React Native</em></a></p>
<h3 id="heading-7-symbols"><strong>7. Symbols</strong></h3>
<p>Symbols can make your work easier. These have completely changed the design process. Forget building and duplicating list items over and over, let symbols do the work for you.</p>
<ul>
<li><p><strong>Figma</strong>: Good to go. Symbols now have states, constraints, and overrides.</p>
</li>
<li><p><strong>Sketch</strong>: The symbol functionality in Sketch is very impressive, and continues to improve. Symbols can be updated across entire documents and can resize responsively (that means less work for you when changing screen sizes).</p>
</li>
<li><p><strong>Adobe XD</strong>: It offers components that can be used throughout a document as well as linked across documents. It also allows designers to create variations of a component for different interactions, known as component states.</p>
</li>
<li><p><strong>InVision Studio:</strong> they have components that are a close approximation to the symbol conventions found in other applications. Components in their final form will honor a broad, scalable hierarchy that allows designers to quickly build-up, mix, and match components intelligently across their designs.</p>
</li>
</ul>
<p><img src="https://i.imgur.com/9lfwDD5.png" alt="Symbols" width="2874" height="1600" loading="lazy"></p>
<p><em>Image: Sketch -</em> <a target="_blank" href="https://www.creative-tim.com/product/material-kit-pro?ref=freecodecamp"><em>Material Kit Pro</em></a></p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Sketch has a big disadvantage here because it is only available for Mac users. And as such, it lets tools like Figma and Adobe XD innovate beyond the basic necessities.</p>
<p>Also, in terms of design tools, Adobe XD provides a robust set of responsive while the Sketch doesn’t have this feature built-in (but it has many plugins). If your tool does something better than the other, it is often enough of a reason to switch over. The browser-based approach that Figma has taken is also something to behold.</p>
<p>When talking about Adobe XD vs Sketch, the first one’s future is looking very bright and will win over many Sketch users. InVision’s change of focus may ensure its survival but one thing is for certain - Adobe XD is here to stay. The Adobe powerhouse is strong, and smaller companies like InVision and Sketch will have to work hard to stay relevant in the future.</p>
<p>People usually prefer to design and work in just one place. If you’re a part of a team, then Figma is undoubtedly for you.</p>
<p><img src="https://i.imgur.com/YaMctAr.png" alt="conclusions" width="2522" height="1932" loading="lazy"></p>
<p><strong>After all of that: first is Figma, second is Sketch, third is Adobe XD and fourth is InVision Studio.</strong></p>
<p>Overall, when talking about the best design software, these four tools are extremely well-suited for modern designer needs.</p>
<p>Try all four out to see which one is better for your use cases. I hope this comparison - Adobe XD vs Sketch vs Figma vs InVision - helped you decide which design tool is better for you.</p>
<p>Resources:</p>
<p><a target="_blank" href="https://www.figma.com/figma-vs-sketch/">https://www.figma.com/figma-vs-sketch/</a></p>
<p><a target="_blank" href="https://uxtools.co/blog/sketch-vs-adobe-xd-vs-figma/">https://uxtools.co/blog/sketch-vs-adobe-xd-vs-figma/</a></p>
<p><a target="_blank" href="https://www.codeinwp.com/blog/figma-vs-sketch-vs-adobe-xd/">https://www.codeinwp.com/blog/figma-vs-sketch-vs-adobe-xd/</a></p>
<p><a target="_blank" href="https://support.invisionapp.com/hc/en-us/sections/360004450191-Studio">https://support.invisionapp.com/hc/en-us/sections/360004450191-Studio</a></p>
<p><a target="_blank" href="https://helpx.adobe.com/ro/xd/help/components.html">https://helpx.adobe.com/ro/xd/help/components.html</a></p>
<p><a target="_blank" href="https://www.sketch.com/docs/">https://www.sketch.com/docs/</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How (and why) to embed domain concepts in code ]]>
                </title>
                <description>
                    <![CDATA[ Code should clearly reflect the problem it’s solving, and thus openly expose that problem’s domain. Embedding domain concepts in code requires thought and skill, and doesn't drop out automatically from TDD. However, it is a necessary step on the road... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/embedding-domain-concepts-in-code/</link>
                <guid isPermaLink="false">66bb925a867a396452a80286</guid>
                
                    <category>
                        <![CDATA[ Quality Software ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Code Quality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #Domain-Driven-Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Cedd Burge ]]>
                </dc:creator>
                <pubDate>Tue, 12 Nov 2019 07:48:19 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/11/2015-Gran-Paradiso-007.JPG" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Code should clearly reflect the problem it’s solving, and thus openly expose that problem’s domain. Embedding domain concepts in code requires thought and skill, and doesn't drop out automatically from TDD. However, it is a necessary step on the road to writing easily understandable code.</p>
<p>I was at a software craftsmanship meetup recently, where we formed pairs to solve a simplified Berlin Clock Kata. A Berlin Clock displays the time using rows of flashing lights, which you can see below (although in the kata we just output a text representation, and the lights in a row are all the same colour).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/berlin-clock-2.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-initial-test-driven-solution">Initial Test Driven solution</h2>
<p>Most pairs used inside out TDD, and there were a lot of solutions that looked something like this (complete <a target="_blank" href="https://github.com/ceddlyburge/berlin-clock-initial-tdd-solution/blob/master/BerlinClock.py">code available on GitHub</a>).</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">berlin_clock_time</span>(<span class="hljs-params">julian_time</span>):</span>
    hours, minutes, seconds = list(map(int, julian_time.split(<span class="hljs-string">":"</span>)))

    <span class="hljs-keyword">return</span> [
        seconds_row_lights(seconds % <span class="hljs-number">2</span>)
        , five_hours_row_lights(hours)
        , single_hours_row_lights(hours % <span class="hljs-number">5</span>)
        , five_minutes_row_lights(minutes)
        , single_minutes_row_lights(minutes % <span class="hljs-number">5</span>)
    ]

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">five_hours_row_lights</span>(<span class="hljs-params">hours</span>):</span>
    lights_on = hours // <span class="hljs-number">5</span>
    lights_in_row = <span class="hljs-number">4</span>
    <span class="hljs-keyword">return</span> lights_for_row(<span class="hljs-string">"R"</span>, lights_on, lights_in_row)

<span class="hljs-comment"># ...</span>
</code></pre>
<p>This type of solution drops out naturally from applying inside out TDD to the problem. You write some tests for the seconds row, then some tests for the five hours row, and so on, and then you put it all together and do some refactoring. This solution does expose some of the domain concepts at a glance:</p>
<ul>
<li>There are 5 rows</li>
<li>There is one second row, 2 hour rows and 2 minute rows</li>
</ul>
<p>Some more concepts are available after a bit of digging, but aren't immediately obvious. The rows are made up of lights that can be on (or presumably off), and that the number of lights on is an indication of the time.</p>
<p>However there are some big parts of the problem that are not exposed. And since I haven't yet explained it, you probably don't know exactly how the Berlin Clock works yet.</p>
<h2 id="heading-elevate-the-concepts">Elevate the concepts</h2>
<p>To improve this we can bring some of the details that are buried in the helper functions (such as <code>get_five_hours</code>) closer to the top of the file. This brings you to something like the following (complete <a target="_blank" href="https://github.com/ceddlyburge/berlin-clock-elevated-concepts/blob/master/BerlinClock.py">code available on GitHub</a>), although the downside is that it breaks nearly all of the tests. Solutions like this are rarer on GitHub, but do exist.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">berlin_clock_time</span>(<span class="hljs-params">julian_time</span>):</span>
    hours, minutes, seconds = list(map(int, julian_time.split(<span class="hljs-string">":"</span>)))

    single_seconds = seconds_row_lights(seconds % <span class="hljs-number">2</span>)
    five_hours = row_lights(
        light_colour=<span class="hljs-string">"R"</span>,
        lights_on=hours // <span class="hljs-number">5</span>,
        lights_in_row=<span class="hljs-number">4</span>)
    single_hours = row_lights(
        light_colour=<span class="hljs-string">"R"</span>,
        lights_on=hours % <span class="hljs-number">5</span>,
        lights_in_row=<span class="hljs-number">4</span>)
    five_minutes = row_lights(
        light_colour=<span class="hljs-string">"Y"</span>,
        lights_on=minutes // <span class="hljs-number">5</span>,
        lights_in_row=<span class="hljs-number">11</span>)
    single_minutes = row_lights(
        light_colour=<span class="hljs-string">"Y"</span>,
        lights_on=minutes % <span class="hljs-number">5</span>,
        lights_in_row=<span class="hljs-number">4</span>)

    <span class="hljs-keyword">return</span> [
        single_seconds,
        five_hours,
        single_hours,
        five_minutes,
        single_minutes
    ]

<span class="hljs-comment"># ...</span>
</code></pre>
<p>This improves the concepts that are now exposed at a glance:</p>
<ul>
<li>There are 5 rows</li>
<li>The seconds row is a special case</li>
<li>There are 2 hour rows and 2 minute rows</li>
<li>The rows use different colour lights</li>
<li>The rows have a different number of lights</li>
</ul>
<p>This is pretty good, and is already better that most of the solutions out there. However, it's still a bit mysterious how the rows are related to each other (there are 2 rows to display the hours and the minutes, so presumably these are linked). It's also not obvious what amount of time each light represents.</p>
<h2 id="heading-name-implicit-concepts">Name implicit concepts</h2>
<p>At the moment some of the concepts (such as the amount of time each light represents) are implicit in the code. Making these explicit, and naming them, forces us to understand them and to embed that understanding in the code.</p>
<p>In order to make the amount of time each light represents explicit, it seems like it would be sensible to pass a <code>time_per_light</code> value to <code>row_lights</code>. This means we have to push the calculation of <code>lights_on</code> down into <code>row_lights</code>.</p>
<p>This in turn makes it obvious that there are two kinds of rows: one related to the quotient (<code>\\</code>) of the time value, and one related to the remainder / modulus (<code>%</code>). If we look at the quotient case, we see that the 2nd parameter to the operation is the <code>time_per_light</code>, which is 5 in both cases (5 hours in one case and 5 minutes in the other).</p>
<p>This allows us to write these rows like this:</p>
<pre><code class="lang-python">five_hour_row = row_lights(
    time_per_light=<span class="hljs-number">5</span>,
    value=hours, 
    light_colour=<span class="hljs-string">"R"</span>,
    lights_in_row=<span class="hljs-number">4</span>)
</code></pre>
<p>If we now turn our attention to the remainder case, we realise that <code>time_per_light</code> is always singular (one hour or one minute), as it is filling in the gaps in the quotient case. </p>
<p>For example, the five hours row can represent 0, 5, 10, 15, or 20 hours, but nothing in between. In order to represent any hour, there must be another row to represent +1, +2, +3 and +4. This means that this row must have exactly 4 lights, and that each light must represent 1 hour.</p>
<p>This implies that the remainder case is dependent on the quotient one, which most people would describe as a parent / child relationship.</p>
<p>With this knowledge in hand, we can now create a function for the child remainder rows, and the solution now looks like this (complete <a target="_blank" href="https://github.com/ceddlyburge/berlin-clock">code on GitHub</a>):</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">berlin_clock_time</span>(<span class="hljs-params">julian_time</span>):</span>
    hours, minutes, seconds = list(map(int, julian_time.split(<span class="hljs-string">":"</span>)))

    <span class="hljs-keyword">return</span> [
        seconds_row_lights(
            seconds % <span class="hljs-number">2</span>),
        parent_row_lights(
            time_per_light=<span class="hljs-number">5</span>,
            value=hours, 
            light_colour=<span class="hljs-string">"R"</span>,
            lights_in_row=<span class="hljs-number">4</span>),
        child_remainder_row_lights(
            parent_time_per_light=<span class="hljs-number">5</span>,
            value=hours,
            light_colour=<span class="hljs-string">"R"</span>),
        parent_row_lights(
            time_per_light=<span class="hljs-number">5</span>,
            value=minutes, 
            light_colour=<span class="hljs-string">"Y"</span>,
            lights_in_row=<span class="hljs-number">11</span>),
        child_remainder_row_lights(
            parent_time_per_light=<span class="hljs-number">5</span>,
            light_colour=<span class="hljs-string">"Y"</span>,
            value=minutes)
    ]

<span class="hljs-comment"># ...</span>
</code></pre>
<p>A quick glance at this code now reveals nearly all the domain concepts</p>
<ul>
<li>The first row represents the seconds and is a special case</li>
<li>On the second row each "R" light represents 5 hours</li>
<li>The third row shows the remainder from the second</li>
<li>On the fourth row each "Y" light represents 5 hours</li>
<li>The fifth row shows the remainder from the fourth</li>
</ul>
<p>This took something thinking about, which will have cost us some time / money. But we increased our understanding of the problem while we did it, and most importantly we embedded that knowledge in to the code. This means that the next person to read the code will not have to do this, which will save some time / money. Since we spend about 10 times longer reading code than we do writing it, this is probably a worthwhile endeavour.</p>
<p>Embedding this understanding has also made it harder for future programmers to make mistakes. For example, the concept of parent / child rows didn't exist in earlier examples, and it would be easy to mismatch them. Now the concept is plain to see, and the values are mostly worked out for you. It is also easier to refactor to support new clock variants, for example where lights in the first hours row represent 6 hours.</p>
<h2 id="heading-how-far-should-you-take-it">How far should you take it?</h2>
<p>There are things we can do to take this further. For example the <code>parent_time_per_light</code> of a child row must match the <code>time_per_light</code> of its parent, and there is nothing enforcing this. There is also a relationship between <code>time_per_light</code> and <code>lights_in_row</code> for the parent rows, and again it is not enforced. </p>
<p>However, at the moment we are only required to support one clock variant, so these probably aren't worth doing. When a change is required for the code, we should refactor so that the change is easy (which might be hard) and then make the easy change.</p>
<h2 id="heading-conclusions">Conclusions</h2>
<p>Embedding domain concepts in code requires thought and skill, and TDD won't necessarily do it for you. It takes longer than a naive solution, but makes the code easier to understand, and will very likely save time in the medium term. Time is money, and finding the right balance of spending time now versus saving time later is also an important skill for a professional programmer to have. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to write easily describable code ]]>
                </title>
                <description>
                    <![CDATA[ When code is not describable using words, most people have to do some mental mapping to turn it in to words. This wastes mental energy, and you run the risk of getting the mapping wrong. Different people will map to different words, which leads to co... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/writing-describable-code/</link>
                <guid isPermaLink="false">66bb9273a5fd14123a8b4a3c</guid>
                
                    <category>
                        <![CDATA[ Code Quality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design patterns ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Cedd Burge ]]>
                </dc:creator>
                <pubDate>Wed, 02 Oct 2019 20:34:23 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/10/writing-describable-code.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When code is not describable using words, most people have to do some mental mapping to turn it in to words. This wastes mental energy, and you run the risk of getting the mapping wrong. Different people will map to different words, which leads to confusion when discussing the code. </p>
<p>This is usually a fertile breeding ground for bugs born out of miscommunication / misunderstanding, and fixing these bugs often introduces new ones, for the same reasons. In the end it becomes code that no one really understands or wants to touch.</p>
<h2 id="heading-example-of-undescribable-code">Example of undescribable code</h2>
<p>It is easy to think that code is already a written language. If it looks simple, it should be easy to read, speak and listen to. However, this is not always the case.</p>
<p>Below is a common solution to deciding whether a year is a leap year.</p>
<pre><code class="lang-python">(divisibleBy(<span class="hljs-number">4</span>) <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> divisibleBy(<span class="hljs-number">100</span>)) <span class="hljs-keyword">or</span> divisibleBy(<span class="hljs-number">400</span>)
</code></pre>
<p>This is not overly complicated code. It calls a functions 3 times, has 3 operators (and, or, not), and has two levels of nesting.</p>
<p>However, if you take a second to try and describe the algorithm in words I think you will find it to be a struggle.</p>
<p>Maybe “A year is leap year if it is divisible by 4 and not divisible by 100, or divisible by 400”?</p>
<p>The trouble with this is that the code has brackets, but the words do not. So they cannot adequately describe the condition, and whether “or divisible by 400” applies to “divisible by 4” or “not divisible by 400”. You could try some hand waving and gesturing to get around this, or vary the length of pause between the statements, but hopefully it’s obvious that there is a lot of potential for error.</p>
<h2 id="heading-refactoring-to-describable-code">Refactoring to describable code</h2>
<p>Instead we can start by describing the condition with words, and then make the words as clear and concise as possible. We might start with this:</p>
<p>“400 years is a special case. If a year is divisible by 400, then it is a leap  year. 100 years is also a special case. If a year is divisible by 100 then it isn’t a leap year, unless it is also divisble by 400, the 400 year special case takes priority. If there are no special cases, then the year is a leap year if it is divisible by 4.”</p>
<p>This is clear, but isn’t concise, so we would probably want to shrink it a bit:</p>
<p>“If a year is divisible by 400, then it is a leap year. Otherwise if it is divisible by 100 then it is a normal year, otherwise it is a leap year if it is divisible by 4.”</p>
<p>If we turn these words in to code, we probably get something like the following:</p>
<pre><code class="lang-python">    <span class="hljs-keyword">if</span> divisbleBy(<span class="hljs-number">400</span>):
        <span class="hljs-keyword">return</span> LeapYear
    <span class="hljs-keyword">elif</span> divisbleBy(<span class="hljs-number">100</span>)
        <span class="hljs-keyword">return</span> NormalYear
    <span class="hljs-keyword">elif</span> divisbleBy(<span class="hljs-number">4</span>):
        <span class="hljs-keyword">return</span> LeapYear
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> NormalYear
</code></pre>
<h2 id="heading-conclusions">Conclusions</h2>
<p>Hard to understand code is a daily occurrence for virtually all programmers. We can help ourselves and our co-workers by writing code that is easy to describe in words.</p>
<p>And the great thing is that doing so is actually easier than writing code any other way, as there is no mental mapping / wasted mental effort. The only “trick” is to describe the algorithm in words, and then write code to match the words.</p>
<p>In many organisations, the algorithm will already be described in words, as part of acceptance tests or user stories, which will improve productivity even further.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Learn Software Design and Architecture - a Roadmap ]]>
                </title>
                <description>
                    <![CDATA[ By Khalil Stemmler This article is a summary of what I'm writing about in my newest project, solidbook.io - The Handbook to Software Design and Architecture with TypeScript. Check it out it you like this post. It's crazy to me to consider the fact ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/software-design/</link>
                <guid isPermaLink="false">66d45f6c868774922c884fea</guid>
                
                    <category>
                        <![CDATA[ architecture ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sun, 29 Sep 2019 18:17:54 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/09/banner-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Khalil Stemmler</p>
<blockquote>
<p>This article is a summary of what I'm writing about in my newest project, <a target="_blank" href="https://solidbook.io">solidbook.io - The Handbook to Software Design and Architecture with TypeScript</a>. Check it out it you like this post.</p>
</blockquote>
<p>It's crazy to me to consider the fact that Facebook was once an empty text file on someone's computer.</p>
<p>Lol.</p>
<p>This past year, I've been going hard in software design and architecture, <a target="_blank" href="https://khalilstemmler.com/articles/domain-driven-design-intro/">Domain-Driven Design</a>, and <a target="_blank" href="https://solidbook.io">writing a book</a> on it, and I wanted to take a moment to try to piece it together into something useful I could share with the community.</p>
<p>Here's my roadmap for how to learn software design and architecture.</p>
<p>I've broken it down into two artifacts: the <strong>stack</strong> and the <strong>map</strong>.</p>
<h2 id="heading-the-stack">The Stack</h2>
<p>Similar to the <a target="_blank" href="https://en.wikipedia.org/wiki/OSI_model">OSI Model</a> in networking, each layer builds on top of the foundation of the previous one.</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/e727h5b9nozcuo4za2yw.png" alt="The stack" width="600" height="400" loading="lazy"></p>
<h2 id="heading-the-map">The Map</h2>
<p>While I think the stack is good to see the bigger picture of how everything works together, the map is a little bit more detailed (and inspired by the <a target="_blank" href="https://github.com/kamranahmedse/developer-roadmap">web developer roadmap</a>) and as a result, I think it's more useful.</p>
<p>Here it is below! To <a target="_blank" href="https://khalilstemmler.com/articles/software-design-architecture/full-stack-software-design/">fork the repo, read my detailed write-up and download it in  high-res, click here</a>.</p>
<p><img src="https://user-images.githubusercontent.com/6892666/65834517-bb39f980-e2a9-11e9-8a75-0e1559c5ed56.png" alt="Software Design and Architecture Roadmap" width="600" height="400" loading="lazy"></p>
<h2 id="heading-stage-1-clean-code">Stage 1: Clean code</h2>
<p>The very first step towards creating long-lasting software is figuring out how to write <strong>clean code</strong>. </p>
<p>Clean code is code that is easy to understand and change. At the low-level, this manifests in a few design choices like:</p>
<ul>
<li>being consistent</li>
<li>preferring meaningful variable, method and class names over writing comments</li>
<li>ensuring code is indented and spaced properly</li>
<li>ensuring all of the tests can run</li>
<li>writing pure functions with no side effects</li>
<li>not passing null </li>
</ul>
<p>Writing clean code is incredibly important. </p>
<p>Think of it like a game of jenga.</p>
<p>In order to keep the structure of our project stable over time, things like indentation, small classes and methods, and meaningful names, pay off a lot in the long run. </p>
<p>The best resource to learn how to write clean code is Uncle Bob's book, "<a target="_blank" href="https://www.amazon.ca/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882">Clean Code</a>".</p>
<h2 id="heading-stage-2-programming-paradigms">Stage 2: Programming Paradigms</h2>
<p>Now that we're writing readable code that's easy to maintain, it would be a good idea to really understand the 3 major programming paradigms and the way they influence how we write code.</p>
<p>In Uncle Bob's book, "<a target="_blank" href="https://www.amazon.ca/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=asc_df_0132350882/?tag=googleshopc0c-20&amp;linkCode=df0&amp;hvadid=292982483438&amp;hvpos=1o2&amp;hvnetw=g&amp;hvrand=13521899336201370454&amp;hvpone=&amp;hvptwo=&amp;hvqmt=&amp;hvdev=c&amp;hvdvcmdl=&amp;hvlocint=&amp;hvlocphy=9000834&amp;hvtargid=pla-435472505264&amp;psc=1">Clean Architecture</a>", he brings attention to the fact that:</p>
<ul>
<li>Object-Oriented Programming is the tool best suited for defining how we cross architectural boundaries with polymorhpism and plugins</li>
<li>Functional programming is the tool we use to push data to the boundaries of our applications</li>
<li>and Structured programming is the tool we use to write algorithms</li>
</ul>
<p>This implies that effective software uses a hybrid all 3 programming paradigms styles at different times.</p>
<p>While you <em>could</em> take a strictly functional or strictly object-oriented approach to writing code, understanding where each excels will improve the quality of your designs.</p>
<blockquote>
<p>If all you have is a hammer, everything seems like a nail.</p>
</blockquote>
<h3 id="heading-resources">Resources</h3>
<p>For <strong>functional programming</strong>, check out:</p>
<ul>
<li><a target="_blank" href="https://mostly-adequate.gitbooks.io/mostly-adequate-guide/">Professor Frisby's Mostly Adequate Guide to Functional Programming</a></li>
<li><a target="_blank" href="https://pragprog.com/book/swdddf/domain-modeling-made-functional?fbclid=IwAR0NHoyVrMoSRIE-EJMUOdsb3bhivow6JXKyUeg4FPHE8QmeOQG4L77HzMo">Domain Modeling Made Functional</a></li>
</ul>
<h2 id="heading-stage-3-object-oriented-programming">Stage 3: Object-Oriented Programming</h2>
<p>It's important to know how each of the paradigms work and how they urge you to structure the code within them, but with respect to architecture, Object-Oriented Programming is the clear <em>tool for the job</em>.</p>
<p>Not only does Object-Oriented programming enable us to create a <strong>plugin architecture</strong> and build flexibility into our projects; OOP comes with the 4 principles of OOP (encapsulation, inheritance, polymorhism, and abstraction) that help us create <strong>rich domain models</strong>.</p>
<p>Most developers learning Object-Oriented Programming never get to this part: learning how to create a <u>software implementation of the problem domain</u>, and locating it in the center of a <strong>layered</strong> web app. </p>
<p>Functional programming can seem like the means to all ends in this scenario, but  I'd recommend getting acquainted with model-driven design and <a target="_blank" href="https://khalilstemmler.com/articles/domain-driven-design-intro/">Domain-Driven Design</a> to understand the bigger picture on how object-modelers are able to encapsulate an entire business in a zero-dependency domain model.</p>
<blockquote>
<p>Why is that a huge deal?</p>
</blockquote>
<p>It's huge because if you can create a mental-model of a business, you can create a software implementation of that business.</p>
<h2 id="heading-stage-4-design-principles">Stage 4: Design Principles</h2>
<p>At this point, you're understanding that Object-Oriented Programming is very useful for encapsulating rich domain models and solving the <a target="_blank" href="https://khalilstemmler.com/wiki/3-categories-of-hard-software-problems/">3rd type of "Hard Software Problems"- Complex Domains</a>.</p>
<p>But OOP can introduce some design challenges. </p>
<p>When should I use composition?</p>
<p>When should I use inheritance?</p>
<p>When should I use an abstract class?</p>
<p>Design principles are really well-established and battle-tested object-oriented best practices that you use as railguards.</p>
<p>Some examples of common design principles you should familiarize yourself with are:</p>
<ul>
<li>Composition over inheritance</li>
<li>Encapsulate what varies</li>
<li>Program against abstractions, not concretions</li>
<li>The hollywood principle: "Don't call us, we'll call you"</li>
<li>The <a target="_blank" href="https://khalilstemmler.com/articles/solid-principles/solid-typescript/">SOLID principles</a>, especially the <a target="_blank" href="https://khalilstemmler.com/articles/solid-principles/single-responsibility/">Single responsibility principle</a></li>
<li>DRY (Do Not Repeat Yourself)</li>
<li><a target="_blank" href="https://khalilstemmler.com/wiki/yagni/">YAGNI (You Aren't Gonna Need It)</a></li>
</ul>
<p>Make sure to come to your <em>own</em> conclusions, though. Don't just follow what someone else says you should do. Make sure that it makes sense to you.</p>
<h2 id="heading-stage-5-design-patterns">Stage 5: Design Patterns</h2>
<p>Just about every problem in software has been categorized and solved already. We call these patterns: design patterns, actually.</p>
<p>There are 3 categories of design patterns: <strong>creational</strong>, <strong>structural</strong>, and <strong>behaviour</strong>.</p>
<h3 id="heading-creational">Creational</h3>
<p>Creational patterns are patterns that control how objects are created.</p>
<p>Examples of creational patterns include:</p>
<ul>
<li>The <strong>Singleton pattern</strong>, for ensuring only a single instance of a class can exist</li>
<li>The <strong>Abstract Factory pattern</strong>, for creating an instance of several families of classes</li>
<li>The <strong>Prototype pattern</strong>, for starting out with an instance that is cloned from an existing one</li>
</ul>
<h3 id="heading-structural">Structural</h3>
<p>Structural patterns are patterns that simplify how we define relationships between components.</p>
<p>Examples of structural design patterns include:</p>
<ul>
<li>The <strong>Adapter pattern</strong>, for creating an interface to enable classes that normally can't work together, to work together. </li>
<li>The <strong>Bridge pattern</strong>, for splitting a class that should actually be one or more, into a set of classes that belong to a hierarchy, enabling the implementations to be developed independently of each other.</li>
<li>The <strong>Decorator pattern</strong>, for adding responsibilities to objects dynamically.</li>
</ul>
<h3 id="heading-behavioural">Behavioural</h3>
<p>Behavioural patterns are common patterns for facilitating elegant communication between objects.</p>
<p>Examples of behavioural patterns are:</p>
<ul>
<li>The <strong>Template pattern</strong>, for deferring the exact steps of an algorithm to a subclass.</li>
<li>The <strong>Mediator pattern</strong>, for defining the exact communication channels allowed between classes. </li>
<li>The <strong>Observer pattern</strong>, for enabling classes to subscribe to something of interest, and to be notified when a change occurred.</li>
</ul>
<h3 id="heading-design-pattern-criticisms">Design pattern criticisms</h3>
<p>Design patterns are great and all, but sometimes they can an additional complexity to our designs. It's important to remember YAGNI and attempt to keep our designs as simple as possible. Only use design patterns when you're really sure you need them. You'll know when you will.</p>
<p>If we know what each of these patterns are, when to use them, and when to <em>not even bother</em> using them, we're in good shape to begin to understand how to architect larger systems.</p>
<p>The reason behind that is because <strong>architectural patterns are just design patterns blown-up in scale to the high-level</strong>, where design patterns are low-level implementations (closer to classes and functions).</p>
<h3 id="heading-resources-1">Resources</h3>
<p><a target="_blank" href="https://refactoring.guru/design-patterns">Refactoring Guru - Design Patterns</a></p>
<h2 id="heading-stage-6-architectural-principles">Stage 6: Architectural Principles</h2>
<p>Now we're at a higher level of thinking beyond the class level.</p>
<p>We now understand that the decisions we make towards organzing and building relationships between components at the high-level and the low-level, will have a significant impact on the maintainability, flexibility, and testability of our project.</p>
<p>Learn the guiding principles that helps you build in the flexibility that your codebase needs in order to be able to react to new features and requirements, with as little effort as possible.</p>
<p>Here's what I'd recommend learning right off the bat:</p>
<ul>
<li>Component design principles: <a target="_blank" href="https://khalilstemmler.com/wiki/stable-abstraction-principle/">The Stable Abstraction Principle</a>, <a target="_blank" href="https://khalilstemmler.com/wiki/stable-dependency-principle/">The Stable Dependency Principle</a>, and The Acyclic Dependency Principle, for how to organize components, their dependencies, when to couple them, and the implications of accidentally creating dependency cycles and relying on unstable components.</li>
<li><a target="_blank" href="https://khalilstemmler.com/articles/enterprise-typescript-nodejs/clean-nodejs-architecture/">Policy vs. Detail</a>, for understanding how to separate the rules of your application from the implementation details.</li>
<li>Boundaries, and how to identify the <a target="_blank" href="https://khalilstemmler.com/articles/enterprise-typescript-nodejs/application-layer-use-cases/">subdomains</a> that the features of your application belongs within.</li>
</ul>
<p>Uncle Bob discovered and originally documented many of these principles, so the best resource to learn about this is again, "<a target="_blank" href="https://www.amazon.ca/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=asc_df_0132350882/?tag=googleshopc0c-20&amp;linkCode=df0&amp;hvadid=292982483438&amp;hvpos=1o2&amp;hvnetw=g&amp;hvrand=13521899336201370454&amp;hvpone=&amp;hvptwo=&amp;hvqmt=&amp;hvdev=c&amp;hvdvcmdl=&amp;hvlocint=&amp;hvlocphy=9000834&amp;hvtargid=pla-435472505264&amp;psc=1">Clean Architecture</a>".</p>
<h2 id="heading-stage-7-architectural-styles">Stage 7: Architectural Styles</h2>
<p>Architecture is about the stuff that matters.</p>
<p>It's about identifying what a system needs in order for it to be successful, and then <u>stacking the odds of success</u> by choosing the architecture that best fits the requirements.</p>
<p>For example, a system that has a lot of <strong>business logic complexity</strong> would benefit from using a <strong>layered architecture</strong> to encapsulate that complexity.</p>
<p>A system like Uber needs to be able to handle a lot of <strong>real time-events</strong> at once and update drivers' locations, so <strong>publish-subscribe</strong> style architecture might be most effective.</p>
<p>I'll repeat myself here because it's important to note that the 3 categories of architectural styles are similar to the 3 categories of design patterns, because <strong>architectural styles are design patterns at the high-level</strong>.</p>
<h3 id="heading-structrual">Structrual</h3>
<p>Projects with <em>varying levels</em> of components and wide-ranging functionality will either benefit or suffer from adopting a structural architecture.</p>
<p>Here are a few examples:</p>
<ul>
<li><strong>Component-based</strong> architectures emphasize <u>separation of concerns</u> between the <em>individual components</em> within a system. Think <strong>Google</strong> for a sec. Consider how many applications they have within their enterprise (Google Docs, Google Drive, Google Maps, etc). For platforms with lots of functionality, component-based architectures divide the concerns into loosely coupled independent components. This is a <em>horizontal</em> separation. </li>
<li><strong>Monolithic</strong> means that the application is combined into a single platform or program, deployed altogether. <em>Note: You can have a component-based AND monolithic  architecture if you separate your applications properly, yet deploy it all as one piece</em>.</li>
<li><strong>Layered</strong> architectures separate the concerns <em>vertically</em> by cutting software into infrastructure, application, and domain layers.</li>
</ul>
<p><img src="https://khalilstemmler.com/img/blog/software-architecture-design/app-logic-layers.svg" alt="Clean Architecture" width="600" height="400" loading="lazy"></p>
<blockquote>
<p>An example of cutting the concerns of an application <em>vertically</em> by using a layered architecture. Read <a target="_blank" href="https://khalilstemmler.com/articles/software-design-architecture/organizing-app-logic/">here</a> for more information on how to do this.</p>
</blockquote>
<h3 id="heading-messaging">Messaging</h3>
<p>Depending on your project, messaging might be a really important component to the success of the system. For projects like this, message-based architectures build on top of functional programming principles and behavioural design patterns like the observer pattern.</p>
<p>Here are a few examples of message-based architectural styles:</p>
<ul>
<li><strong>Event-Driven</strong> architectures view all signficant changes to state as events. For example, within a <a target="_blank" href="https://github.com/stemmlerjs/white-label">vinyl-trading app</a>, a offer's state might change from "pending" to "accepted" when both parties agreee on the trade. </li>
<li><strong>Publish-subscribe</strong> architectures build on top of the Observer design pattern by making it the primary communication method between the system itself, end-users / clients, and others systems and components.</li>
</ul>
<h3 id="heading-distributed">Distributed</h3>
<p>A distributed architecture simply means that the components of the system are deployed separately and operate by communicating over a network protocol. Distributed systems can be very effective for scaling throughput, scaling teams, and delegating (potentially expensive tasks or) responsibility to other components.</p>
<p>A few examples of distributed architectural styles are:</p>
<ul>
<li><strong>Client-server</strong> architecture. One of the most common architectures, where we divide the work to be done between the client (presentation) and the server (business logic). </li>
<li><strong>Peer-to-peer</strong> architectures distribute application-layer tasks between equally-privileged participants, forming a peer-to-peer network. </li>
</ul>
<h2 id="heading-stage-8-architectural-patterns">Stage 8: Architectural Patterns</h2>
<p>Architectural <em>patterns</em> explain in greater tactical detail how to actually implement one of those architectural <em>styles</em>.</p>
<p>Here are a couple of examples of architectural patterns and the styles that they inherit from:</p>
<ul>
<li><strong><a target="_blank" href="https://khalilstemmler.com/articles/domain-driven-design-intro/">Domain-Driven Design</a></strong> is an approach to software development against really complex problem domains. For DDD to be most successful, we need to implement a <strong>layered architecture</strong> in order to separate the concerns of a domain model from the infrastrural details that makes the application actually run, like databases, webservers, caches, etc.</li>
<li><strong>Model-View Controller</strong> is probably the <u>most well-known</u> architectural pattern for developing user interface-based applications. It works by dividing the app into 3 components: model, view, and controller. MVC is incredibly useful when you're first starting out, and it helps you piggyback towards other architectures, but there hit's a point when we realize <a target="_blank" href="https://khalilstemmler.com/articles/enterprise-typescript-nodejs/when-crud-mvc-isnt-enough/">MVC isn't enough</a> for problems with lots of business logic.</li>
<li><strong>Event sourcing</strong> is a functional approach where we  store only the transactions, and never the state. If we ever need the state, we can apply all the transactions from the beginning of time.</li>
</ul>
<h2 id="heading-stage-9-enterprise-patterns">Stage 9: Enterprise patterns</h2>
<p>Any architectural pattern you choose will introduce a number of constructs and technical jargon to familiarize yourself with and decide on whether it's worth the effort to use or not.</p>
<p>Taking an example that many of us know, in <strong>MVC</strong>, the <em>view</em> holds all the presentation layer code, the <em>controller</em> is translates commands and queries from the <em>view</em> into requests that are handled by the <em>model</em> and returned by the <em>controller</em>.</p>
<p>Where in the Model (M) do we handle these things?:</p>
<ul>
<li>validation logic</li>
<li>invariant rules</li>
<li>domain events</li>
<li>use cases</li>
<li>complex queries</li>
<li>and business logic</li>
</ul>
<p>If we simply use an ORM (object-relational mapper) like <a target="_blank" href="">Sequelize</a> or <a target="_blank" href="">TypeORM</a> as the <em>model</em>, all that important stuff to gets left to interpretation on where it should go, and it finds itself in some unspecified layer between (what should be a rich) <em>model</em> and the <em>controller</em>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/mvc-2.svg" alt="mvc-2" width="600" height="400" loading="lazy"></p>
<blockquote>
<p>Taken from "3.1 - Slim (Logic-less) models" in <a target="_blank" href="https://solidbook.io">solidbook.io</a>.</p>
</blockquote>
<p>If there's something I've learned so far in my journey going beyond MVC, it's that <strong>there is a construct for everything</strong>.</p>
<p>For each of those things that MVC fails to address, there exist other <strong>enterprise patterns</strong> to solve them. For example:</p>
<ul>
<li><strong><a target="_blank" href="https://khalilstemmler.com/articles/typescript-domain-driven-design/entities/">Entities</a></strong> describe models that have an identity.</li>
<li><strong><a target="_blank" href="https://khalilstemmler.com/articles/typescript-value-object/">Value Objects</a></strong> are models that have no identity, and can be used in order to encapsulate validation logic.</li>
<li><strong><a target="_blank" href="https://khalilstemmler.com/articles/typescript-domain-driven-design/chain-business-logic-domain-events/">Domain Events</a></strong> are events that signify some relevant business event occurring, and can be subscribed to from other components.</li>
</ul>
<p>Depending on the architectural style you've chosen, there are going to be a ton of other enterprise patterns for you to learn in order to implement that pattern to it's fullest potential. </p>
<h3 id="heading-integration-patterns">Integration patterns</h3>
<p>Once your application is up and running, as you get more and more users, you might run into performance issues. API calls might take a long time, servers might crash from being overloaded with requests, etc. In order to solve these problems, you might read about integrating things like <strong>message queues</strong> or <strong>caches</strong> in order to improve performance. </p>
<p>This is probably the most challenging stuff: <em>scaling, audits, and performance</em>. </p>
<p>Designing a system for <em>scale</em> can be incredibly challenging. It requires a deep understanding of the limitations of each component within the architecture, and a plan of action for how to mitigate stress on your architecture and continue to serve requests in high-traffic situations.</p>
<p>The need also the need to <em>audit</em> what's going on in your application. Large enterprise companies need to be able to perform audits in order to identify potential security issues, understand how users are using their applications, and  have a log of everything that's ever happened.</p>
<p>This can be challenging to implement, but common architectures end up looking <strong>event-based</strong> and build upon a wide range of software and system design concepts, principles, and practices like Event Storming, DDD, CQRS (command query response segregation), and Event Sourcing.</p>
<hr>
<p>I hope that was useful to you!</p>
<p>Let me know if you have any suggestions or questions.</p>
<p>Cheers!</p>
<p><a target="_blank" href="https://github.com/stemmlerjs/software-design-and-architecture-roadmap">Fork it on GitHub</a></p>
<p><a target="_blank" href="https://solidbook.io">Read the book on software design &amp; architecture</a></p>
<p><a target="_blank" href="https://khalilstemmler.com/articles/software-design-architecture/full-stack-software-design/">Read the write-up</a></p>
<hr>
<blockquote>
<p><a target="_blank" href="https://khalilstemmler.com">khalilstemmler.com</a> - I teach Advanced TypeScript &amp; Node.js best practices for large-scale applications and how to write flexible, maintainable software.</p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ When to use TypeScript: a detailed guide through common scenarios ]]>
                </title>
                <description>
                    <![CDATA[ By Khalil Stemmler Strap yourself in. In this guide, we compare when it’s absolutely vital to be using TypeScript, the strictly-typed programming language, and when it makes sense to stick to vanilla JavaScript Have you heard of that little programmi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/when-to-use-typescript-a-detailed-guide-through-common-scenarios-b0a57e57905/</link>
                <guid isPermaLink="false">66d45f709f2bec37e2da062a</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 19 Apr 2019 17:23:29 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*ygOV4sntqZDN8t7u9n-MGw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Khalil Stemmler</p>
<p><em>Strap yourself in. In this guide, we compare when it’s absolutely vital to be using TypeScript, the strictly-typed programming language, and when it makes sense to stick to vanilla JavaScript</em></p>
<p>Have you heard of that little programming language called <strong>TypeScript</strong>? You know, the one that Microsoft made? The one that’s kinda <a target="_blank" href="https://redmonk.com/sogrady/2019/03/20/language-rankings-1-19">blowing up</a>?</p>
<p>Maybe you were like me, a true JavaScript purist. I was doing <em>just fine</em> building things with React and Node without types. Prop types and <a target="_blank" href="https://github.com/hapijs/joi">Joi validation</a> have been treating me just nicely, thank you.</p>
<p>Maybe you caved at some point and gave it a shot. Started playing with it. Maybe you hated it because it reminded you of Java. Maybe you got annoyed with how you couldn’t be super productive right away.</p>
<p>These were some of <strong>my own initial sentiments</strong> when I first started with TypeScript.</p>
<p>I certainly didn’t see the benefit… up until I started experiencing some really annoying stuff. Things like builds not failing when they should, buggy code and typos finding their way into production code somehow in addition to finding it increasingly challenging to express my designs in a really clean object-oriented way.</p>
<p>9 months later into using TypeScript, I’ve built new features in Angular apps for clients, I began compiling <a target="_blank" href="https://univjobs.ca">Univjobs</a>'s React / Redux front-end with TypeScript and ported all of our backend services to TypeScript from vanilla Node.js, refactoring mass amounts of code along the way.</p>
<p>In this article, we’ll take a look at some of the most common scenarios and identify when it might be vital to use TypeScript, and when we could probably just do without it and stick to <em>vanilla</em> JS.</p>
<h3 id="heading-why-this-discussion-matters-today-more-than-ever">Why this discussion matters today more than ever</h3>
<p>I’ve come to the very important conclusion that depending on your situation, context, project, skill level, and other factors, that it’s actually <strong>dangerous</strong> for your project to <strong>NOT</strong> be using TypeScript today.</p>
<p>The front-end space, for one, is getting more and more complex. Certain features that were once considered bleeding-edge, are now very much standard user experience assumptions.</p>
<p>For example, it’s almost always expected that your app is still going to work offline in some capacity. And when users ARE online, it’s also usually expected that they’re going to get real-time notifications without having to refresh the page.</p>
<p>These are some pretty steep (but definitely not unrealistic in 2019) demands.</p>
<p>Before we dive into different scenarios, we should actually talk about the three categories of really hard software problems to be solved.</p>
<h3 id="heading-3-categories-of-hard-software-problems">3 Categories of Hard Software Problems</h3>
<p>Generally speaking, there are three of these. The Performant System Problem, the Embedded System Problem, and the Complex Domain Problem.</p>
<h4 id="heading-1-the-performant-system-problem">1. The Performant System Problem</h4>
<p>Let’s talk about Twitter for a sec.</p>
<p>Twitter is actually a really simple concept.</p>
<p>You sign up, you make tweets, you like other people’s tweets and that’s pretty much it.</p>
<p>If Twitter is that simple, why couldn’t someone else do it?</p>
<p>It’s apparent that the real challenge for Twitter is not actually so much as <strong>what it does</strong>, but it’s <strong>how it’s able to do what it does</strong>.</p>
<p>Twitter has the unique challenge of serving requests from approximately <strong>500 million users every single day</strong>.</p>
<p>The hard problem that Twitter solves is actually a <em>performance problem</em>.</p>
<p>When the challenge is performance, whether or not we use a strictly typed language is much less important.</p>
<h4 id="heading-2-the-embedded-system-problem">2. The Embedded System Problem</h4>
<p>An embedded system is a combination of computer hardware and software, with the purpose of enabling control over the mechanical or electrical aspects of a system.</p>
<p>Most systems we use today are built on a very complex layer of code that, if not initially written in, compiles down to C or C++ usually.</p>
<p>Coding in these languages is not for the faint of heart.</p>
<p>In C, there is no such thing as objects; and we as humans like objects because we can easily understand them. C is procedural and this makes the code that we have to write in this language more challenging to keep clean. These problems also require knowledge of the lower-level details.</p>
<p>C++ does make life a whole lot better because it has object orientation, but the challenge is still fundamentally interacting with lower-level hardware details.</p>
<p>Because we don’t really have that much of a choice on the languages we use for these problems, so it’s irrelevant to consider TypeScript here.</p>
<h4 id="heading-3-the-complex-domain-problem">3. The Complex Domain Problem</h4>
<p>For some problems, that challenge is less about scaling in terms of handling more requests, but scaling in terms of <strong>the codebase’s size</strong>.</p>
<p>Enterprise companies have <strong>complex real-life problems</strong> to be solved. In these companies, the biggest engineering challenges are usually:</p>
<ul>
<li>Being able to <strong>logically</strong> (domains) separate parts of that monolith into smaller apps. And then, <strong>physically</strong> (microservices for bounded contexts) splitting them up so that teams can be assigned to maintain them</li>
<li>Handling integration and synchronization between these apps</li>
<li>Modeling the domain concepts and actually solving the problems of the domain</li>
<li>Creating a <em>ubiquitous</em> (all-encompassing) language to be shared by developers and domain experts</li>
<li>Not getting lost in the mass amounts of code written and slowing down to the point where it becomes impossible to add new features without breaking existing ones</li>
</ul>
<p>I’ve essentially described the types of problems that <a target="_blank" href="https://khalilstemmler.com/articles/domain-driven-design-intro/">Domain-Driven Design</a> solves. For these types of projects, you wouldn’t even think about not using a strictly-typed language like TypeScript.</p>
<h4 id="heading-object-oriented-javascript">Object-oriented JavaScript</h4>
<p>For <strong>Complex Domain</strong> problems, if you don’t choose TypeScript and instead, choose JavaScript, it will require some extra effort to be successful. Not only will you have to be <strong>extra comfortable</strong> with your object modeling abilities in vanilla JavaScript, but you’ll also have to know how to utilize the 4 principles of object-oriented programming (encapsulation, abstraction, inheritance, and polymorphism).</p>
<p>This can be <strong>hard to do</strong>. JavaScript doesn’t naturally come with concepts of interfaces and abstract classes.</p>
<p>“Interface Segregation” from the SOLID design principles isn’t easily achievable with vanilla JavaScript.</p>
<p>Using JavaScript alone would also require a certain level of discipline as a developer in order to keep the code clean, and this is vital once the codebase is sufficiently large. You’re also left to ensure that your team shares the same discipline, experience and knowledge level on how to implement common design patterns in JavaScript. If not, you’ll need to guide them.</p>
<p>In Domain-Driven projects like this, the strong benefit from using a strictly typed language is <strong><em>less</em></strong> about expressing <strong><em>what can be done</em></strong>, but more about using encapsulation and information hiding <strong>to reduce the surface area of bugs</strong> by limiting what domain objects are <strong><em>actually allowed to do</em></strong>.</p>
<p>We can live without this on the front-end, but it’s a <strong>hard language requirement for the</strong> <strong>backend</strong> in my books. It’s also the reason why I moved my Node.js backend services to TypeScript.</p>
<p>There’s a reason why TypeScript is called “<strong>JavaScript that scales</strong>”.</p>
<p>Out of all three categories of hard software problems, only the Complex Domain Problem is the one where TypeScript is an absolute necessity.</p>
<p>Besides this, there are other factors that might determine when it’s best to use TypeScript for your JavaScript project.</p>
<h3 id="heading-code-size">Code size</h3>
<p>Code size usually ties back to the <strong>Complex Domain Problem</strong>, where a large codebase means a complex domain, but that’s not always the case.</p>
<p>When the amount of code a project has gets to a certain size, it becomes <strong>harder</strong> to keep track of everything that exists and becomes <strong>easier</strong> to end up re-implementing something already coded.</p>
<p><strong>Duplication is the enemy to well-designed and stable software.</strong></p>
<p>This is especially heightened when new developers start coding on an already large codebase.</p>
<p>Visual Studio Code’s autocompletion and Intellisense helps to navigate through huge projects. It works really well with TypeScript, but it’s somewhat limited with JavaScript.</p>
<p>For projects that I know will stay simple and small, or if I know that it will be thrown away eventually, I would be less pressed to recommend TypeScript as a necessity.</p>
<h3 id="heading-production-software-vs-pet-projects">Production software vs. pet projects</h3>
<p><strong>Production software</strong> is code that you care about or code that you’ll get in trouble for if it doesn’t work. This is also code that you’ve written tests for. The general rule of thumb is that “if you care about the code, you need to have unit tests for it”.</p>
<p>If you don’t care, don’t have tests.</p>
<p><strong>Pet projects</strong> are self-explanatory. Do whatever you like. You have no professional commitment to uphold any standards of craftsmanship whatsoever.</p>
<p>Go on and make things! Make small things, make big things.</p>
<p>Maybe someday you’ll experience the pain when your pet project turns into your main project which turns into production software, which is buggy because it didn’t have tests or types ? not like I’ve been there or anything…</p>
<h4 id="heading-lack-of-unit-tests">Lack of Unit Tests</h4>
<p>It’s not always possible to have tests for everything, because, well — <strong>life</strong>.</p>
<p>In that case, I’d say that if you don’t have Unit Tests, the next best thing you could have is compile-time checking with TypeScript. After that, if you’re using React, the next best is thing is to use runtime checking with Prop types.</p>
<p>However, compile-time checking is <strong>not a substitute</strong> for having unit tests. The good thing is that unit tests can be written in any language — so the argument for TypeScript here is irrelevant. What’s important is that tests are written and we are confident about our code.</p>
<h3 id="heading-startups">Startups</h3>
<p>Definitely use whatever helps you be most productive.</p>
<p>At this time, the language you choose matters a lot less.</p>
<p>The most important thing for you to do is to <strong>validate your product</strong>.</p>
<p>Choosing a language (Java, for example) or a tool (like Kubernetes) that you heard would help you scale in the future (while being totally unfamiliar with it) may or may not be the best option in the case of a startup.</p>
<p>Depending on how early you are, the most important thing for you to do is to be productive.</p>
<p>In Paul Graham’s famous article, <a target="_blank" href="http://www.paulgraham.com/pypar.html">The Python Paradox</a>, his main point is that startup engineers should just use the technology that maximizes their productivity.</p>
<p>Overall, in this case, use whatever you’re most comfortable with: types or no types. You can always refactor towards a better design once you know you’ve built something people actually want.</p>
<h3 id="heading-working-on-teams">Working on Teams</h3>
<p>Depending on the size of your team and the frameworks you’re using, using TypeScript might be a make or break kind-of-thing.</p>
<h4 id="heading-large-teams">Large teams</h4>
<p>When teams are sufficiently large (because the problems are sufficiently large), it’s a good reason to use an opinionated framework, like Angular for the front-end, and TypeScript for the backend.</p>
<p>The reason why using an opinionated framework is beneficial is because you limit the number of possible ways for people to accomplish something. In Angular, there’s pretty much one main way to add a Route Guard, use Dependency Injection, hook up Routing, Lazy-Loading, and Reactive Forms.</p>
<p>The huge benefit here is that the API is well specified.</p>
<p>With TypeScript, we also save massive amounts of time and make communication efficient.</p>
<p>The ability to quickly determine the required arguments and its return type for any method, or the ability to explicitly describe program intent through public, private, and protected variables alone is incredibly useful.</p>
<p>Yes, some of this is possible with JavaScript, but it’s hacky.</p>
<h4 id="heading-communicating-patterns-amp-implementing-design-principles">Communicating patterns &amp; implementing design principles</h4>
<p>Not only that, but <strong>design patterns</strong>, the solutions to commonly occurring problems in software, are more easily communicated through explicit strictly-typed languages.</p>
<p>Here’s a JavaScript example of a common pattern. See if you can identify what it is.</p>
<pre><code class="lang-js">
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AudioDevice</span> </span>{
  <span class="hljs-keyword">constructor</span> () {
    <span class="hljs-built_in">this</span>.isPlaying = <span class="hljs-literal">false</span>;
    <span class="hljs-built_in">this</span>.currentTrack = <span class="hljs-literal">null</span>;
  }

  play (track) {
    <span class="hljs-built_in">this</span>.currentTrack = track;
    <span class="hljs-built_in">this</span>.isPlaying = <span class="hljs-literal">true</span>;
    <span class="hljs-built_in">this</span>.handlePlayCurrentAudioTrack();
  }

  handlePlayCurrentAudioTrack () {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`Subclasss responsibility error`</span>)
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Boombox</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AudioDevice</span> </span>{
  <span class="hljs-keyword">constructor</span> () {
    <span class="hljs-built_in">super</span>()
  }

  handlePlayCurrentAudioTrack () {
    <span class="hljs-comment">// Play through the boombox speakers</span>
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IPod</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AudioDevice</span> </span>{
  <span class="hljs-keyword">constructor</span> () {
    <span class="hljs-built_in">super</span>()
  }

  handlePlayCurrentAudioTrack () {
    <span class="hljs-comment">// Ensure headphones are plugged in</span>
    <span class="hljs-comment">// Play through the ipod</span>
  }
}

<span class="hljs-keyword">const</span> AudioDeviceType = {
  <span class="hljs-attr">Boombox</span>: <span class="hljs-string">'Boombox'</span>,
  <span class="hljs-attr">IPod</span>: <span class="hljs-string">'Ipod'</span>
}

<span class="hljs-keyword">const</span> AudioDeviceFactory = {
  <span class="hljs-attr">create</span>: <span class="hljs-function">(<span class="hljs-params">deviceType</span>) =&gt;</span> {
    <span class="hljs-keyword">switch</span> (deviceType) {
      <span class="hljs-keyword">case</span> AudioDeviceType.Boombox:
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Boombox();
      <span class="hljs-keyword">case</span> AudioDeviceType.IPod:
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> IPod();
      <span class="hljs-keyword">default</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
    }
  } 
}

<span class="hljs-keyword">const</span> boombox = AudioDeviceFactory
  .create(AudioDeviceType.Boombox);

<span class="hljs-keyword">const</span> ipod = AudioDeviceFactory
  .create(AudioDeviceType.IPod);
</code></pre>
<p>If you guessed <strong>Factory Pattern</strong>, you’re right. Depending on your familiarity with the pattern, it might not have been that obvious to you.</p>
<p>Let’s look at it in TypeScript now. Look at how much more intent we can signify about <strong>AudioDevice</strong> in TypeScript.</p>
<pre><code class="lang-js">abstract <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AudioDevice</span> </span>{
  protected isPlaying: boolean = <span class="hljs-literal">false</span>;
  protected currentTrack: ITrack = <span class="hljs-literal">null</span>;

  <span class="hljs-keyword">constructor</span> () {
  }

  play (track: ITrack) : <span class="hljs-keyword">void</span> {
    <span class="hljs-built_in">this</span>.currentTrack = track;
    <span class="hljs-built_in">this</span>.isPlaying = <span class="hljs-literal">true</span>;
    <span class="hljs-built_in">this</span>.handlePlayCurrentAudioTrack();
  }

  abstract handlePlayCurrentAudioTrack () : <span class="hljs-keyword">void</span>;
}
</code></pre>
<p><strong>Immediate improvements</strong></p>
<ul>
<li>We know the class is abstract <strong>right away</strong>. We needed to sniff around in the JavaScript example.</li>
<li><strong>AudioDevice</strong> can be instantiated in the JavaScript example. This is bad, we intended <strong>AudioDevice</strong> to be an abstract class. And abstract classes shouldn’t be able to be instantiated, they’re only meant to be subclassed and implemented by <a target="_blank" href="https://khalilstemmler.com/wiki/concrete-class/">concrete classes</a>. This limitation is set in place correctly in the TypeScript example.</li>
<li>We’ve signaled the scope of the variables.</li>
<li>In this example, <strong>currentTrack</strong> refers to an interface. As per the <a target="_blank" href="https://khalilstemmler.com/wiki/dependency-inversion/">Dependency Inversion</a> <strong>design principle,</strong> we should always depend on abstractions, not concretions. This isn’t possible in the JavaScript implementation.</li>
<li>We’ve also signaled that any subclasses of <strong>AudioDevice</strong> will need to implement the <strong>handlePlayCurrentAudioTrack</strong> themselves. In the JavaScript example, we exposed the possibility for someone to introduce runtime errors trying to execute the method from either the illegal abstract class or the non-complete concrete class implementation.</li>
</ul>
<p>Takeaway: If you work on a large team and you need to minimize the potential ways someone could misuse your code, TypeScript is a good way to help fix that.</p>
<h3 id="heading-smaller-teams-amp-coding-styles">Smaller teams &amp; coding styles</h3>
<p>Smaller teams are a lot easier to manage coding styles and communication. Paired with linting tools, frequent discussions about how things will get done and pre-commit hooks, I think small teams can be really successful without TypeScript.</p>
<p>I think that success is an equation involving the size of the codebase and the size of the team.</p>
<p><strong>As the codebase grows</strong>, the team might find that they need to rely on some help from the language itself to remember where things are and how they should be.</p>
<p><strong>As the team grows</strong>, they might find they need more rules and restrictions to keep the style consistent and prevent duplicate code.</p>
<h3 id="heading-frameworks">Frameworks</h3>
<h4 id="heading-react-amp-angular">React &amp; Angular</h4>
<p>Much of what draws me and other developers to React is the ability to write code however you want and in an elegant/clever way.</p>
<p>It’s true that React makes you a better JavaScript developer because it forces you to approach problems differently, it forces you to be aware of how <strong>this binding</strong> in JavaScript works and enables you to compose large components out of small ones.</p>
<p>React also allows you to have a bit of your own style. And because of the number of ways I can implement any given task, I will most often write vanilla React.js apps when:</p>
<ul>
<li>the codebase is small</li>
<li>it’s just me coding it</li>
</ul>
<p>And I will compile it with TypeScript when:</p>
<ul>
<li>more than 3 people are coding it, or</li>
<li>the codebase is expected to be very large</li>
</ul>
<p>I will also optionally use Angular for the same reason I will compile React with TypeScript.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>In conclusion, these are my personal opinions on when TypeScript is absolutely necessary and I welcome you to disagree with any of it.</p>
<p>This is what has worked for me in the past when deciding whether or not to use TypeScript. However, today, since I’ve seen the light, it’s not much more effort for me to use TypeScript over vanilla JavaScript as I’m equally comfortable with both and would prefer the type safety.</p>
<p>My final points here are:</p>
<h4 id="heading-you-can-always-gradually-start-using-typescript">You can always gradually start using TypeScript</h4>
<p>Start gradually by adding TypeScript and ts-node to your package.json and utilizing the <strong>allowjs: true</strong>, option in your tsconfig file.</p>
<p>This is how I migrated all of my Node.js apps over time to TypeScript.</p>
<h4 id="heading-compile-time-errors-are-better-than-runtime-ones">Compile time errors are better than runtime ones</h4>
<p>You can’t argue with that. If catching bugs in production code is especially important to you, TypeScript will help you minimize a lot of these.</p>
<h4 id="heading-if-you-are-in-a-position-to-learn-it-learn-it-it-does-wonders-for-your-software-design-skills">If you are in a position to learn it, learn it. It does wonders for your software design skills</h4>
<p>Depending on where you are in your life and your career, you might not have the time to learn it. If you do have the time, I’d recommend you start learning it and start learning about <strong>SOLID design principles</strong> and <strong>software design patterns</strong>. This is the <strong>fastest way to level up as a Junior Developer</strong> in my honest opinion.</p>
<p>I hope this article was useful to you! Are you considering using TypeScript on your next project? Let me know if you agree/disagree in the comments.</p>
<h4 id="heading-learn-enterprise-typescript-amp-javascripthttpskhalilstemlercom"><a target="_blank" href="https://khalilstemler.com">Learn Enterprise TypeScript &amp; JavaScript</a></h4>
<p>Essential software development patterns, principles, and tutorials with modern JavaScript and TypeScript.</p>
<blockquote>
<p>Originally published <a target="_blank" href="http://khalilstemmler.com">April 6th</a> @ <a target="_blank" href="https://khalilstemmler.com"><strong>khalilstemmler.com</strong></a><strong>.</strong></p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What to keep in mind when architecting a system ]]>
                </title>
                <description>
                    <![CDATA[ By Ayelet Sachto Architecture may sound like a “scary ” or overwhelming subject, but actually, applying logic and approaching the problem methodologically simplifies the process drastically. When you architect a system, service, or feature, you actua... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-to-keep-in-mind-when-architecting-a-system-912ec5c6f79/</link>
                <guid isPermaLink="false">66c3660d8e244e167873863a</guid>
                
                    <category>
                        <![CDATA[ Devops ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ System Architecture ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 12 Dec 2018 17:54:27 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*GRF6gYIhUy5WBdbsqLWm3A.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ayelet Sachto</p>
<p>Architecture may sound like a “scary ” or overwhelming subject, but actually, applying logic and approaching the problem methodologically simplifies the process drastically.</p>
<p>When you architect a system, service, or feature, you actually design a <strong>solution</strong> to a problem in a <strong>specific context</strong>. The solution should answer a real need and solve the problem <strong>at hand.</strong></p>
<p>Throughout the text, I’ll be using <strong>solution</strong> in order to emphasize that the <strong>systems, services, and features</strong> we build are part of a bigger <strong>flow</strong>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/i1p8jGfhA263VAS7AsivCRtMxclqCJV36XT5" alt="Image" width="800" height="800" loading="lazy"></p>
<p>When designing a solution think about the entire environment flow you affect.</p>
<ul>
<li>Think about what happens before the data reaches your code</li>
<li>What triggers your feature or service</li>
<li>Who sends it?</li>
<li>Is it something automatic?</li>
<li>Is it a user?</li>
</ul>
<p>This will also help you think about tests and edge cases you want to address, what happens after, who would use it and how.</p>
<h4 id="heading-1understand-the-problem">1.Understand the problem</h4>
<p>Start from understating the problem at hand and understand your boundaries. Don’t optimize for an unknown future, focus on the current situation and most importantly, <strong>don’t make assumptions.</strong> Don’t limit yourself by requirements that are not there.</p>
<blockquote>
<p>Make sure you have all the information you need to understand the problem, don’t be afraid to do research, Google is your friend ;)</p>
</blockquote>
<p><img src="https://cdn-media-1.freecodecamp.org/images/w9FZSfuNF8PsaTT9F8Puxl4mqP1gcDKVTEbI" alt="Image" width="800" height="557" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@rawpixel?utm_source=medium&amp;utm_medium=referral" rel="noopener" target="_blank" title=""&gt;rawpixel on &lt;a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral" rel="noopener" target="<em>blank" title=")</em></p>
<h4 id="heading-2-understand-your-boundaries-and-set-priorities">2. Understand your boundaries and set priorities</h4>
<p>Solution architecture is always a trade-off between concerns, such as resilience, security, data integrity, throughput, scalability, performance and of course cost.</p>
<blockquote>
<p>Think about value vs friction</p>
</blockquote>
<p>Understand your constraints. What are your <strong>must-haves</strong>. If you have a product team, work with them in order to understand the business need, impact and SLA’s. This will help you understand your considerations and limitations better.</p>
<p>Use <strong>data</strong> to make <strong>priorities</strong>, avoid assumptions when possible and be data-driven.</p>
<ul>
<li>How many users?</li>
<li>Number of requests?</li>
<li>Size of requests?</li>
</ul>
<p>Test your service in order to estimate the resources that are needed.</p>
<blockquote>
<p>Make sure you address the maximum rate you want to support and not only the average (look at percentage vs average).</p>
</blockquote>
<p>Think <strong>about</strong> solving the problem and not just <strong>how</strong> to solve it. First think about the solution and only after that think about the implementation. When you free yourself from the expectation of how the solution <strong>should</strong> look like, you understand that a solution can be provided in many forms. It can be a system, service, feature, process or even documentation.</p>
<h4 id="heading-3-ask-why">3. Ask WHY?</h4>
<p>Challenging people and even yourself can be frustrating sometimes. But asking <strong>why</strong> can help you solve the real problem, understand the mandatory requirements and your boundaries, and can help you avoid mistakes and understand the motivation from the business side.</p>
<ul>
<li>Why is it a real pain?</li>
<li>Why should it be done like this?</li>
<li>Why it works like this today?</li>
</ul>
<blockquote>
<p>Challenge yourself and ask questions. It will help make better decisions and better solutions.</p>
</blockquote>
<p><img src="https://cdn-media-1.freecodecamp.org/images/9T5m8DCeqFgZhYxrTs1XjV5MMWIWK42xILAl" alt="Image" width="800" height="533" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@emilymorter?utm_source=medium&amp;utm_medium=referral" rel="noopener" target="_blank" title=""&gt;Emily Morter on &lt;a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral" rel="noopener" target="<em>blank" title=")</em></p>
<h4 id="heading-4-your-solution-is-not-in-a-vacuum">4. Your solution is not in a vacuum</h4>
<p>Context is important. A startup of 4 people that needs to provide MVP and is limited by funds will and should solve a problem differently than a team in a big organization that needs to create a sustainable product that will need to be maintained by several teams.</p>
<p>Going back to my first statement, after you understand the problem think about the context.</p>
<ul>
<li>What are the tools you have at your disposal?</li>
<li>Are you part of a big organization?</li>
<li>Are there any limitations such as time or money?</li>
<li>Who will maintain the solution?</li>
</ul>
<p>Think about what is right for <strong>your</strong> situation, define what <em>production ready</em> means to <strong>you</strong>, and whether it should be highly available (HA). Think about the <a target="_blank" href="https://en.wikipedia.org/wiki/Return_on_investment">ROI</a>. Should you address Edge cases?</p>
<ul>
<li>How would you design a solution that will return values from a database?</li>
<li>And what if I told you that it would be used only once a week until the end of the year. Would it change your answer? Would it affect the design?</li>
<li>If you have 1 day to build a solution would it be the same as if you had a month?</li>
</ul>
<p><strong>Think about growth</strong>. For different solutions and different companies, growth means different things. It can be from a <strong>scale</strong> perspective, such as supporting the growth of additional users. It can also be from a <strong>functionality</strong> perspective, where your solution should be <strong>flexible</strong> to enable other developers to add /modify functionality with ease.</p>
<h4 id="heading-5-cost">5. Cost</h4>
<p>As engineers and developers, we sometimes do not stop to think about the cost of our solutions and services. From my experience it is mostly due to lack of awareness and not willingness.</p>
<p>When we are at university, we are “pumped” with performance and complexity concerns, and taught to think about the efficiency of the solution. But when designing a product that will be used, we need to also think about efficiency with regards to cost. You can build an amazing stable and reliable service that provides value, but if its ROI is not high or if your company won’t be able to afford the cost, it will be axed in favor of other alternatives.</p>
<blockquote>
<p>Remember, performance and infrastructure are not free.</p>
</blockquote>
<h4 id="heading-6-production-deployment-is-only-the-beginning">6. Production deployment is only the beginning</h4>
<p>An important concept that sometimes is neglected is <strong>maintenance</strong>. Is our system or service stable and easy to maintain, debug, troubleshoot and fix?</p>
<p>Production deployment is only the beginning of our solution. Make sure it can be easily maintained, make sure it is production ready and can serve real traffic and users. When developing your solution, think about end to end monitoring, focusing on application monitoring vs. utilization, and make sure to add logging and documentation.</p>
<blockquote>
<p>When designing your solution, think about a simple and easy to maintain design, as much as the requirements allow for it of course.</p>
</blockquote>
<p>As developers, we are sometimes drawn to new “flashy” and trendy technologies. Stop to think whether this technology is mature enough. Could it be maintained in production? Could a different stack be more efficient or offer fewer risks?</p>
<h4 id="heading-wrapping-up">Wrapping up</h4>
<p>To recap, if you want to architect the best solution EVER, start from understanding the problem and your limitations, and know the context of the solution you are trying to design for.</p>
<p>Then think about what happens with your solution after it’s up.</p>
<p>Unless you have unlimited funds (which is never the case), think about your solution’s cost and make sure that it maintainable.</p>
<p>If you liked what you read, be sure to ? it below!</p>
<p>Let me know in the comments ❤ if you like more architecture posts and/or would like me to deep dive about each of the points above.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Multiple Inheritance in C++ and the Diamond Problem ]]>
                </title>
                <description>
                    <![CDATA[ By Onur Tuna Unlike many other object-oriented programming languages, C++ allows multiple inheritance. Multiple inheritance allows a child class to inherit from more than one parent class. At the outset, it seems like a very useful feature. But a use... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/multiple-inheritance-in-c-and-the-diamond-problem-7c12a9ddbbec/</link>
                <guid isPermaLink="false">66c35b9939357f94469765f1</guid>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ programming languages ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sat, 21 Oct 2017 18:03:55 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*QVZomxLNxnRYhm9gGIfYyw.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Onur Tuna</p>
<p>Unlike many other object-oriented programming languages, C++ allows multiple inheritance.</p>
<p>Multiple inheritance allows a child class to inherit from more than one parent class.</p>
<p>At the outset, it seems like a very useful feature. But a user needs to be mindful of a few <em>gotchas</em> while implementing this feature.</p>
<p>In the examples below, we will cover a few scenarios that one needs to be mindful about.</p>
<p>We’ll start with a simple example to explain this concept in C++.</p>
<p>The output of this code is as follows:</p>
<pre><code>I<span class="hljs-string">'m breathing as a snake.I’m crawling as a snake.</span>
</code></pre><p>In the example above, we have a base class named as <strong>LivingThing</strong>. The <strong>Animal</strong> and <strong>Reptile</strong> classes inherit from it. Only the <strong>Animal</strong> class overrides the method <code>breathe()</code>. The <strong>Snake</strong> class inherits from the <strong>Animal</strong> and <strong>Reptile</strong> classes. It overrides their methods. In the example above, there is no problem. Our code works well.</p>
<p>Now, we’ll add a bit of complexity.</p>
<p>What if <strong>Reptile</strong> class overrides the <code>breathe()</code> method?</p>
<p>The <strong>Snake</strong> class would not know which <code>breathe()</code> method to call. This is the “Diamond Problem”.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*cI0TQYv7yOgSsHhfES1Kaw.png" alt="Image" width="563" height="640" loading="lazy"></p>
<h4 id="heading-diamond-problem">Diamond Problem</h4>
<p>Look at the code below. It is like the code in the example above, except that we have overridden the <code>breathe()</code> method in the <strong>Reptile</strong> class.</p>
<p>If you try compiling the program, it won’t. You’ll be staring at an error message like the one below.</p>
<pre><code>member ‘breathe’ found <span class="hljs-keyword">in</span> multiple base classes <span class="hljs-keyword">of</span> different types
</code></pre><p>The error is due to the “Diamond Problem” of multiple inheritance. The <strong>Snake</strong> class does not know which <code>breathe()</code> method to call.</p>
<p>In the first example, only the <strong>Animal</strong> class had overridden the <code>breathe()</code> method. The <strong>Reptile</strong> class had not. Hence, it wasn’t very difficult for the <strong>Snake</strong> class to figure out which <code>breathe()</code> method to call. And the <strong>Snake</strong> class ended up calling the <code>breathe()</code> method of the <strong>Animal</strong> class.</p>
<p>In the second example, the Snake class inherits <strong>two</strong> <code>breathe()</code> methods. The <code>breathe()</code> method of the <strong>Animal</strong> and <strong>Reptile</strong> class. Since we haven’t overridden the <code>breathe()</code> method in the <strong>Snake</strong> class, there is ambiguity.</p>
<p>C++ has many powerful features such as multiple inheritance. But, it is not necessary that we use all the features it provides.</p>
<p>I don’t prefer using multiple inheritance and use <em>virtual</em> inheritance instead.</p>
<p>Virtual inheritance <em>solves</em> the classic “Diamond Problem”. It ensures that the child class gets only a single instance of the common base class.</p>
<p>In other words, the <strong>Snake</strong> class will have only <strong>one</strong> instance of the <strong>LivingThing</strong> class. The <strong>Animal</strong> and <strong>Reptile</strong> classes share this instance.</p>
<p>This solves the compile time error we receive earlier. Classes derived from abstract classes must override the pure virtual functions defined in the base class.</p>
<p>I hope you enjoyed this overview of multiple inheritance and the “Diamond Problem”.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
