<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Carsten Behrens</title>
    <description>The latest articles on DEV Community by Carsten Behrens (@carstenbehrens).</description>
    <link>https://dev.to/carstenbehrens</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F319092%2Fa0129e06-db17-42ee-993b-9c51e3efd980.jpeg</url>
      <title>DEV Community: Carsten Behrens</title>
      <link>https://dev.to/carstenbehrens</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/carstenbehrens"/>
    <language>en</language>
    <item>
      <title>Summary of "A Philosophy of Software Design" by John Ousterhout</title>
      <dc:creator>Carsten Behrens</dc:creator>
      <pubDate>Fri, 29 Dec 2023 11:36:05 +0000</pubDate>
      <link>https://dev.to/carstenbehrens/summary-of-a-philosophy-of-software-design-by-john-ousterhout-c52</link>
      <guid>https://dev.to/carstenbehrens/summary-of-a-philosophy-of-software-design-by-john-ousterhout-c52</guid>
      <description>&lt;p&gt;"A Philosophy of Software Design" is a book written by John Ousterhout.&lt;br&gt;
It summarizes the author's extensive experience in computer science and&lt;br&gt;
his experience of teaching software design at Standford University. The main focus of this book is problem decomposition: "how to take a complex problem and device it up into pieces that can be solved independently." The book provides techniques on how to deal with the complexity of software.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 1 Introduction (It's all about complexity)
&lt;/h2&gt;

&lt;p&gt;In the first chapter, Ousterhout lays out what the book is about. As software systems are not&lt;br&gt;
limited by practical limitations such as physics, the only limit to what we can create is our ability&lt;br&gt;
to read and understand the code we are writing.&lt;/p&gt;

&lt;p&gt;Any program generally gets more complex with time, as new features are always added.&lt;br&gt;
He states that there are two general approaches when fighting complexity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Making code simpler and more obvious"&lt;/li&gt;
&lt;li&gt;"Encapsulate complexity (also called modular design)"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, he explains that, in contrast with physical systems (like bridges and buildings), software systems tend to be more complex, and it isn't possible to fully visualize the design before writing the code.&lt;/p&gt;

&lt;p&gt;Therefore, a waterfall model doesn't work for software, and this is also why an incremental approach like agile&lt;br&gt;
development makes more sense when writing software.&lt;/p&gt;

&lt;p&gt;The developers should constantly consider design issues since incremental development also means incremental software design. The author finds that reducing complexity is the most important element of software design, so the developers should be focusing on that.&lt;/p&gt;

&lt;p&gt;Then, he lays out the two overall goals of the book:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Describing the nature of complexity"&lt;/li&gt;
&lt;li&gt;"Present techniques for minimizing complexity"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;He also emphasizes that since the concepts in the book can be abstract, the book should be used during code reviews. A list of red flags at the end of the book can provide some guidance&lt;br&gt;
during these reviews.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 2 The Nature of Complexity
&lt;/h2&gt;

&lt;p&gt;In this chapter, the author provides us with his definition of complexity.&lt;/p&gt;

&lt;p&gt;He defines complexity as follows: "Complexity is anything related&lt;br&gt;
to the structure of a software system that makes it hard to understand and modify the system."&lt;/p&gt;

&lt;p&gt;The author notes that complexity is experienced more often when reading code than writing code.&lt;br&gt;
Hence, it is crucial to focus on creating code that others can easily understand.&lt;/p&gt;

&lt;p&gt;According to Ousterhout, complexity shows itself in three different ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Change Amplification" which means that a simple change requires changes in many different places&lt;/li&gt;
&lt;li&gt;"Cognitive Load" which refers to how much a developer has to know (or keep in mind)&lt;/li&gt;
&lt;li&gt;"Unknown unknowns" refers to a situation where it is not obvious what files must be modified&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ousterhout states that two things cause complexity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"dependencies"&lt;/li&gt;
&lt;li&gt;"obscurity"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A dependency exists when "a given piece of code can not be understood or modified in isolation."&lt;br&gt;
However, he acknowledges that dependencies are an essential part of software and that they can never be&lt;br&gt;
fully eliminated.&lt;/p&gt;

&lt;p&gt;Nevertheless, one of the goals of software design should be to reduce the amount of dependencies as&lt;br&gt;
much as possible, or at least make the remaining dependencies as obvious and straightforward as possible.&lt;/p&gt;

&lt;p&gt;An Obscurity exists when "important information is not obvious."&lt;/p&gt;

&lt;p&gt;This can happen due to various reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A non-obvious dependency between two parts of the code base&lt;/li&gt;
&lt;li&gt;Inconsistency&lt;/li&gt;
&lt;li&gt;Missing documentation (while keeping in mind that a need for extensive documentation could be a red flag in itself)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ousterhout notes that complexity builds up slowly over time and is hard to eliminate once it has&lt;br&gt;
accumulated. Therefore, he suggests "zero tolerance" towards complexity.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 3: Working Code Isn't Enough (Strategic vs. Tactical Programming)
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout identifies the difference between "Tactical Programming" and "Strategic Programming".&lt;/p&gt;

&lt;p&gt;Tactical Programmer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gets stuff done fast&lt;/li&gt;
&lt;li&gt;Doesn't care about complexity building up&lt;/li&gt;
&lt;li&gt;Introduces complexity to the system over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Strategic Programmer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focuses on good design while also having working code&lt;/li&gt;
&lt;li&gt;Has an investment mindset&lt;/li&gt;
&lt;li&gt;Doesn't increase complexity and tries to reduce it constantly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;He suggests spending 10 to 20% of development time on "investments." He argues that this investment will start to pay off within a few months, after which the velocity will increase by 10-20%, meaning that&lt;br&gt;
the investment will pay off quickly.&lt;/p&gt;

&lt;p&gt;Ousterhout also acknowledges that this "investment" approach is not suited well for early start-ups but that the "tactical" approach hurts a company in the medium to long run.&lt;br&gt;
Finally, he concludes that a tactical approach will speed up the first product launch since the payoff from good design comes so quickly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 4: Modules Should Be Deep
&lt;/h2&gt;

&lt;p&gt;In this chapter, the author presents the basic principles of "modular design" while introducing the concept of "deep modules."&lt;/p&gt;

&lt;p&gt;Ousterhout notes that one of the most important techniques for managing complexity is to ensure that developers only focus on a small amount of complexity at a time.&lt;/p&gt;

&lt;p&gt;In modular design, a system is decomposed into smaller - relatively independent - modules.&lt;br&gt;
A module can be anything, for example, a class, a sub-system, or a service. Ideally, all of our modules would be completely&lt;br&gt;
independent of each other. Ousterhout acknowledges, however, that there will always be dependencies between modules in the real world.&lt;br&gt;
Still, the goal of modular design should be to minimize dependencies between modules.&lt;/p&gt;

&lt;p&gt;He states that each module has two parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An interface, which refers to the knowledge that a developer needs to work with the module&lt;/li&gt;
&lt;li&gt;an implementation, which refers to the actual implementation of the module&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;He also defines that anything with an interface and an implementation is a module for this book's purpose.&lt;br&gt;
This would include classes but also methods and functions (and also other services or sub-systems).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's in an interface?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;He explains that an interface has two kinds of information: formal and informal.&lt;/p&gt;

&lt;p&gt;The formal parts of an interface (such as method parameters) can be checked for correctness by the programming language.&lt;br&gt;
The informal parts cannot be understood or enforced by the programming language. An example of this could be a function that&lt;br&gt;
deletes a file named in one of its arguments. If a developer needs to know any information besides the formal parts, this information is part of the module's interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deep Modules&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout argues that the best modules "provide powerful functionality yet have simple interfaces."&lt;br&gt;
These modules are "deep," meaning they hide much of their complexity from other modules through simple interfaces.&lt;/p&gt;

&lt;p&gt;Deep modules are a good abstraction because only a small amount of the module's complexity is exposed to other modules.&lt;br&gt;
The depth of a module also describes its usefulness. The module's functionality should be weighed against the complexity&lt;br&gt;
of its interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shallow Modules&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The opposite of a deep module is a shallow module. Its interface is relatively complex when compared to the functionality&lt;br&gt;
the module provides.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Classitis&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout notes that his view of deep modules vs. shallow modules differs from that of many developers today.&lt;br&gt;
Many developers have the view that classes should be small, not deep. Ousterhout claims that this approach often leads to a lot of shallow classes, which increases the overall complexity of the system. Ousterhout invented a new syndrome called "classitis" for extreme forms of this programming style.&lt;/p&gt;

&lt;p&gt;"Classitis" helps to create simple classes, but the overall system complexity increases when using this coding style:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Since small classes only provide a little functionality, you'll need a lot of them - each with its own interface.&lt;/li&gt;
&lt;li&gt;All these small classes accumulate to create a lot of overall complexity&lt;/li&gt;
&lt;li&gt;Having a lot of small classes is more verbose than having fewer larger classes due to the boilerplate required for each class&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example: Java and Unix I/O&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;He believes that an example of this "classitis" is the Java class library. Java in itself doesn't require lots of small classes, but Ousterhout believes that a culture of "classitis" has affected the Java programming community.&lt;/p&gt;

&lt;p&gt;To illustrate this, he shows us an example of how to open a file in order to create a serialized object from it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;FileInputStream&lt;/span&gt; &lt;span class="n"&gt;fileStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileInputStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;BufferedInputStream&lt;/span&gt; &lt;span class="n"&gt;bufferedStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BufferedInputStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileStream&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;ObjectInputStream&lt;/span&gt; &lt;span class="n"&gt;objectStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectInputStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bufferedStream&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;He explains that the FileInputStream object only provides I/O but is incapable of performing buffered I/O, nor can it read or write a serialized object. To enable buffered I/O, it is required to add buffering by creating a BufferedInputStream object. Finally, the ObjectInputStream adds the ability to read and write serialized objects.&lt;br&gt;
Ousterhout notes that the FileInputStream and the BufferedInputStream objects are never used once the file has been opened.&lt;br&gt;
He finds it annoying (and error-prone) that the developer must always remember to create a BufferedInputStream because otherwise, there will be no buffering, and I/O will be slow.&lt;br&gt;
Ousterhout acknowledges that some users might not need or want buffering, but in his opinion, "interfaces should be designed to make the most common case as simple as possible." Buffering should be the default since most users require it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 5: Information Hiding (and Leakage)
&lt;/h2&gt;

&lt;p&gt;In this chapter, the author shares one of the techniques for creating deep modules.&lt;/p&gt;

&lt;p&gt;According to Ousterhout, information hiding is the most crucial idea to remember while creating deep modules. Information hiding means that each module should encapsulate some functionality.&lt;br&gt;
The only thing visible from the outside of the module is its interface. This means that the implementation of the functionality is hidden.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Information Hiding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Information hiding is so essential because it reduces complexity in two significant ways. First, it simplifies the interface of a module since the module provides its users with a simpler and more abstract view of the module's functionalities.&lt;br&gt;
Second, it reduces dependencies between the modules. For example, if a change is required, but it only affects the parts of the module that are hidden, then that change only affects this module and no other modules that may depend on it.&lt;/p&gt;

&lt;p&gt;Ousterhout suggests carefully considering what information can be hidden when creating a module.&lt;br&gt;
If it is possible to hide a piece of information, then it should also be possible to simplify the module's interface, thus&lt;br&gt;
making it deeper.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Information Leakage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The opposite of information hiding is information leakage. "Information Leakage occurs when a design decision is reflected in multiple modules." When information is leaked, other modules that use the affected module will start to depend on this information, thus creating a dependency between modules.&lt;/p&gt;

&lt;p&gt;Ousterhout notes that if a piece of information is part of the interface of a module, then it is leaked. However, there are other ways information can be leaked. As an example, Ousterhout describes a situation where two classes have knowledge of a file format (one class could be reading the file in that format while the other writes to the file)&lt;br&gt;
then this information - the file format - is leaked between the two classes. This type of information leakage is called&lt;br&gt;
Back-door leakage is the worst type of information leakage since it is not obvious.&lt;/p&gt;

&lt;p&gt;He argues that information leakage is one of software design's most important red flags. He suggests that one should ask oneself, "How can I reorganize these classes so that this particular piece of knowledge only affects&lt;br&gt;
a single class?"&lt;/p&gt;

&lt;p&gt;To do this, it can make sense to combine smaller classes into a bigger one or to pull out all the information and&lt;br&gt;
create a new class that encapsulates just that information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Information hiding within a class&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Information hiding can also be applied to methods in a class, which means that a private method within a class should encapsulate some information and hide it from the rest of the class.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 6 General-Purpose Modules are Deeper
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout tackles the question of how generic or specific modules should be.&lt;br&gt;
According to Ousterhout, the general-purpose approach is more consistent with the investment mindset mentioned in Chapter 3. Still, he acknowledges that the special-purpose approach aligns more with the agile way of developing software today.&lt;/p&gt;

&lt;p&gt;He thinks that the best solution is the sweet spot between general-purpose and special-purpose. This means that a module should provide the features that are needed today while also offering an interface that is general enough to support&lt;br&gt;
multiple use cases.&lt;/p&gt;

&lt;p&gt;To illustrate this, Ousterhout provides an example from his software design class where students were asked to build a simple text editor. Many student projects had a &lt;code&gt;Text&lt;/code&gt; class that provided methods for - among other things - modifying the text file.&lt;/p&gt;

&lt;p&gt;Some projects created a special-purpose method for each text editing feature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;backspace&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Cursor&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Cursor&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;deleteSelection&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Selection&lt;/span&gt; &lt;span class="n"&gt;selection&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Due to this approach, the class had a large amount of shallow methods, each of which was only usable for one of the required features. This also leaked information between the user interface and the &lt;code&gt;Text&lt;/code&gt; class&lt;br&gt;
since the &lt;code&gt;Text&lt;/code&gt; class had knowledge of the user interface. This is not good because it creates a dependency between the two modules.&lt;/p&gt;

&lt;p&gt;A better solution for this would be to make the &lt;code&gt;Text&lt;/code&gt; class more generic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Cursor&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Cursor&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this interface, the &lt;code&gt;Text&lt;/code&gt; class could be reused for other purposes than an editor. This solution is also better because it provides better information hiding. There is no need for the &lt;code&gt;Text&lt;/code&gt; class to&lt;br&gt;
be aware of the UI-specific features such as backspace or delete.&lt;/p&gt;

&lt;p&gt;Ousterhout finds that general-purpose interfaces tend to have simpler interfaces than special-purpose ones.&lt;br&gt;
They also provide better separation between the classes than special-purpose interfaces that tend to leak information between classes.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 7 Different Layer, Different Abstraction
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout describes how abstractions should change on each system layer and how to refactor your code base if this is not the case. Software systems are composed of layers, where higher&lt;br&gt;
layers use the functionality provided by lower layers. Ousterhout argues that in a well-designed system, each layer should provide a different abstraction than the layer above or below it. This means that if you follow a single operation through the layers, the abstraction should change with each method call.&lt;/p&gt;

&lt;p&gt;The opposite would be the case when the abstractions are not changing or are very similar. According to Ousterhout, this red flag indicates a problem with the separation of classes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pass-through methods&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One way this problem manifests itself is in the form of pass-through methods. A pass-through method is a method that does very little besides passing the arguments on to the next method, whose signature is similar to that of the calling method.&lt;/p&gt;

&lt;p&gt;Ousterhout notes that a method with the same interface is not always bad, but each method should add some&lt;br&gt;
functionality. Pass-through methods do not provide additional functionality; thus, they are bad.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decorators&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, Ousterhout describes the decorator design pattern. According to Ousterhout, a decorator object is an object that extends an existing object while providing a similar interface. An example is the &lt;code&gt;BufferedInputStream&lt;/code&gt; class shown in Chapter 4.&lt;/p&gt;

&lt;p&gt;The purpose of decorator classes is to extend core classes to fit a more specific use case.&lt;br&gt;
However, according to Ousterhout, they tend to be shallow because they add a large amount of boilerplate code (many pass-through methods) for a relatively small amount of new functionality.&lt;/p&gt;

&lt;p&gt;Therefore, decorator classes should be kept to a minimum. Ousterhout suggests to &lt;strong&gt;consider&lt;/strong&gt; alternatives such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding the new functionality directly to the underlying class&lt;/li&gt;
&lt;li&gt;Add the new functionality to an already existing decorator class&lt;/li&gt;
&lt;li&gt;Create a whole new class&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Interface versus Implementation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout argues that the interface of a class should be different from its implementation. This means that the representation used internally should differ from the abstractions in the interface.&lt;/p&gt;

&lt;p&gt;To illustrate this, Ousterhout presents another example from his software design class text editor project. The &lt;code&gt;Text&lt;/code&gt; class usually &lt;strong&gt;stored&lt;/strong&gt; the text in lines within the file. Some of the teams also designed&lt;br&gt;
the &lt;strong&gt;interface&lt;/strong&gt; of the &lt;code&gt;Text&lt;/code&gt; class around lines, with methods like &lt;code&gt;getLine&lt;/code&gt; and &lt;code&gt;putLine.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;However, this interface leads to problems because sometimes text gets inserted in the middle of a line, which means that the callers of this class have to split and join texts. The &lt;code&gt;Text&lt;/code&gt; class was much easier to use when&lt;br&gt;
it provided a character-oriented interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pass-through&lt;/strong&gt; variables&lt;/p&gt;

&lt;p&gt;According to Ousterhout, a Pass-through variable is "a variable which is passed down a long chain of methods."&lt;br&gt;
They add complexity because all intermediate methods must be aware of them even though they might not use the variable themselves. This also means that if you need to change this variable or add a new one, you must modify many methods.&lt;/p&gt;

&lt;p&gt;He notes that it can be challenging to remove pass-through variables. One approach to do this is to see if an object is already shared by the topmost and bottommost methods. If this is the case, one can&lt;br&gt;
store the needed information in that object. Another option is storing the information in a global variable, although this typically creates other problems.&lt;/p&gt;

&lt;p&gt;Ousterhout finds the most fitting solution in most situations is using a context object, one per instance of the system. The context object will allow multiple system instances to coexist in a single process. Still&lt;br&gt;
Ousterhout warns that contexts are far from an ideal solution and that without discipline, a "context can turn into a huge grab-bag of data that creates nonobvious dependencies throughout the system."&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 8 Pull Complexity Downwards
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout introduces another way of thinking about deeper classes. He argues that a module developer should always strive to make using the module as easy as possible. This also means that one should handle complexity internally within the module when possible, which means that we are pulling complexity downwards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configuration parameters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;According to Ousterhout, configuration parameters are an example of moving complexity upwards. Instead of defining the behavior internally, a module can export a few parameters that control its behavior. Users of that module now have to configure these parameters and deal with the complexity that comes with that.&lt;/p&gt;

&lt;p&gt;Ousterhout recognizes that these parameters can be useful because they allow the user of a module to configure the module to their particular requirements. However, they can also easily be used as an excuse not to deal with complexity internally and pass it to the user of the module instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Taking it too far&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout warns that pulling complexity upwards should be done with discretion and that it can easily be overdone.&lt;br&gt;
Pulling complexity downwards makes sense if it results in the overall reduction of complexity. For example, if the complexity being pulled down simplifies the class's interface,&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 9 Better Together Or Better Apart
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout discusses the fundamental question of whether two pieces of functionality should be implemented&lt;br&gt;
together or apart. According to Ousterhout, this question applies to all levels of the system, such as functions, methods, classes, and services.&lt;/p&gt;

&lt;p&gt;The goal, as always, is to reduce the overall complexity of the system as a whole. To do this, it is tempting to divide the system into many small components since the smaller the component, the simpler it will likely be.&lt;/p&gt;

&lt;p&gt;The problem with this approach is that it leads to a high number of components. The more components, the harder it will be to manage them all. This also means the system will need additional code just to manage the components.&lt;br&gt;
Another disadvantage of this approach is that we now have multiple components instead of having one component.&lt;br&gt;
This can make it harder for developers to change the system because they have to modify and be aware of various components instead of one.&lt;/p&gt;

&lt;p&gt;If the components are truly independent and don't have many dependencies between them, then this subdivision is good.&lt;br&gt;
Otherwise, it is bad. According to Ousterhout, this will cause developers to need to know a lot of components, which causes a higher cognitive load. It can also lead to bugs if developers are unaware of these dependencies.&lt;/p&gt;

&lt;p&gt;Ousterhout notes that bringing together pieces of code is most beneficial if they are closely related.&lt;/p&gt;

&lt;p&gt;He also lists a few tips on how to notice that this is the case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They share the same information. For example, if both share some knowledge about a file format&lt;/li&gt;
&lt;li&gt;They are used together, meaning that users of this piece of code also often use the other&lt;/li&gt;
&lt;li&gt;They overlap conceptually, meaning that both of the pieces of code are part of a higher-level category&lt;/li&gt;
&lt;li&gt;It is hard to understand one of the pieces of code without looking at the other&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Separate general-purpose and special-purpose&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, Ousterhout explains that when a module contains a functionality that can be used for several other purposes, it should only provide this functionality and no other special-purpose code. This allows the module to be independent and reusable in other modules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Splitting and joining methods&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;According to Ousterhout, the same questions also apply to methods. Ousterhout finds that - contrary to popular belief - long methods are not always bad. He believes a method containing five 20-line blocks of code is acceptable as long as the blocks are relatively independent and executed in order. This would mean that the method can be read one block at a time; thus, there would not be a benefit in moving the blocks into separate methods.&lt;br&gt;
He explains that this is especially true when the blocks have complex interactions. Because the developer needs to see all the code at once. If they would be in different methods, the developer that works on the&lt;br&gt;
code would be forced to switch back and forth to understand how they work together.&lt;/p&gt;

&lt;p&gt;Next, he applies the idea of deep modules to methods. He finds that a method containing hundreds of lines of code is fine if it has a simple interface because this would mean that the method is 'deep.'&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 10 Define Errors Out Of Existence
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout discusses exception handling and why exceptions contribute disproportionately to complexity and&lt;br&gt;
how to simplify exception handling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why exceptions add complexity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout notes that, exception-handling code is more complex to write than regular code because exceptions tend to disrupt the normal flow of the code. When an exception occurs, a developer can either move forward to the next step regardless of the exception or abort the operation and throw an error. As the error gets reported 'upwards,' the developer must eventually find a way to handle the exception. Ousterhout states that exceptions usually don't occur often in running systems, so the error handling code is not executed often. Thus, bugs can sometimes go undetected for a long time.&lt;/p&gt;

&lt;p&gt;To prove his point, Ousterhout cites a study that found that more than 90% of catastrophic failures in distributed data-intensive systems were caused by incorrect error handling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Too many exceptions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout states that one of the reasons that problems related to exception handling increase is that developers&lt;br&gt;
define too many unnecessary exceptions. According to Ousterhout, most developers are taught that detecting and reporting errors is essential, but some take this to the extreme.&lt;/p&gt;

&lt;p&gt;As an example, Ousterhout describes an error he himself made while designing the Tcl scripting language.&lt;br&gt;
The Tcl scripting language had a command called &lt;code&gt;unset,&lt;/code&gt; which is used to remove a variable. The command throws an error if the variable that should be deleted doesn't exist. Ousterhout explains that he thought that when someone tries to remove a variable that doesn't exist, it must be a bug, and therefore it should be reported. However, he did not&lt;br&gt;
foresee that the most common use case of &lt;code&gt;unset&lt;/code&gt; would be the clean-up of temporary state after a previous operation. Unfortunately, it is often hard to predict the state of a variable at the time of clean-up, especially&lt;br&gt;
after an operation was aborted. Thus, most developers will try to reset all variables regardless of their current state.&lt;/p&gt;

&lt;p&gt;Since &lt;code&gt;unset&lt;/code&gt; throws an error when the variable doesn't exist, developers end up enclosing every unset call with a&lt;br&gt;
catch statement to ignore all errors thrown by it.&lt;/p&gt;

&lt;p&gt;Ousterhout views this design decision as one of his biggest mistakes when designing Tcl.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Define errors out of existence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout suggests that the best way to deal with exception-handling complexity is to define your interfaces so that no exceptions need to be thrown. He calls this "define errors out of existence."&lt;/p&gt;

&lt;p&gt;As an example, he circles back to the &lt;code&gt;unset&lt;/code&gt; command discussed above. Ousterhout states that he should have used a better definition for the &lt;code&gt;unset&lt;/code&gt; command. Instead of deleting the variable, the &lt;code&gt;unset&lt;/code&gt; command should be defined as ensuring that the variable no longer exists. With the first definition (deleting), the &lt;code&gt;unset&lt;/code&gt; command can't do its job&lt;br&gt;
if the variable doesn't exist. With the second definition (ensuring that the variable doesn't exist), the unset command could just do nothing if it doesn't exist. Meaning that it would not have to throw an error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mask exceptions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, Ousterhout describes the second technique for reducing the number of places exceptions must be handled: Exception masking. The basic idea of this technique is that the lower module handles the error so that the higher-level modules don't need to do it.&lt;/p&gt;

&lt;p&gt;He provides TCP as an example since TCP masks packet loss by simply resending lost packets. So that clients are unaware that a problem has occurred.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exception aggregation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, Ousterhout describes the third technique, "exception aggregation." The idea behind exception aggregation is to handle many exceptions with a single piece of code. Instead of having to write exception handlers for each exception, handle them all with a single handler.&lt;/p&gt;

&lt;p&gt;As an example, Ousterhout describes the error handling for a missing parameter in a web server. Typically, a service&lt;br&gt;
method will call a low-level method (e.g., &lt;code&gt;getParameter&lt;/code&gt;) to get the needed parameters. This method will throw an error if the requested parameter does not exist.&lt;/p&gt;

&lt;p&gt;When the students of his software design class implement this, many of them wrap the &lt;code&gt;getParameter&lt;/code&gt; call in an exception handler. This approach resulted in a large number of methods that essentially did the same thing - generating an error response.&lt;/p&gt;

&lt;p&gt;Ousterhout suggests a better approach would be to let the errors propagate up to the top-level dispatch method and handle them there. Thus, a single handler could catch all of the &lt;code&gt;ParameterNotFound&lt;/code&gt; exceptions and generate the error response.&lt;/p&gt;

&lt;p&gt;He highlights that this and the &lt;strong&gt;Mask exceptions&lt;/strong&gt; approach - even though they are both the opposite - both aim to reduce places where exception handlers would be otherwise created.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Just crash?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The final technique that Ousterhout describes is just to let the application crash. These errors are either impossible to handle or not worth trying to handle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Taking it too far&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout warns that the "masking" and the "defining out of existence" techniques only make sense if the exception information&lt;br&gt;
is not needed outside the module. He stresses that when something is important, it should be exposed.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 11 Design it twice
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout argues that one should consider multiple options before deciding on a major design.&lt;br&gt;
To help find the best design, he suggests that one approach the problem from different angles. Then, after one has&lt;br&gt;
designed the alternatives, one should make a list of pros and cons to find the best one. He also provides a few questions&lt;br&gt;
that one should ask oneself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Does one alternative have a simpler interface than another?"&lt;/li&gt;
&lt;li&gt;"Is one interface more general-purpose than another?"&lt;/li&gt;
&lt;li&gt;"Does one interface enable more efficient implementation than another?"&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Chapter 12 Why Write Comments? The Four Excuses
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout points out the excuses developers use to avoid writing comments and why comments play a crucial&lt;br&gt;
role in software design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Good code is self-documenting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout states that some people believe a code does not need comments if it is well-written.&lt;br&gt;
He calls this a "delicious myth". He believes that the informal aspects of an interface can only be described in comments.&lt;br&gt;
According to Ousterhout, there are many other reasons as to why comments make sense. For example, one could explain the rationale behind the code or give a high-level explanation of a method.&lt;/p&gt;

&lt;p&gt;Comments also save time. For example, it's faster to understand what a method does by reading its description than&lt;br&gt;
by reading the methods code. Another reason for comments is that they allow us to provide additional information to the&lt;br&gt;
user of a module.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. I don't have time to write comments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout observes that although it is tempting to de-prioritize writing comments, they provide a massive difference in maintainability and that the effort spent on them pays off quickly. It is the same investment mindset that is discussed in previous chapters that also applies here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Comments get out of date and become misleading&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout suggests that code reviews should fix this issue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. All the comments I have seen are worthless&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Although Ousterhout agrees that some comments are worthless, he suggests that writing good comments is easy once one knows how to write them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits of well-written comments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In summary, Ousterhout concludes that the idea comments should "capture information that was in the mind of the designer but couldn't&lt;br&gt;
be represented in the code." He argues that good comments save future developers time because they will be able to understand&lt;br&gt;
the intent behind the code better. Therefore, good documentation reduces &lt;strong&gt;Cognitive load&lt;/strong&gt; and helps to reduce &lt;strong&gt;Unknown unknowns&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 13 Comments Should Describe Things that Aren't Obvious from the Code
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout discusses what information needs to be described and how to write good comments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pick conventions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout mentions that it is important to pick conventions that decide what and how you will comment.&lt;/p&gt;

&lt;p&gt;The most important comments are the interface and the data structure member (e.g., a class variable or a method)&lt;br&gt;
comments. According to Ousterhout, every class interface, variable, and method should have a comment.&lt;br&gt;
Although occasionally, the declaration of a variable is so obvious that a comment would be redundant, he finds it easier to comment it anyway instead of worrying whether a comment is really needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't repeat the code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout states that many comments are not helpful because they repeat the code. It is not very useful if all the information can be easily deducted from the code &lt;strong&gt;next to&lt;/strong&gt; the comment.&lt;/p&gt;

&lt;p&gt;Then, he provides a few examples of bad comments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Add a horizontal scroll bar&lt;/span&gt;
&lt;span class="n"&gt;hScrollBar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JScrollBar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JScrollBar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Horizontal&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hScrollBar&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BorderLayout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SOUTH&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Add a vertical scroll bar&lt;/span&gt;
&lt;span class="n"&gt;vScrollBar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JScrollBar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JScrollBar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Vertical&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vScrollBar&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;BorderLayout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EAST&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Initialize the caret-position values&lt;/span&gt;
&lt;span class="n"&gt;caretX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;caretY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;caretMemX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These comments don't add any information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
 * obtain a normalized resource name from req.
 */&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;getnormalizedresourcenames&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;httprequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="cm"&gt;/*
 * downcast parameter to type.
 */&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="nf"&gt;downcastparameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="cm"&gt;/*
 * the horizontal padding of each line in the text.
 */&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;texthorizontalpadding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the sentences are just made up of the words and the variable names. This is a good indication that a comment isn't helpful.&lt;/p&gt;

&lt;p&gt;A first step to writing better comments is to use different words than the words that are already present in the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
 * The amount of blank space to leave on the left and right sides of each line
 * of text, in pixels.
 */&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;textHorizontalPadding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we use a word different from "padding" because some people might not know what it means.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lower-level comments add precision; higher-level comments enhance intuition&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, Ousterhout explains that comments should be on a different level of detail than the code.&lt;br&gt;
A comment can either be on a higher-level, a lower-level, or the same level as the code.&lt;br&gt;
A lower-level comment is a comment that is more detailed than the code. A higher-level comment provides high-level&lt;br&gt;
information about the code, such as the rationale behind the code.&lt;/p&gt;

&lt;p&gt;Ousterhout notes that comments on the same level will likely repeat the code. Comments on a higher level provide intuition by helping us understand the code's overall intent and rationale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interface documentation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;According to Ousterhout, the most important role of comments is to describe the abstraction an interface provides.&lt;br&gt;
He recalls his definition of abstraction as a "simplified view of an entity, which preserves essential information but omits details that can safely be ignored." He argues that since code isn't able to describe abstracts at a high level, one must provide comments to document the abstraction.&lt;/p&gt;

&lt;p&gt;He distinguishes between interface comments and implementation comments. An interface comment is a comment that provides&lt;br&gt;
information about a class or method for the user who wants to use it. The implementation comments, on the other hand, describe how a class or method works internally to implement the functionality. Ousterhout notes that it is crucial to separate these two comments so that the user of an interface is not confronted with the implementation details.&lt;/p&gt;

&lt;p&gt;He provides an example of an interface comment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * This class implements a simple server-side interface to the HTTP protocol:
 * by using this class, an application can receive HTTP requests, process them, and
 * and return responses. Each interface of this class corresponds to a particular
 * socket used to receive requests. The current implementation is single-threaded and
 * processes one request at a time.
 */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Http&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Implementation comments: what and why, not how&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout explains that, implementation comments are the comments that appear within the methods of a class that help the readers understand how it works and what it is doing. Although the focus should not be on &lt;strong&gt;how&lt;/strong&gt; something is done, the focus is &lt;strong&gt;what&lt;/strong&gt; and &lt;strong&gt;why&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross-module design decisions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout states that real systems often end up with design decisions that affect multiple classes. As an example of this&lt;br&gt;
he names the design decisions of a network protocol that affect both the sender and the receiver, which may be implemented in different places.&lt;/p&gt;

&lt;p&gt;This can make it hard to decide where the best place to document these design decisions is.&lt;br&gt;
In a case like this, Ousterhout suggests putting the documentation in a place that will naturally be discovered by&lt;br&gt;
a developer working on these classes. If there is no obvious place like that, he suggests having a file called &lt;strong&gt;designNotes&lt;/strong&gt;&lt;br&gt;
that is divided up with labels for each major design decision.&lt;/p&gt;

&lt;p&gt;Then, in the code related to this design decision, he suggests putting a comment referring to the &lt;strong&gt;designNotes&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// See 'topic' in designNotes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ousterhout notes that one disadvantage is that the documentation is not close enough to the code, so keeping it up to date with the code could be difficult.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 14 Choosing Names
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout discusses naming things, which, according to Ousterhout, is one of the most underrated aspects of software design. When variables - and classes, methods, and so on - have good names, it is easier to understand the code because they act like a form of documentation and thus make the code more obvious.&lt;/p&gt;

&lt;p&gt;The opposite is true about bad names since poor name choices increase the complexity of the code and can lead to misunderstandings, which can result in bugs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: bad names cause bugs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As an example of a bug due to bad naming, Ousterhout recalls the most challenging bug he ever fixed.&lt;br&gt;
At the time, he was working on an operating system called Sprite. A bug occurred randomly where some files would lose data.&lt;br&gt;
The bug was quite simple but was very hard to find because the naming of the variable was ambiguous. The file system code used the variable name &lt;code&gt;block&lt;/code&gt; for two different things. Sometimes, the name &lt;code&gt;block&lt;/code&gt; would refer to a physical block on a disk, and sometimes it would refer to a logical block within a file. At one point in the code, there was a mix-up due to this naming, which caused an unrelated block on the disk&lt;br&gt;
to be overwritten with zeros.&lt;/p&gt;

&lt;p&gt;Ousterhout notes that a more precise naming, such as &lt;code&gt;fileBlock&lt;/code&gt; and &lt;code&gt;diskBlock&lt;/code&gt; could have prevented this bug. Hence, he suggests that one should take extra time to choose great names which are precise, unambiguous, and intuitive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Names should be precise&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout finds that a name must be precise and consistent for it to be good. The most common problem with variable names is that most of them are too generic and not precise enough. If a name is too broad, it may be confused with other things, which it is not. Ousterhout notes that if one has trouble coming up with a good name for a variable,&lt;br&gt;
this could indicate that the variable may need a more straightforward definition or purpose. For example, a variable could be used to represent too many things; in that case, it would make sense to separate it into multiple variables.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 15 Write The Comments First (Use Comments as Part of The Design Process)
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout discusses how comments can help during the design process and why writing them as one writes the code is essential.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Delayed comments are bad comments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;He states that almost every developer he has met puts off writing documentation. This is a problem because once this process is delayed, it often means that the documentation does not get written at all. Ousterhout argues that&lt;br&gt;
even if it does eventually get done, the quality of the documentation will not be the same because the developer will have&lt;br&gt;
forgotten some of the details of the design process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write the comments first&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead, he suggests writing the comments before implementing the code. For a new class, he starts by writing the class interface comment. Next, he will write the interface comments and signatures for the most important public methods. Then, he will iterate a bit until the comments and the basic structure of the class feel right. At that point,&lt;br&gt;
he will write the declarations and comments for the most important instance variables. As the last step, he will implement the methods and add the implementation comments.&lt;/p&gt;

&lt;p&gt;With this approach, there will never be a backlog of unwritten comments. According to Ousterhout, this approach has three&lt;br&gt;
benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It produces better comments&lt;/li&gt;
&lt;li&gt;Design decisions are still fresh on one's mind, so there is no need to remember things&lt;/li&gt;
&lt;li&gt;It's easier to focus on the abstraction and the interface of a method when writing the comment first without having
to worry about its implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Comments are a design tool&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An important benefit of writing comments at the beginning, which Ousterhout mentions, is that it improves the system design.&lt;br&gt;
When writing a comment, one can think about the abstraction before actually implementing it.&lt;br&gt;
Also, comments are essential to good system design because they provide the only way to describe the abstraction fully. The very act of writing a good comment forces one to identify the essence of a variable or a piece of code, which also helps improve the overall system design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Early comments are fun&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another benefit that Ousterhout mentions is that for him, one of the most enjoyable part of programming is the early design phase, where he can think about the abstraction and structure of the class. Ousterhout argues that writing comments during this phase is more fun.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 16 Modifying Existing Code
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout shares his views on modifying existing code. He argues that since software development is iterative and incremental, the final design of a system is more influenced by the design decisions that were made during the systems&lt;br&gt;
evolution than the initial design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stay strategic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;He warns that one must resist the temptation to make quick fixes. Instead, one should consider if the system's current design is still the best for its job and change it if it's not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Maintaining comments: keep the comments near the code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout notes that it's easy to keep the comments up to date when they are near the code. For example, the methods interface comment should be above the method's body.&lt;/p&gt;

&lt;p&gt;He also argues that the farther away the comment is from the code, the more abstract it should be.&lt;/p&gt;

&lt;p&gt;A comment that gives a high-level overview should not go into implementation details. By doing this, we reduce the likelihood of the comment being invalidated by code changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comments belong in the code, not the commit log&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;He argues that since the commit log is less likely to be seen than the source code itself, placing the documentation there does not make sense. Instead, it should be in the source code itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Maintaining comments: avoid duplication&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, Ousterhout suggests avoiding duplicate comments since it is more difficult to update multiple places instead of one. He also mentions that if information is already documented outside the source code, one should reference that external documentation.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 17 Consistency
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout shares his thoughts on consistency and how consistency can help reduce a system's overall complexity by making things more obvious. Consistency allows a developer to learn how a thing&lt;br&gt;
is done in one place and apply that knowledge to other places. If a code base is inconsistent, developers must learn each situation separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Examples of consistency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consistency can be applied at all levels of a system. To illustrate this, Ousterhout provides a few examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Names&lt;/li&gt;
&lt;li&gt;Coding style&lt;/li&gt;
&lt;li&gt;Interfaces (meaning &lt;code&gt;interfaces&lt;/code&gt; as a language feature)&lt;/li&gt;
&lt;li&gt;Design patterns&lt;/li&gt;
&lt;li&gt;Invariants&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ensuring consistency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout states that consistency is hard to maintain since many people typically work on a project over time. Another reason is that some people (e.g., a new co-worker) might now know about already established conventions.&lt;/p&gt;

&lt;p&gt;He provides a few tips that help to maintain consistency:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Document a list that describes the most important overall conventions, such as coding style guidelines.&lt;/li&gt;
&lt;li&gt;Enforce the conventions by having a tool that checks for violations and checks the code before it can be committed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a final tip on conventions, Ousterhout shares the old saying: "When in Rome, do as the Romans do."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Taking it too far&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout argues that consistency is only beneficial if it applies to similar things. Meaning that it is fine to do things differently if it makes sense in that case. Ousterhout warns that one should not become overzealous&lt;br&gt;
and try to force things into being done the same way for consistency's sake, as this will only create complexity and confusion.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chapter 18 Code Should be Obvious
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout tackles one of the two leading causes of complexity: Obscurity. He then shares some factors that make code more or less obvious.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Things that make code more obvious&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, Ousterhout recalls previously discussed techniques that help to reduce obscurity:&lt;br&gt;
&lt;strong&gt;Choosing good names&lt;/strong&gt; and &lt;strong&gt;consistency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;He then offers a few more general-purpose techniques for making code more obvious. The first is to use white space when formatting one's code, as it impacts how easy it is to read. An example of this he provides&lt;br&gt;
two code snippets.&lt;/p&gt;

&lt;p&gt;Without whitespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="o"&gt;/**&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nd"&gt;@param&lt;/span&gt; &lt;span class="n"&gt;numThreads&lt;/span&gt; &lt;span class="nc"&gt;The&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;threads&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; 
  &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;spin&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;manage&lt;/span&gt; &lt;span class="n"&gt;ongoing&lt;/span&gt; &lt;span class="n"&gt;connections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nc"&gt;The&lt;/span&gt; &lt;span class="nc"&gt;MessageManager&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;spins&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;least&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="n"&gt;thread&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;every&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;so&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;least&lt;/span&gt; &lt;span class="n"&gt;equal&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;connections&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;expect&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;once&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nc"&gt;This&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;multiple&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;expect&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;lot&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;short&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nd"&gt;@param&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="nc"&gt;Used&lt;/span&gt; &lt;span class="n"&gt;as&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="n"&gt;incoming&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nc"&gt;MessageManagers&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;connections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nc"&gt;See&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nd"&gt;@code&lt;/span&gt; &lt;span class="nc"&gt;MessageHandler&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nd"&gt;@code&lt;/span&gt; &lt;span class="n"&gt;handleMessage&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;details&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With whitespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="o"&gt;/**&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nd"&gt;@param&lt;/span&gt; &lt;span class="n"&gt;numThreads&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="nc"&gt;The&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;threads&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;spin&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;manage&lt;/span&gt; &lt;span class="n"&gt;ongoing&lt;/span&gt; &lt;span class="n"&gt;connections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nc"&gt;The&lt;/span&gt; &lt;span class="nc"&gt;MessageManager&lt;/span&gt; &lt;span class="n"&gt;spins&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;up&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;least&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="n"&gt;thread&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;every&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;so&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;least&lt;/span&gt; &lt;span class="n"&gt;equal&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;connections&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; 
  &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;expect&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;once&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nc"&gt;This&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;multiple&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; 
  &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;expect&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;lot&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;short&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nd"&gt;@param&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt; 
  &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="nc"&gt;Used&lt;/span&gt; &lt;span class="n"&gt;as&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="n"&gt;incoming&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nc"&gt;MessageManagers&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;connections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nc"&gt;See&lt;/span&gt;
  &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nd"&gt;@code&lt;/span&gt; &lt;span class="nc"&gt;MessageHandler&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nd"&gt;@code&lt;/span&gt; &lt;span class="n"&gt;handleMessage&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;details&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;He also suggests using whitespaces within methods to separate major blocks. He suggests adding a comment above each block to make the code even more obvious.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Things that make code less obvious&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this section, the author shares a few examples of things that can make the code nonobvious.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Event-driven programming&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;According to Ousterhout, Event-driven programming is a programming style where an application responds to&lt;br&gt;
external occurrences, such as the arrival of a network packet or the press of a mouse button.&lt;/p&gt;

&lt;p&gt;One module will be in charge of reporting incoming events (the event module), while other parts of the application register&lt;br&gt;
interest in an event and asking the event module to invoke a given function or method once the event occurs.&lt;br&gt;
Ousterhout finds this programming style hard to follow because the event handler functions are never invoked directly.&lt;br&gt;
Typically, they are invoked indirectly by the event module using a function pointer or interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generic containers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout states that many programming languages provide classes to group two or more items into a single object. For example, &lt;code&gt;Pair&lt;/code&gt; in Java. He states that one of the most common use cases of these classes is to return multiple values from a method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pair&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;currentTerm&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ousterhout claims that, these generic containers result in nonobvious code because the elements have generic names&lt;br&gt;
that obscure their actual names.&lt;/p&gt;

&lt;p&gt;To solve the issue of returning multiple values from a method, Ousterhout suggests just creating a specialized class structure for this use case. That way, one can provide meaningful names for the elements, and it is also possible to add documentation to the declaration.&lt;/p&gt;

&lt;p&gt;He notes that, this example illustrates a general rule where "software should be designed for ease of reading, not ease of writing".&lt;/p&gt;

&lt;p&gt;Generic containers break this rule because they are easy to write but can be confusing for the reader.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 19 Software Trends
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout considers several trends in the software development world and evaluates if and how they might&lt;br&gt;
help to reduce complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Object-oriented programming and inheritance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout states that, one of the main elements of OOP is inheritance. He believes that inheritance comes in two forms, which both have a different impact on complexity:&lt;/p&gt;

&lt;p&gt;The first form of inheritance is interface inheritance, where a parent class defines the signatures of one or more methods but does not implement them. Ousterhout finds that interface inheritance reduces complexity because one will reuse the same interface for multiple purposes. This is especially true if an interface has many implementations,&lt;br&gt;
because then it is more likely that this interface captures essential features of all the implementations while not being concerned with the implementation details.&lt;/p&gt;

&lt;p&gt;The second form of inheritance is the implementation inheritance, where a parent class not only defines the signatures but also implements one or more methods. Subclasses inherit these methods, but they can also overwrite them.&lt;br&gt;
This allows for code sharing among classes because it is possible to provide an implementation of a method to all&lt;br&gt;
subclasses.&lt;/p&gt;

&lt;p&gt;A disadvantage to implementation inheritance, according to Ousterhout, is that the inheritance creates dependencies between the parent class and the subclasses. He finds this can lead to information leakage between&lt;br&gt;
the classes in the class tree. For example, he mentions the case where a developer needs to make changes to the parent class; in that case, he may have to check all of its subclasses to ensure they still work as expected.&lt;/p&gt;

&lt;p&gt;In an extreme case, the developer would have to check all classes in the tree to ensure nothing breaks.&lt;br&gt;
Therefore, Ousterhout suggests using implementation inheritance cautiously and that one should consider a composition-based approach first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agile development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Agile development is a practice that aims to make software development more lightweight, flexible, and incremental.&lt;/p&gt;

&lt;p&gt;Ousterhout finds this approach is similar to the one he advocates in this book. However, he also finds that one of the risks of this agile, incremental approach is that it can encourage tactical programming to get a feature done as fast as possible. Another problem, in his opinion, is that some practitioners argue that one shouldn't implement a general-purpose approach right away. They argue that one should first implement a special-purpose solution and then implement the general-purpose one once needed.&lt;/p&gt;

&lt;p&gt;Although Ousterhout agrees that this makes sense, he still finds that it encourages a tactical style of programming that can result in a rapid accumulation of complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unit tests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unit tests are one of the tenets of agile development, and the practice of writing unit tests has become widely accepted today. Since unit tests help verify that the code works as expected, they also help facilitate refactoring. Hence, he finds that unit tests are crucial in software design as they encourage developers to refactor and improve the code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test-driven development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Test-driven development is an approach to software development where developers write the tests before implementing the code. Since the developer's goal is to make the test pass, Ousterhout finds that this approach focuses too much on getting stuff done rather than finding the best design.&lt;/p&gt;

&lt;p&gt;The only place where he uses this approach is when fixing bugs. This means that he'll write a test that reproduces the bug and fails, and only then will he start with the implementation of the fix.&lt;br&gt;
Now, if the test passes, one can be sure that the bug is fixed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Design patterns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;According to Ousterhout, a design pattern is a commonly used approach for solving a particular problem.&lt;br&gt;
He finds that one should use the patterns when it makes sense because it would be hard to devise a better solution yourself. However, he warns that one should not try to force it and that a custom approach&lt;br&gt;
is preferred if it is cleaner.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getters and Setters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Getters and setters are a popular design pattern in software design, especially within the Java programming community. He finds that getters and setters can make sense if one must expose an instance variable. However, he argues that one should be wary of exposing instance variables in the first place since this means that a part of the class's implementation is leaked, violating the idea of information hiding.&lt;/p&gt;

&lt;p&gt;He also argues that getters and setters typically are shallow because they are often just one line. They add clutter to the class interface without providing much functionality. Therefore, he believes one should avoid getters and setters as much as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 20 Design for Performance
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout discusses how to achieve high performance without sacrificing clean design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to think about performance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout suggests that, one should neither try to optimize for maximum speed nor completely ignore it. This is because an approach for maximum speed will likely slow down development while ignoring performance&lt;br&gt;
completely will likely lead to many inefficiencies, which will be hard to fix.&lt;/p&gt;

&lt;p&gt;Hence, he suggests to use the middle road of these two approaches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Measure before modifying&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout observes that, it is tempting to make performance tweaks based on intuition. He argues that one should avoid doing this because intuition can be unreliable. Instead, he suggests measuring the system's existing behavior before trying to fix it.&lt;/p&gt;

&lt;p&gt;This will have the benefit of identifying the places where performance tuning will have the most impact while also ensuring that the performance tweak actually improves performance.&lt;/p&gt;

&lt;p&gt;He also believes there is no need to retain complex changes if they do not improve performance significantly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Design around the critical path&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When fixing performance issues, the first question one should ask oneself&lt;br&gt;
what is the smallest amount of code that must be executed to achieve the desired outcome.&lt;br&gt;
Also, one should focus on something other than special cases when fixing performance issues. When performance is an issue, one should minimize the number of special cases that must be checked. Ideally, this check should be done at the end, where the special cases can then be handled.&lt;/p&gt;

&lt;p&gt;Since performance is less critical for special cases, one should focus on lowering the case's complexity instead of worrying about performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ousterhout concludes that one should focus on simplicity when trying to create fast code, because slow code tends to be slow because it does unnecessary work. He finds that simple code often is fast enough, and&lt;br&gt;
therefore, one does not have to worry about performance much in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 21 Conclusion
&lt;/h2&gt;

&lt;p&gt;In this chapter, Ousterhout gives a summary of the topics that were discussed in this book. He also reiterates that this book is all about one thing: complexity. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>codenewbie</category>
      <category>learning</category>
    </item>
    <item>
      <title>React Rendering for Dummies</title>
      <dc:creator>Carsten Behrens</dc:creator>
      <pubDate>Thu, 24 Aug 2023 17:42:26 +0000</pubDate>
      <link>https://dev.to/carstenbehrens/react-rendering-for-dummies-438h</link>
      <guid>https://dev.to/carstenbehrens/react-rendering-for-dummies-438h</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;React allows us to write Components that automatically update and re-render once the data of the component changes. In this blog post, I will briefly introduce how React archives this.&lt;/p&gt;

&lt;p&gt;Hopefully, this blog post will answer the question:&lt;br&gt;
&lt;strong&gt;"What happens when I update my component state?"&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Counter Example
&lt;/h2&gt;

&lt;p&gt;Let's take a look at an exemplary "component".&lt;br&gt;&lt;br&gt;
Notice that this example does not use any build-step. Instead, we import the required libraries (React, ReactDOM, and Babel) directly inside the browser. I'm doing this because I don't want any framework "magic" to hide what is happening here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/react@18/umd/react.development.js"&lt;/span&gt; &lt;span class="na"&gt;crossorigin&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/react-dom@18/umd/react-dom.development.js"&lt;/span&gt; &lt;span class="na"&gt;crossorigin&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/@babel/standalone@7.22.10/babel.js"&lt;/span&gt; &lt;span class="na"&gt;crossorigin&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/babel"&lt;/span&gt; &lt;span class="na"&gt;data-presets=&lt;/span&gt;&lt;span class="s"&gt;"env,react"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;+&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;-&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reactElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reactElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is a simple counter that displays the current count and allows the user to increase or decrease it. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There are three parts to this example:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, the &lt;code&gt;Counter&lt;/code&gt; function returns JSX and stores the count value. I will now refer to this function as "Component" as this is the language that people are most familiar with.
&lt;/li&gt;
&lt;li&gt;Then, we create a ReactElement using the &lt;code&gt;createElement&lt;/code&gt; function.
&lt;/li&gt;
&lt;li&gt;After that, we use ReactDOM to render the ReactElement.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When the user presses the (+)-Button, we can observe that the DOM updates and the new count is displayed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens when you update a state variable
&lt;/h2&gt;

&lt;p&gt;When a user clicks the (+)-Button, we'll call the setCount function to update the count state. Updating the count state will trigger React to call the &lt;code&gt;Counter&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;The process of React calling the &lt;code&gt;Counter&lt;/code&gt; component is often referred to as "rendering". Each time we update the state within our component, React will "render" the component.&lt;/p&gt;

&lt;p&gt;It is essential to understand that calling the &lt;code&gt;Counter&lt;/code&gt; function does not update the DOM. That part gets handled by ReactDOM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modifying the DOM
&lt;/h2&gt;

&lt;p&gt;Updating the DOM is slow, that's why ReactDOM will decide which parts of the DOM need to be modified by comparing the old JSX that our &lt;code&gt;Counter&lt;/code&gt; component returned with the new JSX.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Count: 0&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Count: 1&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The process of finding the minimum number of changes that must be made to the DOM is called Reconciliation.&lt;/p&gt;

&lt;p&gt;In our case this is pretty simple, React just has to update the number within the P-Tag. Note that it will not update the whole component, just the elements that need to be changed.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>beginners</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Event bubbling for Dummies</title>
      <dc:creator>Carsten Behrens</dc:creator>
      <pubDate>Sat, 19 Aug 2023 22:27:14 +0000</pubDate>
      <link>https://dev.to/carstenbehrens/event-bubbling-for-dummies-4o1c</link>
      <guid>https://dev.to/carstenbehrens/event-bubbling-for-dummies-4o1c</guid>
      <description>&lt;p&gt;Before we can go into what Event bubbling is, we have to make sure that we understand what an &lt;code&gt;Event&lt;/code&gt; is.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;Event&lt;/code&gt; is something that happens on a webpage, for example, a user clicking on a button or an error that occurs.&lt;/p&gt;

&lt;p&gt;Events are fired and then handled via an event handler. (Or ignored if we don't have any event handler listing for that Event)&lt;/p&gt;

&lt;h2&gt;
  
  
  Events in action
&lt;/h2&gt;

&lt;p&gt;An example of an event being fired and an event handler looks like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Click Me&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what is happening here is the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We search the button via the querySelector&lt;/li&gt;
&lt;li&gt;We attach an event listener&lt;/li&gt;
&lt;li&gt;We &lt;code&gt;console.log&lt;/code&gt; the event&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now let's go into event bubbling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Event bubbling
&lt;/h2&gt;

&lt;p&gt;The example above is pretty straightforward, but what happens if we don't attach the event handler to the button directly?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Click Me&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we attach the event handler to the div that is the &lt;strong&gt;parent&lt;/strong&gt; of the button.&lt;/p&gt;

&lt;p&gt;Even though the event handler is not attached to the button, the event handler still gets called.&lt;/p&gt;

&lt;p&gt;This is because the event "bubbles" up from the child element to the parent element and so on.&lt;/p&gt;

&lt;p&gt;It is noteworthy that the event will keep "bubbling up" after an event handler has already handled it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Click Me&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both event handlers will be called.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Integration Tests using Vue 3 and Pinia</title>
      <dc:creator>Carsten Behrens</dc:creator>
      <pubDate>Wed, 19 Apr 2023 17:25:51 +0000</pubDate>
      <link>https://dev.to/carstenbehrens/integration-tests-using-vue-3-and-pinia-p2n</link>
      <guid>https://dev.to/carstenbehrens/integration-tests-using-vue-3-and-pinia-p2n</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this article, I will show you how to write integration tests for a Vue 3 app that uses Pinia for state management.&lt;br&gt;
I will be using this &lt;a href="https://github.com/ar363/todolist-vue-ts" rel="noopener noreferrer"&gt;todo app&lt;/a&gt; by &lt;a href="https://github.com/ar363" rel="noopener noreferrer"&gt;ar363&lt;/a&gt; to demonstrate the process.&lt;/p&gt;

&lt;p&gt;I do this because I find it easier to explain things when I work with a concrete example.&lt;/p&gt;
&lt;h2&gt;
  
  
  Installing Dependencies
&lt;/h2&gt;

&lt;p&gt;First of all, we need a test framework to run our tests. We'll use &lt;a href="https://vitest.dev/" rel="noopener noreferrer"&gt;Vitest&lt;/a&gt; for this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; vitest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we'll add the Vue Test Utils. This library provides a lot of useful functions to test Vue components comfortably.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; @vue/test-utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;Vitest uses Vite under the hood and uses the same configuration file. This is great because it means you don't have to duplicate your configuration between the two tools.&lt;/p&gt;

&lt;p&gt;As we are working on a Vue 3 app, we'll need to ensure that the &lt;code&gt;@vitejs/plugin-vue&lt;/code&gt; plugin is installed and used within our vite.config.ts configuration.&lt;/p&gt;

&lt;p&gt;Add a vite.config.&lt;strong&gt;ts&lt;/strong&gt; or a vite.config.&lt;strong&gt;js&lt;/strong&gt; file to the root of your project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;vue&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@vitejs/plugin-vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// https://vitejs.dev/config/&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;vue&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring Vitest
&lt;/h2&gt;

&lt;p&gt;Next, we'll configure Vitest. This is done by creating a vitest.config.&lt;strong&gt;ts&lt;/strong&gt; or a vitest.config.&lt;strong&gt;js&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mergeConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vitest/config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;viteConfig&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./vite.config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;mergeConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;viteConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jsdom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Use jsdom environment, which is needed for testing components that use the DOM&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, vitest looks for any files that match this pattern &lt;code&gt;['**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}']&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This means that we can place our tests anywhere in our project as long as they match this pattern.&lt;/p&gt;

&lt;p&gt;I like to put my tests in a separate folder, so I'll place them within a &lt;code&gt;src/tests&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;We'll also add the following script to our package.json file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vitest"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Writing the first Test
&lt;/h2&gt;

&lt;p&gt;When writing integration tests for Single Page Applications, I like to use the root component as the starting point.&lt;/p&gt;

&lt;p&gt;I do this because the root component will include all other components, so testing this component will make sure that all components work together as expected.&lt;/p&gt;

&lt;p&gt;Since this test doesn't have to know about the implementation details of any subcomponents (also known as "black box testing") it will be robust and have a good chance of catching real bugs.&lt;/p&gt;

&lt;p&gt;We'll create a &lt;code&gt;tests&lt;/code&gt; folder inside our &lt;code&gt;src&lt;/code&gt; dir and add a &lt;code&gt;HomeView.test.ts&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;HomeView&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;should be able to add and complete todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HomeView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;global&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;createPinia&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;todoInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[data-testid='todo-input']&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Find the todo input&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addTodoButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[data-testid='todo-add-button']&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Find the add todo button&lt;/span&gt;

    &lt;span class="c1"&gt;// Create the two todos&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;todoInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;First Todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;addTodoButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;todoInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Second Todo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;addTodoButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[data-testid='todo-item']&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Find all open todo items&lt;/span&gt;

    &lt;span class="c1"&gt;// Check if there are two open todos&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Check the first todo&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checked&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doneTodos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[data-testid='todo-item-done']&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Find all done todo items&lt;/span&gt;

    &lt;span class="c1"&gt;// Check if there is one done todo&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doneTodos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Check if there is one done todo&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[data-testid='todo-item']&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Should still have one open todo&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things to note here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We use the &lt;code&gt;mount&lt;/code&gt; function from &lt;code&gt;@vue/test-utils&lt;/code&gt; to mount the component.&lt;/li&gt;
&lt;li&gt;We use the &lt;code&gt;createPinia&lt;/code&gt; function from &lt;code&gt;pinia&lt;/code&gt; to create a new pinia instance. We &lt;strong&gt;don't&lt;/strong&gt; mock our store, because we want to test the real store.&lt;/li&gt;
&lt;li&gt;We use the &lt;code&gt;data-testid&lt;/code&gt; attribute to find elements within our component. This makes our tests more robust. See the rationale behind this &lt;a href="https://kentcdodds.com/blog/making-your-ui-tests-resilient-to-change" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;We don't try to test the implementation details of our components. We test the component like a real user would.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find the full code for this example &lt;a href="https://github.com/carstenbehrens/todolist-vue-ts/commit/f9af99487dd9e6d64b7bc41b1f507bd440643f6d" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>vite</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Vue Form Validation using Yup</title>
      <dc:creator>Carsten Behrens</dc:creator>
      <pubDate>Mon, 30 Jan 2023 20:34:38 +0000</pubDate>
      <link>https://dev.to/carstenbehrens/vue-form-validation-using-yup-he0</link>
      <guid>https://dev.to/carstenbehrens/vue-form-validation-using-yup-he0</guid>
      <description>&lt;p&gt;This blog post will show you how to validate forms in Vue 3 using Yup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;In this blog post, I will use the following setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vue 3 with TypeScript, Prettier, and ESLint.&lt;/li&gt;
&lt;li&gt;Yup, for form validation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don't use TypeScript, you can skip the parts specific to TypeScript.&lt;/p&gt;

&lt;p&gt;Before we can start, we will have to add Yup as a dependency in our project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;yup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Simple Form Validation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Creating a form
&lt;/h3&gt;

&lt;p&gt;First, we will create a simple form with a single input field.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit.prevent=&lt;/span&gt;&lt;span class="s"&gt;"validateForm"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"formInput.name"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reactive&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;reactive&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adding a validation schema
&lt;/h3&gt;

&lt;p&gt;Now that we have a form, we can add a validation schema. To do this, we will use Yup.&lt;/p&gt;

&lt;p&gt;Yup allows us to create a schema containing each field's rules. In our case, we only have one field, &lt;code&gt;name&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The field &lt;code&gt;name&lt;/code&gt; should be a string and is required.&lt;br&gt;
Please note that when using Yup, if a string is required, then an empty string is not allowed.&lt;/p&gt;
&lt;h3&gt;
  
  
  Validating the form input
&lt;/h3&gt;

&lt;p&gt;We can validate the form input now that we have our form and schema.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validateForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validateSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formInput&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll show an error message in the console if the validation fails.&lt;/p&gt;

&lt;p&gt;Our complete component looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit.prevent=&lt;/span&gt;&lt;span class="s"&gt;"validateForm"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"formInput.name"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reactive&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;reactive&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validateForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validateSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formInput&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have a simple form validation, we can address some missing features.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our form only has one field&lt;/li&gt;
&lt;li&gt;We don't show any error messages to the user; without this the user will not know what went wrong.&lt;/li&gt;
&lt;li&gt;We only validate the form when the user submits the form,
the user experience would be improved if we validated the form as the user types.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll address these issues in another blog post if there is enough interest.&lt;/p&gt;

</description>
      <category>crypto</category>
      <category>web3</category>
      <category>offers</category>
    </item>
    <item>
      <title>Scoped Slots in Vue for Dummies</title>
      <dc:creator>Carsten Behrens</dc:creator>
      <pubDate>Mon, 02 May 2022 18:54:52 +0000</pubDate>
      <link>https://dev.to/carstenbehrens/scoped-slots-in-vue-for-dummies-2jjg</link>
      <guid>https://dev.to/carstenbehrens/scoped-slots-in-vue-for-dummies-2jjg</guid>
      <description>&lt;h2&gt;
  
  
  What are scoped slots
&lt;/h2&gt;

&lt;p&gt;To easily understand scoped slots, it is helpful to revisit the concept of regular slots.           &lt;/p&gt;

&lt;p&gt;Slots allow us to provide markup to a child component, this markup then gets rendered inside the child component.&lt;/p&gt;

&lt;p&gt;E.g.:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                          
  &lt;span class="nt"&gt;&amp;lt;child-component&amp;gt;&lt;/span&gt;                                                                                 
    This will get rendered inside the slot inside the child component -                             
    it is called the slot content.                                                                  
  &lt;span class="nt"&gt;&amp;lt;/child-component&amp;gt;&lt;/span&gt;                                                                                
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                         

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                            
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ChildComponent&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/ChildComponent.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                                       

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                                                                                    
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                                                                                      
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                                                                                     
    &lt;span class="nx"&gt;ChildComponent&lt;/span&gt;                                                                                  
  &lt;span class="p"&gt;}&lt;/span&gt;                                                                                                 
&lt;span class="p"&gt;}&lt;/span&gt;                                                                                                   
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                           
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;So what are scoped slots?&lt;/strong&gt;                                                                 &lt;/p&gt;

&lt;p&gt;Scoped slots are exactly like regular slots, with the difference that we pass data from the child component to the parent component. This data can then be used inside the slot content.                                      &lt;/p&gt;

&lt;h2&gt;
  
  
  How to use scoped slots in Vue 2
&lt;/h2&gt;

&lt;p&gt;The child component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                          
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;                                                                                             
    &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;v-bind:example=&lt;/span&gt;&lt;span class="s"&gt;"example"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                 
    &lt;span class="nt"&gt;&amp;lt;/slot&amp;gt;&lt;/span&gt;                                                                                         
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;                                                                                            
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                         

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                            

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                                                                                    
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ChildComponent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                                                                           
  &lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                                                                                          
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                                                                                        
      &lt;span class="na"&gt;example&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;just some data...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;                                                                  
    &lt;span class="p"&gt;}&lt;/span&gt;                                                                                               
  &lt;span class="p"&gt;}&lt;/span&gt;                                                                                                 
&lt;span class="p"&gt;}&lt;/span&gt;                                                                                                   
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                           
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How the data gets used inside the parent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                          
  &lt;span class="nt"&gt;&amp;lt;child-component&amp;gt;&lt;/span&gt;                                                                                 
    &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;v-slot:default=&lt;/span&gt;&lt;span class="s"&gt;"slotProps"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                           
      Now we can use the data from the child component here: &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;slotProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;                
    &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                     
  &lt;span class="nt"&gt;&amp;lt;/child-component&amp;gt;&lt;/span&gt;                                                                                
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;                                                                                         

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                            
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ChildComponent&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/ChildComponent.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                                       

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                                                                                    
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                                                                                      
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                                                                                     
    &lt;span class="nx"&gt;ChildComponent&lt;/span&gt;                                                                                  
  &lt;span class="p"&gt;}&lt;/span&gt;                                                                                                 
&lt;span class="p"&gt;}&lt;/span&gt;                                                                                                   
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                           
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find the full code for this example &lt;a href="https://github.com/carstenbehrens/scoped-slots-v2" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use scoped slots in Vue 3
&lt;/h2&gt;

&lt;p&gt;The child component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                          
  &lt;span class="nt"&gt;&amp;lt;slot&lt;/span&gt; &lt;span class="na"&gt;:example=&lt;/span&gt;&lt;span class="s"&gt;"example"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/slot&amp;gt;&lt;/span&gt;                                                                  
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                         

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                      
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;                                                                           

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;example&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;just some data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                                                               
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                           
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How the data gets used inside the parent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                          
  &lt;span class="nt"&gt;&amp;lt;child-component&lt;/span&gt; &lt;span class="na"&gt;v-slot=&lt;/span&gt;&lt;span class="s"&gt;"slotProps"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                              
    Now we can use the data from the child component here: &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;slotProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;                  
  &lt;span class="nt"&gt;&amp;lt;/child-component&amp;gt;&lt;/span&gt;                                                                                
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                         

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                      
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ChildComponent&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/ChildComponent.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;                                        
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                                                                                           
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find the full code for this example &lt;a href="https://github.com/carstenbehrens/scoped-slots-v3" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use scoped slots
&lt;/h2&gt;

&lt;p&gt;So why would we want to use scoped slots in vue?                                                    &lt;/p&gt;

&lt;p&gt;We use scoped slots to give more responsibility to the consumer of our component this allows our components to be more reusable!&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Scroll Progress Bar
&lt;/h2&gt;

&lt;p&gt;To see a real-life example of how this amazing Vue feature can be used, take a look at this library &lt;a href="https://github.com/carstenbehrens/reusable-vue-scroll-progress-bar" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Using scoped slots, we give the user full control over how the component should look. The only downside to this is that we also expose more complexity to the user of our library/component.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>SOLID: Dependency Inversion Principle in JavaScript and TypeScript</title>
      <dc:creator>Carsten Behrens</dc:creator>
      <pubDate>Tue, 18 Jan 2022 18:41:19 +0000</pubDate>
      <link>https://dev.to/carstenbehrens/solid-dependency-inversion-principle-in-javascript-and-typescript-2gbf</link>
      <guid>https://dev.to/carstenbehrens/solid-dependency-inversion-principle-in-javascript-and-typescript-2gbf</guid>
      <description>&lt;p&gt;In this series of blog posts, I will take a look at SOLID Principles in the context of JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SOLID&lt;/strong&gt; is an acronym referring to the SOLID Principles of class design that were popularized by Robert C. Martin.&lt;/p&gt;

&lt;h2&gt;
  
  
  THE DEPENDENCY INVERSION PRINCIPLE
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Modules that encapsulate high-level policy should not&lt;br&gt;
depend upon modules that implement details. Rather, &lt;br&gt;
both kinds of modules should depend upon abstractions.&lt;br&gt;
&lt;strong&gt;Robert C. Martin&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or in a more simple way:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;A.&lt;/strong&gt; High-level modules should not depend on low-level modules. Both should depend on abstractions.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;B.&lt;/strong&gt; Abstractions should not depend upon details. Details should depend upon abstractions.  &lt;/p&gt;

&lt;p&gt;This means that an abstraction (interface or abstract class) should not depend on a detail (concrete classes).&lt;/p&gt;

&lt;p&gt;The goal of the DIP is to decouple high-level modules from low-level modules. This safeguards the higher-level modules from possibly breaking changes in lower-level modules.&lt;/p&gt;

&lt;p&gt;The best way to explain the DIP is to look at the flow of control of an exemplary program. Let's say we have an API that allows us to create video courses. We have a &lt;code&gt;CourseController&lt;/code&gt; that handles the routing, validation, and stuff like that.&lt;/p&gt;

&lt;p&gt;Then we have a &lt;code&gt;CourseService&lt;/code&gt; that will handle the creation of courses, get courses, and so on...&lt;/p&gt;

&lt;p&gt;The simplified code for a class of such program might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CourseService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CourseController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;courseService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CourseService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;courseService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;courseService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// ...&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;courseService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCourses&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example we use a constructor function to provide a CourseService to our CourseController class. The CourseService then gets used in the &lt;code&gt;get&lt;/code&gt; method of the CourseController.&lt;/p&gt;

&lt;p&gt;The flow of control looks like this:&lt;/p&gt;

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

&lt;p&gt;This means that &lt;strong&gt;a high-level module depends on a low-level module&lt;/strong&gt;. The question you have to ask yourself is: Do I want my high-level policy to be polluted by low-level detail?&lt;/p&gt;

&lt;p&gt;Now imagine that CourseService itself depends on other modules which themselves depend on even lower-level modules. A change in one of the low-level modules could break modules that depend on it.&lt;/p&gt;

&lt;p&gt;To stop this from happening we need to &lt;strong&gt;invert&lt;/strong&gt; the dependency. Basically, we will add an interface between the two classes.&lt;/p&gt;

&lt;p&gt;Afterward, the flow of control should look like this:&lt;/p&gt;

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

&lt;p&gt;And the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ICourseService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;getCourses&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ICourse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CourseService&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;ICourseService&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;getCourses&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CourseController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;courseService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ICourseService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;courseService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;courseService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;courseService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCourses&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;We changed the CourseController class in such a way that it only refers to an abstraction of the CourseService (the interface ICourseService), not to a concrete class.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>solid</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Why and when you should use Vuex</title>
      <dc:creator>Carsten Behrens</dc:creator>
      <pubDate>Wed, 13 Oct 2021 08:32:27 +0000</pubDate>
      <link>https://dev.to/carstenbehrens/why-and-when-you-should-use-vuex-3fn8</link>
      <guid>https://dev.to/carstenbehrens/why-and-when-you-should-use-vuex-3fn8</guid>
      <description>&lt;p&gt;As developers, we sometimes fall into the trap of using technologies just because they are popular and or commonly used together. That's why it can be beneficial to take a step back and truly understand the &lt;strong&gt;why&lt;/strong&gt; of each technology we use.&lt;/p&gt;

&lt;p&gt;In this blog post, I will try to do this in regards to &lt;a href="https://vuex.vuejs.org/" rel="noopener noreferrer"&gt;Vuex&lt;/a&gt; while answering&lt;br&gt;
the following question:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What problem does Vuex solve?&lt;/li&gt;
&lt;li&gt;How does it solve the problem?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The Beginning
&lt;/h2&gt;

&lt;p&gt;Let's start with just plain old Vue. You only have one component which includes the state, the template to render your HTML, and methods that modify that state.&lt;/p&gt;

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

&lt;p&gt;Your component has perfect encapsulation and life is good.&lt;/p&gt;

&lt;p&gt;Now you add a second component and you pass it some of the state of the first component via props.&lt;/p&gt;

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

&lt;p&gt;Simple enough.&lt;/p&gt;

&lt;p&gt;Now imagine the following scenario: The component at the bottom of this graph needs some state from the first component.&lt;/p&gt;

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

&lt;p&gt;In this graph you can see that we pass the needed state through many layers of components, this approach is referred to as &lt;strong&gt;prop drilling&lt;/strong&gt;. It might not seem like a problem by looking at this simple graph, but imagine what this graph would look like in a large application. &lt;/p&gt;

&lt;p&gt;Things will start to get messy quick.&lt;/p&gt;

&lt;p&gt;But what exactly is the cause of increased complexity when using this approach?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Even if the components in-between don't need the state from the first component, they still need to pass them to the next component. (Increased Coupling)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The number of changes needed to rename a prop is high. (Code Duplication)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It becomes less simple to locate the place in your code where the state is modified. This increases cognitive load. (Increased Complexity)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Your Application Grows
&lt;/h2&gt;

&lt;p&gt;As your application grows, it will eventually come to a point where more and more state is needed by multiple components scattered across your component hierarchy.&lt;/p&gt;

&lt;p&gt;You also often find the need to control part of the state of the parent component by one of its children,which means you'll now have to trigger events from the child component and listen for them in the parent.&lt;/p&gt;

&lt;p&gt;This of course increases coupling even more.&lt;/p&gt;

&lt;p&gt;In the graph below you will see a small application that has gotten to the point where global state can simplify the code.&lt;/p&gt;

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

&lt;p&gt;Just imagine what a nightmare it would be if the component red component (bottom left) needs to access state from the yellow component (bottom right).&lt;/p&gt;

&lt;p&gt;To solve this issue we have three different options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Move the state up to the top of our component hierarchy, so that we can then pass it down again to the components that need it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send the state up the component hierarchy via events and then pass it down via props.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use global state.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By now you should know that the first two options can become very complex, especially in larger applications. So let's take a look at the third option.&lt;/p&gt;
&lt;h2&gt;
  
  
  Global State
&lt;/h2&gt;

&lt;p&gt;This is where global state comes in, it allows us to access and modify the state from anywhere within our application.&lt;/p&gt;

&lt;p&gt;In Vue this could be as simple as doing this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;toggleTheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;darkMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you could use it in other components simply by referencing &lt;code&gt;this.$root.darkMode&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As you can probably tell from the example code we are setting the theme for the application.&lt;/p&gt;

&lt;p&gt;In this case, this should truly be available throughout the program, it would not make sense for this to be bound to a component.&lt;/p&gt;

&lt;p&gt;The question then arises: If this is approach is so simple why do we need Vuex to manage our global state instead?&lt;/p&gt;

&lt;p&gt;The problem with global state is that it has some inherent problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The global state can be modified from anywhere, this means it becomes harder to predict what the value is at runtime and where it was changed from. (Increased Complexity)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If two components depend on the same global variable, this means that the components are now coupled. This is not only a problem of global state as we had the same problem before. But it is a &lt;strong&gt;new&lt;/strong&gt; problem if you didn't have any coupling between the components before.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Makes testing harder. Since now you'll have to mock the global state. (Increased Complexity)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Flux
&lt;/h2&gt;

&lt;p&gt;This is where Flux comes in. Flux is a pattern for managing data flow in your application.&lt;/p&gt;

&lt;p&gt;I'll try to give you a quick introduction to Flux below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So what is Flux?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Going back to our example from the graph above, where the bottom left component (red) needs state from the bottom right component (yellow).&lt;/p&gt;

&lt;p&gt;Here is how this would work in Vuex (which is the official Flux implementation for Vue):&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Components dispatch actions (e.g. user clicks a button)&lt;/li&gt;
&lt;li&gt;The store updates based on what the action it receives (e.g. "increment" will increase the count property in the store)&lt;/li&gt;
&lt;li&gt;Components update when the store updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of coupling the data with the component, Flux (and therefore Vuex) keeps the data completely separate.&lt;/p&gt;

&lt;p&gt;Different implementations of Flux often use different terms and add or omit a few parts of the original pattern, so it can get confusing sometimes. But at the root, all of the implementations follow the same principle. If you want more information about Flux,you can get a great overview &lt;a href="https://github.com/facebook/flux/tree/main/examples/flux-concepts" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vuex
&lt;/h2&gt;

&lt;p&gt;Ok, so Vuex is the official Flux implementation for Vue, and just like the example above shows,&lt;br&gt;
it solves the same "prop drilling" problems like our global state example from the "Global State" section above.&lt;/p&gt;

&lt;p&gt;One of the main differences between the global state example and Vuex is that Vuex actually encourages its users to keep &lt;a href="https://vuex.vuejs.org/guide/state.html#components-can-still-have-local-state" rel="noopener noreferrer"&gt;most&lt;/a&gt; of the application state inside the store. That way Vuex becomes the single source of truth.&lt;/p&gt;

&lt;p&gt;At the same time, it tries to mitigate the problems that global state inherently has by providing a better developer experience.&lt;/p&gt;

&lt;p&gt;So what are the advantages of Vuex compared to using regular global state?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standardized patterns for modifying state&lt;/li&gt;
&lt;li&gt;Better integration with Vue&lt;/li&gt;
&lt;li&gt;Great &lt;a href="https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=en" rel="noopener noreferrer"&gt;Debugging Tools&lt;/a&gt; and integration in testing utils to allow for &lt;a href="https://vue-test-utils.vuejs.org/guides/using-with-vuex.html" rel="noopener noreferrer"&gt;easier testing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Better support since it's used a lot by the Vue community&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall Vuex offers great value for medium to large applications. When you have a small application you&lt;br&gt;
might consider not using it.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>vue</category>
    </item>
    <item>
      <title>The basics of JWT (JSON Web Tokens) for Dummies</title>
      <dc:creator>Carsten Behrens</dc:creator>
      <pubDate>Tue, 03 Aug 2021 19:45:38 +0000</pubDate>
      <link>https://dev.to/carstenbehrens/the-basics-of-jwt-json-web-tokens-for-dummies-2iin</link>
      <guid>https://dev.to/carstenbehrens/the-basics-of-jwt-json-web-tokens-for-dummies-2iin</guid>
      <description>&lt;p&gt;JSON Web Tokens are a proposed internet standard that allows for stateless authentication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use
&lt;/h2&gt;

&lt;p&gt;JWT are mostly used to authenticate users in the context of websites / web application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Before going into the nitty-gritty here is a simple example of its usage:&lt;/p&gt;

&lt;p&gt;Let's say we have a Web Application called Tweeter, this Web Application can do a bunch of fancy stuff but let's focus on the user profile. Now obviously each user should only be able to access their own user profile settings.&lt;/p&gt;

&lt;p&gt;So very simply User with ID 123 should only be able to access profile settings of User ID 123.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here is how the authentication flow could look like:&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;Looking at this diagram you'll notice two things:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Once the User/Browser has the Token, the DB is no longer needed to authenticate the user.&lt;br&gt;
&lt;strong&gt;This is why it's called stateless authentication.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
With the Token, we can send information about the user, in this example the ID.&lt;br&gt;&lt;br&gt;
This information can then be verified using the Secret Key.&lt;/p&gt;
&lt;h2&gt;
  
  
  The JWT
&lt;/h2&gt;

&lt;p&gt;The Token itself is either send via Cookie or via &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization" rel="noopener noreferrer"&gt;Authorization Header&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;E.g.:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authorization:
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Mjc5MjgyMzksInVzZXJSb2xlcyI6WyJBRE1JTiIsIkRCX1JFQUQiLCJEQl9XUklURSJdLCJ1c2VySWQiOjEyMzQ1LCJpYXQiOjE2Mjc5MjgxMTl9.8vTwsBOp8LSa0sdc0nWAUnmWAAgOnS0ElB3bfaiSRfQ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mangled mess of letters and numbers is nothing more than &lt;strong&gt;encoded&lt;/strong&gt; JSON. Notice that it is &lt;strong&gt;encoded&lt;/strong&gt; not &lt;strong&gt;encrypted&lt;/strong&gt; that means we can easily decode it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;atob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// This will return: {alg: "HS256", typ: "JWT"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the &lt;a href="//jwt.io"&gt;jwt.io&lt;/a&gt; website we can make it really easy for ourselves. Just paste the JWT and get the decoded JSON data.&lt;/p&gt;

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

&lt;p&gt;The JWT is made up of three parts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Header:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Contains information on the signing algorithm that was used.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Payload:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Contains the claims. Like UserId and any other information you want to use, but also a bunch of reserved Claims that you can see &lt;a href="https://auth0.com/docs/tokens/json-web-tokens/json-web-token-claims#reserved-claims" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Footer:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Contains the signature of the token that can be verified with the Secret Key. If the Token gets changed in any way, it won't be valid anymore.&lt;/p&gt;

&lt;p&gt;If you need more input on this topic I highly suggest you watch this &lt;a href="https://www.youtube.com/watch?v=67mezK3NzpU" rel="noopener noreferrer"&gt;presentation&lt;/a&gt;, it's great.&lt;/p&gt;

</description>
      <category>jwt</category>
      <category>auth</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What is Business Logic anyway?</title>
      <dc:creator>Carsten Behrens</dc:creator>
      <pubDate>Wed, 28 Apr 2021 09:31:08 +0000</pubDate>
      <link>https://dev.to/carstenbehrens/what-is-business-logic-anyway-18e8</link>
      <guid>https://dev.to/carstenbehrens/what-is-business-logic-anyway-18e8</guid>
      <description>&lt;p&gt;The term business logic is often used by developers when talking about software design and clean code. But understanding what it means can be confusing.&lt;/p&gt;

&lt;p&gt;Here is the definition of business logic on Wikipedia:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In computer software, business logic or domain logic is the part of the program that encodes the real-world business  rules that determine how data can be created, stored, and changed. It is contrasted with the remainder of the software that might be concerned with lower-level details of managing a database or displaying the user interface, system infrastructure, or generally connecting various parts of the program. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After reading this definition I had more questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do business rules only apply to business matters?&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;What if my application does not have a database?&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Does every application have business logic?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'll try to answer all of these and some other questions here.&lt;/p&gt;
&lt;h2&gt;
  
  
  CLEARLY UNCLEAR
&lt;/h2&gt;

&lt;p&gt;The truth is, that the term is not clearly defined, there are too many opinions of&lt;br&gt;
what the definition of business logic is, and it's often way easier to understand the term in context.&lt;/p&gt;

&lt;p&gt;Now it seems like I am not the only one that is confused by this term, as even the &lt;a href="https://wiki.c2.com/?BusinessLogicDefinition" rel="noopener noreferrer"&gt;definition&lt;/a&gt; on WikiWikiWeb is a hot mess.&lt;/p&gt;

&lt;p&gt;The best way to explain business logic is by using an example.&lt;/p&gt;

&lt;p&gt;Imagine that we want to build a web app that calculates the BMI (Body Mass Index).&lt;/p&gt;

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

&lt;p&gt;After users calculate their BMI the information gets saved in a database.&lt;/p&gt;

&lt;p&gt;In this example, the business logic could be boiled down to a simple function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;calculateBmi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// This is a simplified version. &lt;/span&gt;
&lt;span class="c1"&gt;// You'll also need to consider different units, metric vs. imperial and so on... &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obviously business logic often gets way more complex in real-life applications. Try to keep this in mind.&lt;/p&gt;

&lt;p&gt;Now let me show you the difference between business logic and the rest of the application.&lt;/p&gt;

&lt;p&gt;Let's say we choose &lt;a href="https://vuejs.org/" rel="noopener noreferrer"&gt;Vue&lt;/a&gt; as a modern frontend framework to help us build this web app.&lt;/p&gt;

&lt;p&gt;Think about all the other code that our imaginary web app will likely have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A form users can enter the information&lt;/li&gt;
&lt;li&gt;Some kind of form validation&lt;/li&gt;
&lt;li&gt;A database connection so we can store the data&lt;/li&gt;
&lt;li&gt;Templates to generate our HTML&lt;/li&gt;
&lt;li&gt;CSS to make our web app look pretty&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this code is &lt;strong&gt;NOT&lt;/strong&gt; part of our business logic.&lt;/p&gt;

&lt;p&gt;Since that code either deals with the presentation or the database, it is&lt;br&gt;
not part of our business logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if we changed our frontend framework?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The calculateBmi function would remain unchanged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if we changed our database?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The calculateBmi function would remain unchanged.&lt;/p&gt;

&lt;p&gt;These questions can help you identify business logic easier. If the code could&lt;br&gt;
remain unchanged, it's a tell-tale sign that it is business logic code.&lt;/p&gt;

&lt;p&gt;If you struggle with this example here is another example from the&lt;br&gt;
WikiWikiWeb I have mentioned above:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It may help to consider a simple but illustrative example like computer chess:&lt;br&gt;
The game itself, i.e., the board and the pieces, their movements, and how the&lt;br&gt;
rules of the game are handled independent of any display or user interaction&lt;br&gt;
is business logic.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Do business rules only apply to business matters?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No, that's why the term business logic is also often called domain logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if my application does not have a database?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your application can still have business logic. Since the business logic can be independent of your database anyway, it does not matter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does every application have business logic?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not all applications have business logic. On my &lt;a href="https://github.com/carstenbehrens/cat-facts" rel="noopener noreferrer"&gt;Github&lt;/a&gt; I have a simple exemplary Vue application. It uses the Catfacts API and the&lt;br&gt;
Unsplash API to get a random cat breed and load a picture of that breed.&lt;/p&gt;

&lt;p&gt;So all it does is fetching data and displaying it. It does not have business logic.&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@huntersrace?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Hunters Race&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/business?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>vue</category>
      <category>react</category>
    </item>
    <item>
      <title>How to Make your If Statements more readable by using this ES2020 Feature</title>
      <dc:creator>Carsten Behrens</dc:creator>
      <pubDate>Mon, 26 Apr 2021 10:40:14 +0000</pubDate>
      <link>https://dev.to/carstenbehrens/how-to-make-your-if-statements-more-readable-by-using-this-es2020-feature-16ff</link>
      <guid>https://dev.to/carstenbehrens/how-to-make-your-if-statements-more-readable-by-using-this-es2020-feature-16ff</guid>
      <description>&lt;p&gt;Have you ever written an if-statement like this?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The object we are working with&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;car&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;make&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bmw&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;founded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1916&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;germany&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;car&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;make&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;make&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;make&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bmw&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Do something.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In JavaScript, we often check if each property exists.&lt;br&gt;
We do this because we don't want to run into errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The only problem:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's ugly
&lt;/li&gt;
&lt;li&gt;It's harder to read than it needs to be
&lt;/li&gt;
&lt;li&gt;Noise-to-Signal Ratio is high
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  THE BETTER WAY
&lt;/h2&gt;

&lt;p&gt;Thanks to &lt;a href="https://tc39.es/proposal-optional-chaining/" rel="noopener noreferrer"&gt;optional chaining&lt;/a&gt; which is part of &lt;a href="https://262.ecma-international.org/11.0/#sec-optional-chains" rel="noopener noreferrer"&gt;ES2020&lt;/a&gt;, you can now do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The object we are working with&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;car&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;make&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bmw&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;founded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1916&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;germany&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;car&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;make&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bmw&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Do something.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Beautiful
&lt;/li&gt;
&lt;li&gt;Easier to read
&lt;/li&gt;
&lt;li&gt;Noise-to-Signal Ratio is low
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my opinion, it's the best way to check if a property exists in your if statements.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>codequality</category>
      <category>codereview</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>How I became a professional self-taught developer in Germany while working a full time job</title>
      <dc:creator>Carsten Behrens</dc:creator>
      <pubDate>Mon, 15 Mar 2021 20:29:31 +0000</pubDate>
      <link>https://dev.to/carstenbehrens/how-i-became-a-professional-self-taught-developer-in-germany-while-working-a-full-time-job-djd</link>
      <guid>https://dev.to/carstenbehrens/how-i-became-a-professional-self-taught-developer-in-germany-while-working-a-full-time-job-djd</guid>
      <description>&lt;p&gt;There are many stories online from self-taught developers that share their journey. &lt;br&gt;
Most of these stories are from developers in the USA.&lt;/p&gt;

&lt;p&gt;I have never stumbled upon a story from a German self-taught developer or from  someone that got a job in Germany as a self-taught developer.&lt;/p&gt;

&lt;p&gt;Since that's exactly what I did, I decided to share my journey here. &lt;br&gt;
Hopefully, this blog post will help someone to avoid the mistakes that I made and also learn from the good decisions that I made.&lt;/p&gt;

&lt;p&gt;Basically, I want to write the blog post that I would have needed back when I started programming.&lt;/p&gt;

&lt;p&gt;At the end of the blog post, I will give you a short &lt;a href="https://carstenbehrens.com/how-i-became-a-self-though-programmer/#1" rel="noopener noreferrer"&gt;TLDR&lt;/a&gt; of all the mistakes to avoid and tips to follow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First I have to mention one disclaimer:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Technically I am not fully self-taught since I did finish an apprenticeship as an "IT Specialist" (Fachinformatiker für Systemintegration). I still consider myself self-taught because I did not learn any real programming during that time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The beginning
&lt;/h2&gt;

&lt;p&gt;My story is not special, I guess many of you reading are in the same situation that I was in back in the day:&lt;/p&gt;

&lt;p&gt;I was unhappy with my career and I wanted to change that.&lt;/p&gt;

&lt;p&gt;I was living in a smaller city at the time and as far as I knew there were not a lot of opportunities for developers there. &lt;/p&gt;

&lt;p&gt;So I decided to quit my job and get a new job closer to the nearest bigger city in hopes of getting a developer job there once I taught myself programming. &lt;/p&gt;

&lt;p&gt;Looking back this was a great decision, not only was I closer to the action, but it also took away some distractions. Since I was new to the city I had no friends there, and I made sure not to make any.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My plan was simple:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get a new job in near a big city&lt;/li&gt;
&lt;li&gt;Teach myself programming in one year&lt;/li&gt;
&lt;li&gt;Get a job as a professional programmer&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  First mistake: Getting a stressful job
&lt;/h2&gt;

&lt;p&gt;So here I am, new job, new city. Everything is cool, right? Well actually no.&lt;/p&gt;

&lt;p&gt;I didn't do my research when searching for a job. I just took the first job that wanted to hire me because I didn't want to stay there long anyway. &lt;/p&gt;

&lt;p&gt;Big mistake.&lt;/p&gt;

&lt;p&gt;The job was extremely stressful and also mentally taxing - the last thing you need when you want to learn to program on the side. Often I would get home completely sapped so much so that I needed a nap just so I could focus on anything again.&lt;/p&gt;

&lt;h2&gt;
  
  
  The schedule
&lt;/h2&gt;

&lt;p&gt;Since I had my goal to become a full-time developer in one year, I needed to break this big goal down into actionable steps. &lt;strong&gt;So I decided that I would do three hours of programming every day besides my 8 hours at my full-time job.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you are trying to become a full-time developer while also working a full-time job, you'll quickly realize that you don't have much time left after your job, commute, cooking, house chores, and all that kinda fun stuff are done. That's why I really started to pay attention to every minute I was spending during the day. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I also wrote down how many hours I managed to program each day so that I would not cheat myself.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;During this time my ideal schedule looked like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monday - Friday&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;06:50 - Wake up and Shower&lt;br&gt;
07:15 - Commute to work&lt;br&gt;
08:00 - Start work (actually I was always 5 minutes late, but let's not talk about that)&lt;br&gt;
17:00 - Finish work&lt;br&gt;
17:50 - Get Home and eat something&lt;br&gt;
19:00 - Take a nap&lt;br&gt;
20:00 - Start programming&lt;br&gt;
23:00 - Wind down at the end of the day and go to sleep&lt;/p&gt;

&lt;p&gt;On Saturday and Sunday, I would not have a set schedule, but I would do at least 3 hours of programming.&lt;/p&gt;

&lt;p&gt;That schedule was rough. I would not recommend that schedule to anyone, and it will lead to burnout in the long run. Also, turns out sitting in front of a computer 12 hours a day not doing any sports is unhealthy, who knew?&lt;/p&gt;

&lt;h2&gt;
  
  
  Second mistake: No direction
&lt;/h2&gt;

&lt;p&gt;When I started I tried to learn python, because I've read that it's a great language.&lt;/p&gt;

&lt;p&gt;I got bored (because I had no project in mind) and switched to C++, then I was going back and forth between C++ and Python. &lt;/p&gt;

&lt;p&gt;Also, I was reading all kinds of programming books that were way too advanced for me at that time. &lt;/p&gt;

&lt;p&gt;That's when it dawned on me that I had just wasted a huge amount of time reading books, when in reality all I needed to do was to get my hands dirty and do some actual programming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You don't learn programming by reading books, you learn programming by programming.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now don't get me wrong, I am not saying that you shouldn't read books about programming.&lt;/p&gt;

&lt;p&gt;In fact, I think it's really important to start reading programming books once you mastered the basics, it's the fastest way to learn about software architecture, clean code, and design patterns. But I believe in the first few months you should spend most of your time programming.&lt;/p&gt;

&lt;p&gt;I was devastated - my approach was not working. Like a truck&lt;br&gt;
that was stuck in the mud, spinning its wheels, I was going nowhere. &lt;/p&gt;

&lt;p&gt;I knew I needed to start from square one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting on the right path
&lt;/h2&gt;

&lt;p&gt;I realized that I needed to create some kind of project, that I could show &lt;br&gt;
to potential employers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's when I did some research and decided that web development was my best bet.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are lots of jobs in web development, you can easily share your project, and there is no shortage of great learning resources.&lt;/p&gt;

&lt;p&gt;So I started learning HTML, CSS, JavaScript, and React.&lt;/p&gt;

&lt;p&gt;After learning the basics, my goal was to create a simple time tracking web app and use that project to get me a programming job.&lt;/p&gt;

&lt;p&gt;I bought some Udemy courses and choose one where the end product was similar to the app that I wanted to create. I still think Udemy courses are a great learning tool if you want to learn a new stack. &lt;strong&gt;In the beginning you often don't know what you don't know.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's why having someone more experienced being your mentor can be so powerful.&lt;/p&gt;

&lt;p&gt;In total this project took me around 2 months to complete.&lt;/p&gt;

&lt;p&gt;You can see the repo &lt;a href="https://github.com/carstenbehrens/timevisualizer" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Now obviously I had no idea what I was doing - the code looks horrible - but I managed to get a working application that I could share with potential employers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The application process
&lt;/h2&gt;

&lt;p&gt;Nobody likes rejection. Maybe that's why I waited 8 months after I started programming to send out applications.&lt;/p&gt;

&lt;p&gt;Looking back, I probably could've sent out applications earlier. I've seen people with similar stories like mine get jobs with pretty weak portfolios. So you might want to consider sending out an application after 3 months or so.&lt;/p&gt;

&lt;p&gt;I tried to put myself in the shoes of HR. Let's say you get 50 applications for one job. 49 of those applications have some kind of experience or some kind of degree.&lt;/p&gt;

&lt;p&gt;Then there is my application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero experience&lt;/li&gt;
&lt;li&gt;No degree that's useful for programming&lt;/li&gt;
&lt;li&gt;My CV did not show any proof that I could program&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What do you think HR will do? They would probably - and rightly so - send me a nice rejection email and move on to the next candidate to fill the position.&lt;/p&gt;

&lt;p&gt;That why I made sure to emphasize my personal projects, I knew that an ordinary application would not be the right thing to do in my situation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My situation was different, so I figured that my application should also be different.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I knew that I had to get past HR and get some developer to look at my project, that was my only chance. So the gist of my application was this:&lt;br&gt;&lt;br&gt;
I have no experience, but please look at my personal projects.&lt;/p&gt;

&lt;p&gt;This worked surprisingly well.&lt;/p&gt;

&lt;p&gt;I probably send out around 15 applications and 4 interviews before I got my job. In the end, it took me eleven months to reach my goal of becoming a professional programmer.&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Start programming ASAP, you learn programming by programming&lt;/li&gt;
&lt;li&gt;Give yourself a deadline of when you want to be a professional programmer&lt;/li&gt;
&lt;li&gt;Focus on one programming language &lt;/li&gt;
&lt;li&gt;Choose a programming language that is widely used&lt;/li&gt;
&lt;li&gt;Create a project on GitHub that you can show to potential employers&lt;/li&gt;
&lt;li&gt;Try to do one step every day, learning to program is a marathon, not a sprint&lt;/li&gt;
&lt;li&gt;Get a mentor or buy an Udemy course in the technology you are interested in&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>learning</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
