Jekyll2023-08-08T15:47:44+00:00http://lasseschultebraucks.com/feed.xmlLasse SchultebraucksIT ConsultantLasse SchultebraucksEfficient Full-Stack Application Development Using Spring Profiles2023-08-08T00:00:00+00:002023-08-08T00:00:00+00:00http://lasseschultebraucks.com/softwaredevelopment/Efficient-Full-Stack-Application-Development-Using-Spring-Profiles<p>The development of full-stack applications often involves integrating various features, user roles, and user interfaces. In this context, the Spring Framework, in conjunction with Spring Boot, can offer a powerful solution. A crucial tool in the Spring arsenal is the use of “Profiles,” which allow configuring applications for different environments, thereby enhancing development efficiency. In this blog post, we’ll delve into Spring Profiles and explore how they can be used for developing a full-stack application using a specific scenario.</p>
<h1 id="a-brief-introduction-in-spring-profiles">A Brief Introduction in Spring Profiles</h1>
<p>Spring Profiles provide a means to manage application configurations based on environment variables, system properties, or other configuration sources. They allow defining different settings for different environments (e.g., development, production, testing) without altering the source code. This not only simplifies application deployment but also facilitates smooth local development.</p>
<h2 id="the-scenario-implementing-a-userservice-class-with-spring-profiles">The Scenario: Implementing a UserService Class with Spring Profiles</h2>
<p>Imagine you’re developing a full-stack application that supports different user roles. Within this application, there exists a <code class="language-plaintext highlighter-rouge">UserService</code> class with a method named <code class="language-plaintext highlighter-rouge">isAdmin()</code>, which determines whether a user has administrative privileges. Depending on whether the user is an administrator or not, certain features and user interfaces are made accessible.</p>
<p>The challenge lies in creating a developer-friendly environment for working on admin functionalities without constantly switching between different user roles.</p>
<h1 id="solution-utilizing-spring-profiles-for-development">Solution: Utilizing Spring Profiles for Development</h1>
<p>This is where Spring Profiles come into play. You can leverage Spring Profiles to override the <code class="language-plaintext highlighter-rouge">UserService</code> class and always set the <code class="language-plaintext highlighter-rouge">isAdmin()</code> method to <code class="language-plaintext highlighter-rouge">true</code> when the development profile (<code class="language-plaintext highlighter-rouge">dev</code>) is activated. This provides you with an easy way to work on admin functionalities within your local development environment.</p>
<h2 id="implementation">Implementation:</h2>
<h3 id="1-start-by-defining-the-userservice-interface-and-a-default-implementation">1. Start by defining the <code class="language-plaintext highlighter-rouge">UserService</code> interface and a default implementation:</h3>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">UserService</span> <span class="o">{</span>
<span class="kt">boolean</span> <span class="nf">isAdmin</span><span class="o">(</span><span class="nc">User</span> <span class="n">user</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Service</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">DefaultUserService</span> <span class="kd">implements</span> <span class="nc">UserService</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isAdmin</span><span class="o">(</span><span class="nc">User</span> <span class="n">user</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// Logic for checking admin rights</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h3 id="2-create-an-alternative-implementation-for-the-userservice-that-is-activated-for-the-development-profile">2. Create an alternative implementation for the <code class="language-plaintext highlighter-rouge">UserService</code> that is activated for the development profile:</h3>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Profile</span><span class="o">(</span><span class="s">"dev"</span><span class="o">)</span>
<span class="nd">@Service</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">DevUserService</span> <span class="kd">implements</span> <span class="nc">UserService</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isAdmin</span><span class="o">(</span><span class="nc">User</span> <span class="n">user</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span> <span class="c1">// Always true for admin in the dev profile</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h3 id="3-active-the-spring-profile">3. Active the Spring profile</h3>
<h4 id="either-configure-the-spring-profile-in-your-applicationproperties-or-applicationyml-file">Either Configure the Spring profile in your <code class="language-plaintext highlighter-rouge">application.properties</code> or <code class="language-plaintext highlighter-rouge">application.yml</code> file:</h4>
<div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">spring.profiles.active</span><span class="p">=</span><span class="s">dev</span>
</code></pre></div></div>
<h4 id="if-you-are-using-intellij-or-another-ide-which-supports-spring-you-can-also-activated-your-spring-profile-in-the-run-configurations">If you are using Intellij or another IDE which supports Spring, you can also activated your Spring profile in the run configurations:</h4>
<p><img src="http://lasseschultebraucks.com/assets/img/springProfilesIntellij.png" alt="Spring Profiles" /></p>
<h3 id="4-use-the-userservice-in-your-application">4. Use the <code class="language-plaintext highlighter-rouge">UserService</code> in your application:</h3>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Controller</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">AdminController</span> <span class="o">{</span>
<span class="nd">@Autowired</span>
<span class="kd">private</span> <span class="nc">UserService</span> <span class="n">userService</span><span class="o">;</span>
<span class="nd">@GetMapping</span><span class="o">(</span><span class="s">"/admin/dashboard"</span><span class="o">)</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">adminDashboard</span><span class="o">()</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">userService</span><span class="o">.</span><span class="na">isAdmin</span><span class="o">(</span><span class="n">currentUser</span><span class="o">))</span> <span class="o">{</span>
<span class="c1">// Show admin dashboard</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
<span class="c1">// Access denied</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h1 id="conclusion">Conclusion</h1>
<p>Checkout <a href="https://docs.spring.io/spring-boot/docs/1.2.0.M1/reference/html/boot-features-profiles.html">the official Spring Documentation</a> to learn more about Profiles in Spring.</p>
<p>The utilization of Spring Profiles streamlines the development of full-stack applications. In the scenario described above, by leveraging profiles, you can override the <code class="language-plaintext highlighter-rouge">UserService</code> implementation, simplifying work on admin functionalities during development. This allows you to swiftly and seamlessly develop the desired features without compromising production logic. Spring Profiles thus provide an elegant solution for managing complex application scenarios and enhancing development efficiency.</p>Lasse SchultebraucksThe development of full-stack applications often involves integrating various features, user roles, and user interfaces. In this context, the Spring Framework, in conjunction with Spring Boot, can offer a powerful solution. A crucial tool in the Spring arsenal is the use of “Profiles,” which allow configuring applications for different environments, thereby enhancing development efficiency. In this blog post, we’ll delve into Spring Profiles and explore how they can be used for developing a full-stack application using a specific scenario.My 7 Most Used Software Design Patterns2023-08-03T00:00:00+00:002023-08-03T00:00:00+00:00http://lasseschultebraucks.com/software%20development/my-7-most-used-design-patterns<p>As a software developer, I have encountered various challenges over time and found certain software design patterns to be particularly useful and versatile.</p>
<p>First of all, design patterns are divided into three different categories.</p>
<h1 id="1-creational-patterns">1. Creational Patterns</h1>
<p>These patterns deal with the creation of objects. They allow instantiation of classes and objects in a flexible and loosely coupled manner. Creational patterns isolate the code from the specific class being created and allow the creation of objects to be delegated to subclasses or configurations. The main goals are decoupling and flexibility in object creation.</p>
<h1 id="2-structural-patterns">2. Structural Patterns</h1>
<p>Structural Patterns deal with the organization of classes and objects in larger structures. They emphasize how classes and objects are put together to create new structures that are easier to use and manage. These patterns help improve relationships between classes, increase reusability, and make the structure more flexible.</p>
<h1 id="3-behavioral-patterns">3. Behavioral Patterns</h1>
<p>Behavioral patterns deal with the interaction and communication between classes and objects. They define the way different objects cooperate and communicate with each other to accomplish specific tasks. These patterns define how the behavior of classes is organized and how responsibilities are distributed.</p>
<p>Here are my seven most frequently used design patterns, which I have applied in different projects time and again.</p>
<h1 id="1-builder-pattern-creational">1. Builder Pattern (Creational)</h1>
<p>The Builder Pattern is a creational pattern that simplifies the construction of complex objects by using a step-by-step approach. It separates the object construction from its representation, resulting in cleaner and more readable code.</p>
<h3 id="example-in-java">Example in Java:</h3>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Computer</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="n">cpu</span><span class="o">;</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="n">gpu</span><span class="o">;</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="n">ram</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">Computer</span><span class="o">(</span><span class="nc">ComputerBuilder</span> <span class="n">builder</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">cpu</span> <span class="o">=</span> <span class="n">builder</span><span class="o">.</span><span class="na">cpu</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">gpu</span> <span class="o">=</span> <span class="n">builder</span><span class="o">.</span><span class="na">gpu</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">ram</span> <span class="o">=</span> <span class="n">builder</span><span class="o">.</span><span class="na">ram</span><span class="o">;</span>
<span class="o">}</span>
<span class="c1">// Getters and other methods...</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ComputerBuilder</span> <span class="o">{</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="n">cpu</span><span class="o">;</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="n">gpu</span><span class="o">;</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="n">ram</span><span class="o">;</span>
<span class="kd">public</span> <span class="nc">ComputerBuilder</span> <span class="nf">setCPU</span><span class="o">(</span><span class="nc">String</span> <span class="n">cpu</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">cpu</span> <span class="o">=</span> <span class="n">cpu</span><span class="o">;</span>
<span class="k">return</span> <span class="k">this</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">ComputerBuilder</span> <span class="nf">setGPU</span><span class="o">(</span><span class="nc">String</span> <span class="n">gpu</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">gpu</span> <span class="o">=</span> <span class="n">gpu</span><span class="o">;</span>
<span class="k">return</span> <span class="k">this</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">ComputerBuilder</span> <span class="nf">setRAM</span><span class="o">(</span><span class="nc">String</span> <span class="n">ram</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">ram</span> <span class="o">=</span> <span class="n">ram</span><span class="o">;</span>
<span class="k">return</span> <span class="k">this</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">Computer</span> <span class="nf">build</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">Computer</span><span class="o">(</span><span class="k">this</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">// Usage:</span>
<span class="nc">Computer</span> <span class="n">computer</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ComputerBuilder</span><span class="o">()</span>
<span class="o">.</span><span class="na">setCPU</span><span class="o">(</span><span class="s">"Intel Core i7"</span><span class="o">)</span>
<span class="o">.</span><span class="na">setGPU</span><span class="o">(</span><span class="s">"Nvidia GeForce RTX 3080"</span><span class="o">)</span>
<span class="o">.</span><span class="na">setRAM</span><span class="o">(</span><span class="s">"16GB DDR4"</span><span class="o">)</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>
<h1 id="2-factory-pattern-creational">2 Factory Pattern (Creational)</h1>
<p>The Factory Pattern is another creational pattern that provides an interface for creating objects without revealing the specific implementations. It allows for a flexible and loosely coupled way of object creation.</p>
<h3 id="example-in-java-1">Example in Java</h3>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">interface</span> <span class="nc">Animal</span> <span class="o">{</span>
<span class="kt">void</span> <span class="nf">makeSound</span><span class="o">();</span>
<span class="o">}</span>
<span class="kd">class</span> <span class="nc">Dog</span> <span class="kd">implements</span> <span class="nc">Animal</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">makeSound</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Woof!"</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="kd">class</span> <span class="nc">Cat</span> <span class="kd">implements</span> <span class="nc">Animal</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">makeSound</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Meow!"</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="kd">class</span> <span class="nc">AnimalFactory</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">Animal</span> <span class="nf">createAnimal</span><span class="o">(</span><span class="nc">String</span> <span class="n">type</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">type</span><span class="o">.</span><span class="na">equalsIgnoreCase</span><span class="o">(</span><span class="s">"dog"</span><span class="o">))</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">Dog</span><span class="o">();</span>
<span class="o">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">type</span><span class="o">.</span><span class="na">equalsIgnoreCase</span><span class="o">(</span><span class="s">"cat"</span><span class="o">))</span> <span class="o">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nf">Cat</span><span class="o">();</span>
<span class="o">}</span>
<span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">// Usage:</span>
<span class="nc">Animal</span> <span class="n">dog</span> <span class="o">=</span> <span class="nc">AnimalFactory</span><span class="o">.</span><span class="na">createAnimal</span><span class="o">(</span><span class="s">"dog"</span><span class="o">);</span>
<span class="n">dog</span><span class="o">.</span><span class="na">makeSound</span><span class="o">();</span> <span class="c1">// Output: Woof!</span>
<span class="nc">Animal</span> <span class="n">cat</span> <span class="o">=</span> <span class="nc">AnimalFactory</span><span class="o">.</span><span class="na">createAnimal</span><span class="o">(</span><span class="s">"cat"</span><span class="o">);</span>
<span class="n">cat</span><span class="o">.</span><span class="na">makeSound</span><span class="o">();</span> <span class="c1">// Output: Meow!</span>
</code></pre></div></div>
<h1 id="3-adapter-pattern-structural">3. Adapter Pattern (Structural)</h1>
<p>The Adapter Pattern is a structural pattern that allows two incompatible interfaces to work together. It acts as a mediator to facilitate communication between the classes and promotes reusability of existing code.</p>
<h3 id="example-in-java-2">Example in Java:</h3>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Legacy code with incompatible interface</span>
<span class="kd">interface</span> <span class="nc">OldPrinter</span> <span class="o">{</span>
<span class="kt">void</span> <span class="nf">print</span><span class="o">(</span><span class="nc">String</span> <span class="n">text</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">class</span> <span class="nc">LegacyPrinter</span> <span class="kd">implements</span> <span class="nc">OldPrinter</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">print</span><span class="o">(</span><span class="nc">String</span> <span class="n">text</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">text</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">// New code with the expected interface</span>
<span class="kd">interface</span> <span class="nc">NewPrinter</span> <span class="o">{</span>
<span class="kt">void</span> <span class="nf">printFormattedText</span><span class="o">(</span><span class="nc">String</span> <span class="n">text</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">class</span> <span class="nc">ModernPrinter</span> <span class="kd">implements</span> <span class="nc">NewPrinter</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">printFormattedText</span><span class="o">(</span><span class="nc">String</span> <span class="n">text</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Formatted: "</span> <span class="o">+</span> <span class="n">text</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">// Adapter to make OldPrinter compatible with NewPrinter</span>
<span class="kd">class</span> <span class="nc">PrinterAdapter</span> <span class="kd">implements</span> <span class="nc">NewPrinter</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">OldPrinter</span> <span class="n">oldPrinter</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">PrinterAdapter</span><span class="o">(</span><span class="nc">OldPrinter</span> <span class="n">oldPrinter</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">oldPrinter</span> <span class="o">=</span> <span class="n">oldPrinter</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">printFormattedText</span><span class="o">(</span><span class="nc">String</span> <span class="n">text</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// Converting to the old format before delegating</span>
<span class="n">oldPrinter</span><span class="o">.</span><span class="na">print</span><span class="o">(</span><span class="n">text</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">// Usage:</span>
<span class="nc">NewPrinter</span> <span class="n">modernPrinter</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ModernPrinter</span><span class="o">();</span>
<span class="n">modernPrinter</span><span class="o">.</span><span class="na">printFormattedText</span><span class="o">(</span><span class="s">"Hello, World!"</span><span class="o">);</span> <span class="c1">// Output: Formatted: Hello, World!</span>
<span class="nc">OldPrinter</span> <span class="n">legacyPrinter</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">LegacyPrinter</span><span class="o">();</span>
<span class="nc">NewPrinter</span> <span class="n">adaptedPrinter</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PrinterAdapter</span><span class="o">(</span><span class="n">legacyPrinter</span><span class="o">);</span>
<span class="n">adaptedPrinter</span><span class="o">.</span><span class="na">printFormattedText</span><span class="o">(</span><span class="s">"Hello, World!"</span><span class="o">);</span> <span class="c1">// Output: Hello, World!</span>
</code></pre></div></div>
<h1 id="4-facade-pattern-structural">4. Facade Pattern (Structural)</h1>
<p>The Facade Pattern is another structural pattern that provides a simplified interface for a complex subsystem. It acts as a kind of “facade” for the underlying components, enabling easier usage and management.</p>
<h3 id="example-in-java-3">Example in Java:</h3>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Complex subsystems</span>
<span class="kd">class</span> <span class="nc">CPU</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">processData</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Processing data..."</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="kd">class</span> <span class="nc">Memory</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">load</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Loading data into memory..."</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="kd">class</span> <span class="nc">HardDrive</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">readData</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Reading data from the hard drive..."</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">// Facade class providing a simplified interface</span>
<span class="kd">class</span> <span class="nc">ComputerFacade</span> <span class="o">{</span>
<span class="kd">private</span> <span class="no">CPU</span> <span class="n">cpu</span><span class="o">;</span>
<span class="kd">private</span> <span class="nc">Memory</span> <span class="n">memory</span><span class="o">;</span>
<span class="kd">private</span> <span class="nc">HardDrive</span> <span class="n">hardDrive</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">ComputerFacade</span><span class="o">()</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">cpu</span> <span class="o">=</span> <span class="k">new</span> <span class="no">CPU</span><span class="o">();</span>
<span class="k">this</span><span class="o">.</span><span class="na">memory</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Memory</span><span class="o">();</span>
<span class="k">this</span><span class="o">.</span><span class="na">hardDrive</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">HardDrive</span><span class="o">();</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">start</span><span class="o">()</span> <span class="o">{</span>
<span class="n">hardDrive</span><span class="o">.</span><span class="na">readData</span><span class="o">();</span>
<span class="n">memory</span><span class="o">.</span><span class="na">load</span><span class="o">();</span>
<span class="n">cpu</span><span class="o">.</span><span class="na">processData</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">// Usage:</span>
<span class="nc">ComputerFacade</span> <span class="n">computerFacade</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ComputerFacade</span><span class="o">();</span>
<span class="n">computerFacade</span><span class="o">.</span><span class="na">start</span><span class="o">();</span>
<span class="c1">// Output:</span>
<span class="c1">// Reading data from the hard drive...</span>
<span class="c1">// Loading data into memory...</span>
<span class="c1">// Processing data...</span>
</code></pre></div></div>
<h1 id="5-decorator-pattern-structural">5. Decorator Pattern (Structural)</h1>
<p>The Decorator Pattern is a structural pattern that allows for flexible object extension at runtime. It enables adding additional functionality and responsibilities to an object without modifying its structure.</p>
<h3 id="example-in-java-4">Example in Java</h3>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Component interface</span>
<span class="kd">interface</span> <span class="nc">Coffee</span> <span class="o">{</span>
<span class="kt">double</span> <span class="nf">getCost</span><span class="o">();</span>
<span class="nc">String</span> <span class="nf">getDescription</span><span class="o">();</span>
<span class="o">}</span>
<span class="c1">// Concrete component</span>
<span class="kd">class</span> <span class="nc">SimpleCoffee</span> <span class="kd">implements</span> <span class="nc">Coffee</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">double</span> <span class="nf">getCost</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="mf">2.0</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getDescription</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="s">"Simple Coffee"</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">// Decorator class</span>
<span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">CoffeeDecorator</span> <span class="kd">implements</span> <span class="nc">Coffee</span> <span class="o">{</span>
<span class="kd">protected</span> <span class="nc">Coffee</span> <span class="n">decoratedCoffee</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">CoffeeDecorator</span><span class="o">(</span><span class="nc">Coffee</span> <span class="n">coffee</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">decoratedCoffee</span> <span class="o">=</span> <span class="n">coffee</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">double</span> <span class="nf">getCost</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">decoratedCoffee</span><span class="o">.</span><span class="na">getCost</span><span class="o">();</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getDescription</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">decoratedCoffee</span><span class="o">.</span><span class="na">getDescription</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">// Concrete decorators</span>
<span class="kd">class</span> <span class="nc">MilkDecorator</span> <span class="kd">extends</span> <span class="nc">CoffeeDecorator</span> <span class="o">{</span>
<span class="kd">public</span> <span class="nf">MilkDecorator</span><span class="o">(</span><span class="nc">Coffee</span> <span class="n">coffee</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="n">coffee</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">double</span> <span class="nf">getCost</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="kd">super</span><span class="o">.</span><span class="na">getCost</span><span class="o">()</span> <span class="o">+</span> <span class="mf">0.5</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getDescription</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="kd">super</span><span class="o">.</span><span class="na">getDescription</span><span class="o">()</span> <span class="o">+</span> <span class="s">", Milk"</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="kd">class</span> <span class="nc">WhipDecorator</span> <span class="kd">extends</span> <span class="nc">CoffeeDecorator</span> <span class="o">{</span>
<span class="kd">public</span> <span class="nf">WhipDecorator</span><span class="o">(</span><span class="nc">Coffee</span> <span class="n">coffee</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="n">coffee</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">double</span> <span class="nf">getCost</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="kd">super</span><span class="o">.</span><span class="na">getCost</span><span class="o">()</span> <span class="o">+</span> <span class="mf">1.0</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getDescription</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="kd">super</span><span class="o">.</span><span class="na">getDescription</span><span class="o">()</span> <span class="o">+</span> <span class="s">", Whip"</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">// Usage:</span>
<span class="nc">Coffee</span> <span class="n">simpleCoffee</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SimpleCoffee</span><span class="o">();</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Cost: "</span> <span class="o">+</span> <span class="n">simpleCoffee</span><span class="o">.</span><span class="na">getCost</span><span class="o">()</span> <span class="o">+</span> <span class="s">", Description: "</span> <span class="o">+</span> <span class="n">simpleCoffee</span><span class="o">.</span><span class="na">getDescription</span><span class="o">());</span>
<span class="nc">Coffee</span> <span class="n">coffeeWithMilk</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MilkDecorator</span><span class="o">(</span><span class="n">simpleCoffee</span><span class="o">);</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Cost: "</span> <span class="o">+</span> <span class="n">coffeeWithMilk</span><span class="o">.</span><span class="na">getCost</span><span class="o">()</span> <span class="o">+</span> <span class="s">", Description: "</span> <span class="o">+</span> <span class="n">coffeeWithMilk</span><span class="o">.</span><span class="na">getDescription</span><span class="o">());</span>
<span class="nc">Coffee</span> <span class="n">coffeeWithMilkAndWhip</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">WhipDecorator</span><span class="o">(</span><span class="n">coffeeWithMilk</span><span class="o">);</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Cost: "</span> <span class="o">+</span> <span class="n">coffeeWithMilkAndWhip</span><span class="o">.</span><span class="na">getCost</span><span class="o">()</span> <span class="o">+</span> <span class="s">", Description: "</span> <span class="o">+</span> <span class="n">coffeeWithMilkAndWhip</span><span class="o">.</span><span class="na">getDescription</span><span class="o">());</span>
<span class="c1">// Output:</span>
<span class="c1">// Cost: 2.0, Description: Simple Coffee</span>
<span class="c1">// Cost: 2.5, Description: Simple Coffee, Milk</span>
<span class="c1">// Cost: 3.5, Description: Simple Coffee, Milk, Whip</span>
</code></pre></div></div>
<h1 id="6-composite-pattern-structural">6. Composite Pattern (Structural)</h1>
<p>The Composite Pattern is another structural pattern that allows objects to be treated as individual objects or object hierarchies uniformly. It enables working with objects as part-whole hierarchies, making the treatment of individual and group objects more straightforward.</p>
<h3 id="example-in-java-5">Example in Java</h3>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Component interface</span>
<span class="kd">interface</span> <span class="nc">Graphic</span> <span class="o">{</span>
<span class="kt">void</span> <span class="nf">draw</span><span class="o">();</span>
<span class="o">}</span>
<span class="c1">// Leaf class</span>
<span class="kd">class</span> <span class="nc">Circle</span> <span class="kd">implements</span> <span class="nc">Graphic</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">draw</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Drawing a circle"</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="kd">class</span> <span class="nc">Square</span> <span class="kd">implements</span> <span class="nc">Graphic</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">draw</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Drawing a square"</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">// Composite class</span>
<span class="kd">class</span> <span class="nc">CompositeGraphic</span> <span class="kd">implements</span> <span class="nc">Graphic</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">List</span><span class="o"><</span><span class="nc">Graphic</span><span class="o">></span> <span class="n">graphics</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o"><>();</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">add</span><span class="o">(</span><span class="nc">Graphic</span> <span class="n">graphic</span><span class="o">)</span> <span class="o">{</span>
<span class="n">graphics</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">graphic</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">draw</span><span class="o">()</span> <span class="o">{</span>
<span class="k">for</span> <span class="o">(</span><span class="nc">Graphic</span> <span class="n">graphic</span> <span class="o">:</span> <span class="n">graphics</span><span class="o">)</span> <span class="o">{</span>
<span class="n">graphic</span><span class="o">.</span><span class="na">draw</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">// Usage:</span>
<span class="nc">CompositeGraphic</span> <span class="n">graphicGroup</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">CompositeGraphic</span><span class="o">();</span>
<span class="n">graphicGroup</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">Circle</span><span class="o">());</span>
<span class="n">graphicGroup</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="k">new</span> <span class="nc">Square</span><span class="o">());</span>
<span class="n">graphicGroup</span><span class="o">.</span><span class="na">draw</span><span class="o">();</span>
<span class="c1">// Output:</span>
<span class="c1">// Drawing a circle</span>
<span class="c1">// Drawing a square</span>
</code></pre></div></div>
<h1 id="7-delegation-pattern-behavioral">7. Delegation Pattern (Behavioral)</h1>
<p>The Delegation Pattern is a behavioral pattern that delegates responsibilities to another object instead of handling them itself. It promotes loose coupling and efficient distribution of tasks.</p>
<h3 id="example-in-java-6">Example in Java:</h3>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Service interface</span>
<span class="kd">interface</span> <span class="nc">Printer</span> <span class="o">{</span>
<span class="kt">void</span> <span class="nf">print</span><span class="o">(</span><span class="nc">String</span> <span class="n">message</span><span class="o">);</span>
<span class="o">}</span>
<span class="c1">// Delegate class</span>
<span class="kd">class</span> <span class="nc">RealPrinter</span> <span class="kd">implements</span> <span class="nc">Printer</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">print</span><span class="o">(</span><span class="nc">String</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Printing: "</span> <span class="o">+</span> <span class="n">message</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">// Client class</span>
<span class="kd">class</span> <span class="nc">PrintClient</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">Printer</span> <span class="n">printer</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">PrintClient</span><span class="o">(</span><span class="nc">Printer</span> <span class="n">printer</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">printer</span> <span class="o">=</span> <span class="n">printer</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">printMessage</span><span class="o">(</span><span class="nc">String</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>
<span class="n">printer</span><span class="o">.</span><span class="na">print</span><span class="o">(</span><span class="n">message</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="c1">// Usage:</span>
<span class="nc">Printer</span> <span class="n">realPrinter</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">RealPrinter</span><span class="o">();</span>
<span class="nc">PrintClient</span> <span class="n">client</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PrintClient</span><span class="o">(</span><span class="n">realPrinter</span><span class="o">);</span>
<span class="n">client</span><span class="o">.</span><span class="na">printMessage</span><span class="o">(</span><span class="s">"Hello, Delegation Pattern!"</span><span class="o">);</span>
<span class="c1">// Output: Printing: Hello, Delegation Pattern!</span>
</code></pre></div></div>
<p>These seven design patterns have proven to be extremely valuable in my day-to-day work as a software developer. By applying them, I could make code more efficient, improve reusability, and enhance the maintainability of my projects. I hope these examples provide you with insight into the versatility and benefits of design patterns in software development in general.</p>Lasse SchultebraucksAs a software developer, I have encountered various challenges over time and found certain software design patterns to be particularly useful and versatile.Learning and Knowledge Acquisition in Software Development2023-07-31T00:00:00+00:002023-07-31T00:00:00+00:00http://lasseschultebraucks.com/software%20development/learning-and-knowledge-acquisition-in-software-development<p>Software development is a dynamic field that is constantly evolving. Therefore, it is crucial for software developers to continuously acquire new knowledge and keep existing knowledge up to date. In the process of acquiring knowledge in software development, we can distinguish three categories:</p>
<h1 id="1-knowledge-with-limited-shelf-life-such-as-frameworks-and-technologies">1. Knowledge with limited shelf life, such as frameworks and technologies</h1>
<p>Frameworks and technologies are essential tools in software development, but they undergo rapid changes. New technologies and frameworks emerge, while older ones lose relevance. Examples of knowledge with limited shelf life include:</p>
<ul>
<li>
<p>jQuery: A few years ago, jQuery was extremely popular in web development and served as an important tool for DOM manipulation and event handling. However, the introduction of modern JavaScript libraries like React and Vue.js has diminished the importance of jQuery.</p>
</li>
<li>
<p>AngularJS: Similar to jQuery, AngularJS was a widely used framework for web applications. Nowadays, Angular (Angular 2+) is preferred, as it offers many improvements and better performance.</p>
</li>
</ul>
<p>Developers should be aware that knowledge about specific frameworks and technologies may not remain relevant forever, so it is essential to be open to new developments.</p>
<h1 id="2-knowledge-with-partially-limited-shelf-life-such-as-programming-languages">2. Knowledge with partially limited shelf life, such as programming languages</h1>
<p>Programming languages are the backbone of software development, and while some programming languages have high longevity, others may become less in demand over time. Examples of knowledge with partially limited shelf life include:</p>
<ul>
<li>
<p>Java: Java has been one of the most popular programming languages for a long time and is used in many enterprise applications. Although it will likely remain relevant, specific language features or libraries may become outdated.</p>
</li>
<li>
<p>Python: Python has gained significant popularity in recent years, especially in areas like data science and AI. The language is continuously evolving, and it is essential to stay familiar with the latest features and improvements.</p>
</li>
</ul>
<p>Partially limited shelf life knowledge requires developers to stay updated on language developments and, if necessary, update their knowledge.</p>
<h1 id="3-knowledge-with-unlimited-shelf-life-such-as-architectures-and-software-patterns">3. Knowledge with unlimited shelf life, such as architectures and software patterns</h1>
<p>Knowledge about software architectures and proven software patterns is timeless. These concepts form the foundation for scalable, maintainable, and flexible software solutions. Examples of knowledge with unlimited shelf life include:</p>
<ul>
<li>
<p>MVC (Model-View-Controller): The MVC pattern is a fundamental concept in software development that enables the separation of data, presentation, and logic. It is a timeless concept that can be applied in various technologies and frameworks.</p>
</li>
<li>
<p>REST (Representational State Transfer): REST is an architectural style widely used in web application and API development. It is a flexible and scalable pattern that will remain relevant in the future.</p>
</li>
</ul>
<p>Unlimited shelf life knowledge provides the basis for a sustainable career in software development, as it is independent of changing technologies and trends.</p>
<h1 id="conclusion">Conclusion</h1>
<p>In software development, it is essential to have a balanced understanding of knowledge with limited shelf life and unlimited shelf life. Developers should regularly stay informed about new technologies and frameworks to stay up to date and be prepared for specific projects. At the same time, they should deepen their understanding of fundamental concepts such as architectures and software patterns to ensure long-term success in their careers. Flexibility, curiosity, and continuous learning are the keys to succeeding in the ever-changing world of software development.</p>Lasse SchultebraucksSoftware development is a dynamic field that is constantly evolving. Therefore, it is crucial for software developers to continuously acquire new knowledge and keep existing knowledge up to date. In the process of acquiring knowledge in software development, we can distinguish three categories:My top 10 Software Development books (every developer should read)2022-11-03T00:00:00+00:002022-11-03T00:00:00+00:00http://lasseschultebraucks.com/books/software%20development/my-top-ten-software-development-books<p>In the following blog post, I will list 10 books for software developers that I have particularly enjoyed over the past few years.</p>
<h1 id="1-clean-code---a-handbook-of-agile-software-craftmanship-by-robert-c-martin">1. Clean Code - A Handbook of Agile Software Craftmanship by Robert C. Martin</h1>
<p><img src="http://lasseschultebraucks.com/assets/img/cleanCode_book_cover.jpg" alt="Clean Code Book cover" /></p>
<p>This classic should be read by every software developer at least once in his life. The author, Robert C. Martin (Uncle Bob) describes the difference between good and bad code. Further he introduces how to transform bad code into good code and describes the basics of Test-Driven-Development. It is really a very good book for software developers who are at the beginning of their career, however, even after a few years and re-reading, you can always learn something new.</p>
<h1 id="2-clean-architecture-a-craftsmans-guide-to-software-structure-and-design-by-robert-c-martin">2. Clean Architecture: A Craftsman’s Guide to Software Structure and Design by Robert C. Martin</h1>
<p><img src="http://lasseschultebraucks.com/assets/img/cleanArch_book_cover.jpg" alt="Clean Architecture book cover" /></p>
<p>Another book by Robert C. Martin and I promise it won’t be the last on this list. It follows Clean Code and discusses what good architecture looks like and what principles of software development there are. Further, Uncle Bob describes what can go wrong with architecture design decisions and what can be done about it.</p>
<h1 id="3-the-clean-coder-a-code-of-conduct-for-professional-programmers-by-robert-c-martin">3. The Clean Coder: A Code of Conduct for Professional Programmers by Robert C. Martin</h1>
<p><img src="http://lasseschultebraucks.com/assets/img/cleanCoder_cover.jpg" alt="The Clean Coder book cover" /></p>
<p>Next, we have another book by Robert C. Martin. In The Clean Coder, Uncle Bob describes what it means to act like a software craftsman. He tells you when to say “no” and how to do it, and also when to say “yes” and what “yes” really means. He tells you about the responsbility you have as a software developer.</p>
<h1 id="4-clean-craftsmanship-disciplines-standards-and-ethics-by-robert-c-martin">4. Clean Craftsmanship: Disciplines, Standards, and Ethics by Robert C. Martin</h1>
<p><img src="http://lasseschultebraucks.com/assets/img/cleanCraft_cover.jpg" alt="Clean Craftmanship book cover" /></p>
<p>I promise, this will be the last book by Robert C. Martin in this list. The book ties in with The Clean Coder and explains what it means to be a software developer and what your responsibilities are. It describes technical practice and the history of software development. Uncle Bob also explains how to solve the problems of your employer, customers, colleagues and others. If you liked The Clean Coder, you will love Clean Craftmanship.</p>
<h1 id="5-refactoring-improving-the-design-of-existing-code-by-martin-fowler">5. Refactoring: Improving the Design of Existing Code by Martin Fowler</h1>
<p><img src="http://lasseschultebraucks.com/assets/img/refactoring_book_cover.jpg" alt="Refactoring book cover" /></p>
<p>Martin Fowler is one of my favorite authors, along with Robert C. Martin, when it comes to software development. In Refactoring, Martin Fowler describes how we can improve the design of existing code without changing its behavior. He lists a catalog of over 40 refactoring methods and describes how to use them to transform code to clean code. Step by step he explains in examples how refactoring can be used. Through the many examples and simply held methods, the learned knowledge can be applied quickly and pragmatically in practice.</p>
<h1 id="6-the-pragamtic-programmer-by-david-thomas--andrew-hunt">6. The Pragamtic Programmer by David Thomas & Andrew Hunt</h1>
<p><img src="http://lasseschultebraucks.com/assets/img/pragmaticProgrammer_cover.jpg" alt="Programatic Programmer book cover" /></p>
<p>The Pragmatic Programmer by David Thomas & Andrew Hunt is about personal responsility, carrer development and architectural techniques for keeping code flexible and easty to adept and reuse. It was rewritten and again published after twenty years in 2019 and is therefore up-to-date.</p>
<h1 id="7-the-passionate-programmer-creating-a-remarkable-career-in-software-development-by-chad-fowler">7. The Passionate Programmer: Creating a Remarkable Career in Software Development by Chad Fowler</h1>
<p><img src="http://lasseschultebraucks.com/assets/img/passionateProgrammer_cover.jpg" alt="Passionate Programmer book cover" /></p>
<p>The Passionate Programmer by Chad Fowler is again a book about the carrer as a software developer.</p>
<h1 id="8-code-that-fits-in-your-head--heuristics-for-software-engineering-robert-c-martin-by-mark-seemann">8. Code That Fits in Your Head : Heuristics for Software Engineering (Robert C. Martin) by Mark Seemann</h1>
<p><img src="http://lasseschultebraucks.com/assets/img/codeHead_cover.jpg" alt="Code Head book cover" /></p>
<p>Code That Fits in Your Head by Mark Seemann is about reducing complexity in your code and developing software more sustainably. He talks about software development metaphors and why bad metaphors does not fit in the software development process. Also he talks about productivity and how to solve problems more quickly and effectively.</p>
<h1 id="9-design-patterns-elements-of-reusable-object-oriented-software-by-erich-gamma-richard-helm-ralph-johnson-john-vlissides">9. Design Patterns. Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides</h1>
<p><img src="http://lasseschultebraucks.com/assets/img/designPatterns_cover.jpg" alt="design patterns book cover" /></p>
<p>Design Patterns are solutions to common occurring problems in software development. Thereforce it is important to know about common patterns. In book 23 design pattern of the categories’ creational, structural, and behavioural patterns will be discussed. The book is also very suitable as a reference book for design patterns and coding exercises.</p>
<h1 id="10-code-complete-a-practical-handbook-of-software-construction-by-steve-mcconnell">10. Code Complete: A Practical Handbook of Software Construction by Steve McConnell</h1>
<p><img src="http://lasseschultebraucks.com/assets/img/codeComplete_cover.jpg" alt="code complete book cover" /></p>
<p>Last but not least, Code Complete by Steve McConnell covers aspects of clean code, best practices and software architecture. It is very comprehensive and covers various topics from almost all the books mentioned so far in almost a thousand pages.</p>Lasse SchultebraucksIn the following blog post, I will list 10 books for software developers that I have particularly enjoyed over the past few years.Are you busy or productive?2022-08-03T00:00:00+00:002022-08-03T00:00:00+00:00http://lasseschultebraucks.com/non-tech/are-you-busy-or-productive<p>What does your calendar look like? Is it packed with meetings or do you have enough time for concentrated work?</p>
<p>Meetings. The ultimate productivity killer. Many meetings can keep people busy, but this is no guarantee for results. Meetings can not only take away time, but also ideas, potential, concentration. Furthermore, it can lead to unnecessary stress and frustration, even burnout. I don’t want to talk completely bad about meetings, there are meetings that make sense, but meetings in which 2-3 people talk and 7 others listen belong rather less in this category.</p>
<p>Always looking busy and disappearing into meetings is unfortunately commonplace in many companies. But there are effective methods. Often, a phone call or a well-worded e-mail leads to the goal.</p>
<p>It is not professional to waste 80% of your time in meetings. On the contrary, you are professionally resigning from meetings that are not relevant to you or leaving meetings that are no longer relevant to you. Sitting out meetings to look busy to colleagues and your boss does not lead to more productivity.</p>
<p>To work productively, you just need to follow some basic rules.</p>
<p>First of all, define a task that is most important to you at the moment. Focus on exactly this task and do not do other tasks in parallel. Multitasking is a myth and only leads to the fact that we need more time to do the same number of tasks “at the same time”, one after the other. If a task seems too big, divide it into several smaller tasks.</p>
<p>Your calendar isn’t just there to get cluttered with meetings. Make time and schedule your task in timeboxes throughout the day or week. This is not always possible, but most of the time you will always find free time to concentrate on your work. Schedule this with your top 1 priority task. Timeboxing is a very effective way to schedule tasks and has many advantages over a simple todo list. You can immediately see how much time you have and if the tasks you have set for yourself are realistic to complete.</p>
<p>You can also set personal goals for the day. At the beginning of the day, ask yourself what you want to have done by the end of the day. At the end of the day, see if you have achieved the goal. This will give you a better feeling about your performance on the day and help you plan better.</p>
<p>When I was a student, I wrote a post about <a href="https://lasseschultebraucks.com/life/work/university/productivity/how-i-plan-my-days-with-todoist-and-google-calendar.html">how I plan my week using Todoist and Google Calendar</a>. This has worked well since then and I still do it currently.</p>Lasse SchultebraucksWhat does your calendar look like? Is it packed with meetings or do you have enough time for concentrated work?End the day with a failing unit test2022-07-15T00:00:00+00:002022-07-15T00:00:00+00:00http://lasseschultebraucks.com/tdd/end-the-day-with-a-failing-unit-test<p>In the last days I tried to end the day with a failing unit test. This may sound wrong at first, but in the end it offers many advantages, which I would like to explain in the following.</p>
<p>I work according to Test Driven Development, a method that should be familiar to every professional software developer. With TDD, the actual programming is done in iterations:</p>
<ol>
<li>You write a test that describes the new behavior. This test (probably) does not satisfy the previous implementation, so the test fails.</li>
<li>You write the minimal implementation to run this test and all previous tests correctly.</li>
<li>You refactor according to the common method: minimal steps to make the code cleaner, test run to check if all tests pass successfully.</li>
</ol>
<p>It seems plausible that a final result that can be checked in and is deployable cannot come about after the first step. The build pipelines would fail because there is a test that does not pass successfully.</p>
<p>But the idea behind “writing the test first” is also among other things to describe the later functionality of the software. When you write the test you analyse the requirement of the software you will write later and figure out the details. I usually find it more difficult to write a good unit test than the later implementation to make the written unit test run successfully. This is not always true, but in my perception most of the time.</p>
<p>It obviously feels very good at the end of the day to complete a task, run all tests successfully, check in the code and finish the feature you were working on. But if this is not the case, then it can be a good idea to write a unit test to prepare for the next morning. This can be compared to putting out the fresh laundry the night before you go to bed or setting the table for breakfast the next day. All these activities can make the start of the day easier and more pleasant. The same is with the unit test that fails, which you write at the end of the day to prepare for the next morning.</p>Lasse SchultebraucksIn the last days I tried to end the day with a failing unit test. This may sound wrong at first, but in the end it offers many advantages, which I would like to explain in the following.One programming language per year2021-10-29T00:00:00+00:002021-10-29T00:00:00+00:00http://lasseschultebraucks.com/learning/programming%20languages/one-programming-language-per-year<p>Constant learning is an important concept as a software developer, especially as a consultant.</p>
<p>Regarding skill distribution, there is often talk of generalists as well as specialists. In reality, t-shaped people are in demand. T-Shaped describes a generalist with at least one specialty. This is e.g. a fullstack developer with specialization in backend technologies with Java. However, this full stack developer is also familiar with frontend technologies and knows what the current trends are there. Not in depth, but he knows and can orient himself. For companies, T-shapend individuals are also very valuable, as they not only gain a specialist, but also a person with additional areas of knowledge. As a result, the person can also take on additional tasks. Especially in SCRUM teams T-Shaped people are in demand, because they can adopt different perspectives and are flexible in their tasks.</p>
<p>That’s why I try a new programming language every year and try to learn the different trends in programming languages that way. Programming languages are not everything, but they are the cornerstone for further technologies. It is therefore important to know different ones in order to have an answer for every situation.</p>
<p>I achieve this among others with AdventOfCode. The AdventOfCode is an advent calendar with programming puzzles. Every day in December, from the 1st to the 25th, there is a two-part puzzle to solve. The solutions can be solved universally with any programming language. Each year I choose a programming language, typically a programming language I have almost no experience with or a programming language I want to go into more. This automatically gives me a fun introduction to a programming language, and I quickly learn how the different language features work. Last year this was Kotlin, this year I expect to try Go.</p>
<p>What I also always find very interesting when learning a new programming language and technology is how other developers develop with the programming language. That’s why at AdventOfCode I also look at many other solutions, besides the language I used at AdventOfCode also solutions from other programming languages.</p>
<p>After an introduction to a programming language through AdventOfCode, I usually try my hand at the programming language with smaller projects. This way I get to know the ecosystem of the language, like frameworks. I also get inspiration from many other projects, e.g. via GitHub in the respective programming language.</p>
<p>Learning different programming language also reinforces the knowledge of individual programming languages, as many concepts and aspects are shared between programming languages. Also, there are many aspects that are different in different programming languages, like memory management and typing.</p>
<p>These different aspects are the reason why I am always happy to learn a new programming language.</p>Lasse SchultebraucksConstant learning is an important concept as a software developer, especially as a consultant.Playing Darts2021-03-15T00:00:00+00:002021-03-15T00:00:00+00:00http://lasseschultebraucks.com/non-tech/darts/playing-darts<p>After a long time without blog post and over a year of pandemic, this is the first blog post again from me.</p>
<p>A lot has happened around the world, but also for me personally and professionally. Fortunately, I and my family and friends are not too affected by the pandemic.</p>
<p>As for me personally: I was able to write my bachelor thesis last year and then start working full time as an IT consultant. After I was able to spend some time regularly at the customer’s office in the fall, I have been working completely from home again since mid-December. My employer itself has coped very well with the crisis and has accordingly made a very good start in 2021.</p>
<p>But what I really wanted to write about is darts. And not about the programming language but about the sport darts. I used to play darts with friends and acquaintances from time to time and also played on an e-dart board, but after I moved into my own apartment last year I got myself a dart board. I would definitely still call myself a beginner, but I’ve gotten a little better.</p>
<p>It’s a good contrast to my other activities where I sit at my desk. Walking, running and sports are of course still things I do, but darts is a good alternative that is easy to do from home and where you can be a little active without getting too exhausted. Most of the time I play darts alone, but in the last few months I’ve been playing once a week with a friend via webcam, which is always fun and a good way to socialize during those times.</p>
<p>One milestone I would like to reach is my first 180. So far I have been playing a little bit of darts more or less every day for half a year, but I have not yet thrown a 180. A 180 is three darts into the triple 20, which adds up to 3 x 3 x 20 = 180. I expect to reach this milestone this year. So far, I’ve hit the Triple 20 a few times already with two out of three darts.</p>
<p>Darts is definitely not the sport that is effective to build muscles or improve his condition, however, through darts can improve his focus, concentration and fine motor skills.</p>
<p>That’s it for now, when I throw my first 180 I will definitely share it on Twitter. Otherwise, in the next times I will write about different topics, technical and non-technical.</p>
<p>Edit: <a href="https://twitter.com/LSchultebraucks/status/1383047550685577217">I did it</a>!</p>
<p><img src="http://lasseschultebraucks.com/assets/dart180.jpg" alt="" /></p>Lasse SchultebraucksAfter a long time without blog post and over a year of pandemic, this is the first blog post again from me.Migrations with Spring Boot and Flyway2019-09-01T00:00:00+00:002019-09-01T00:00:00+00:00http://lasseschultebraucks.com/spring%20boot/java/hibernate/flyway/database/flyway-spring-boot<p>In the last month I worked a lot with migrations in a Spring Boot application. I used <a href="https://flywaydb.org/">Flyway</a> as a version control tool to manage migration scripts. Flyway is a great and easy to use tool to deal with migrations in a Java project with a SQL database.</p>
<p>In the following I will show you in a demo application how to set up flyway in a spring boot application with PostgreSQL. You can check out the whole code on my <a href="https://github.com/LSchultebraucks/FlywayMigrationDemoSpringBoot">GitHub</a>.</p>
<p>First we need to create a fresh spring boot application. You can also add Flyway to your spring boot application if you are already in development or in production and want to begin with database migrations.</p>
<p>You can create a fresh spring boot application with the <a href="https://start.spring.io/">spring initializer</a>. As dependencies choose Web, JPA, Flyway and PostgreSQL. That is all you need in the beginning. I started with adding a Book entity.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">com.lasseschultebraucks.flyway.demo.model</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.persistence.Entity</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.persistence.GeneratedValue</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.persistence.GenerationType</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.persistence.Id</span><span class="o">;</span>
<span class="nd">@Entity</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Book</span> <span class="o">{</span>
<span class="nd">@Id</span>
<span class="nd">@GeneratedValue</span><span class="o">(</span><span class="n">strategy</span> <span class="o">=</span> <span class="nc">GenerationType</span><span class="o">.</span><span class="na">AUTO</span><span class="o">)</span>
<span class="kd">private</span> <span class="kt">long</span> <span class="n">id</span><span class="o">;</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="n">name</span><span class="o">;</span>
<span class="kd">public</span> <span class="nc">Long</span> <span class="nf">getId</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">id</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setId</span><span class="o">(</span><span class="nc">Long</span> <span class="n">id</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">id</span> <span class="o">=</span> <span class="n">id</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getName</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">name</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setName</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>As you can see it already has JPA annotations on the class and on one attribute to mark the whole class as a database entity and the determine the primary key.</p>
<p>Next we can use PostgreSQL to set up a local database and to connect it to our application. Therefore we first need to <a href="https://www.postgresql.org/download/">download and install PostgreSQL</a>. After the installation you can start pgAdmin, add a user (with username/password <code class="language-plaintext highlighter-rouge">admin</code>) and create a new database named <code class="language-plaintext highlighter-rouge">flyway-core</code> and owner <code class="language-plaintext highlighter-rouge">admin</code>.</p>
<p>Next we can create the configure the connection to the database in the <code class="language-plaintext highlighter-rouge">application.yaml</code>.</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">spring</span><span class="pi">:</span>
<span class="na">datasource</span><span class="pi">:</span>
<span class="na">url</span><span class="pi">:</span> <span class="s">jdbc:postgresql://localhost:5432/flyway-demo</span>
<span class="na">username</span><span class="pi">:</span> <span class="s">${db.appUser:admin}</span>
<span class="na">password</span><span class="pi">:</span> <span class="s">${db.password:admin}</span>
<span class="na">jpa</span><span class="pi">:</span>
<span class="na">hibernate</span><span class="pi">:</span>
<span class="na">ddl-auto</span><span class="pi">:</span> <span class="s">none</span>
<span class="na">database-platform</span><span class="pi">:</span> <span class="s">org.hibernate.dialect.PostgreSQLDialect</span>
<span class="na">properties</span><span class="pi">:</span>
<span class="na">hibernate</span><span class="pi">:</span>
<span class="na">temp</span><span class="pi">:</span>
<span class="na">use_jdbc_metadata_defaults</span><span class="pi">:</span> <span class="no">false</span>
<span class="na">flyway</span><span class="pi">:</span>
<span class="na">baseline-on-migrate</span><span class="pi">:</span> <span class="no">true</span>
</code></pre></div></div>
<p>In the first lines we have configured our PostgreSQL database connection. Then we told hibernate to disable the automatic schema generation, because we will deal with it yourself now. Last but not least we enabled the flyway migration on the application start.</p>
<p>Next we can create our first migration script. We can either create migration scripts in Java or SQL with flyway. In this tutorial I will just create migration scripts in SQL. To do this, we need to create a new file in the <code class="language-plaintext highlighter-rouge">resources/db/migration</code> package. Flyway executes the migration script in folder based on their version numbers. So we will start with a file named <code class="language-plaintext highlighter-rouge">V0__InitialBook.sql</code></p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="k">public</span><span class="p">.</span><span class="n">book</span>
<span class="p">(</span>
<span class="n">id</span> <span class="nb">BIGINT</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
<span class="n">name</span> <span class="nb">CHARACTER</span> <span class="nb">varying</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span>
<span class="k">CONSTRAINT</span> <span class="n">book_pkey</span> <span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="p">(</span><span class="n">id</span><span class="p">)</span>
<span class="p">);</span>
<span class="k">ALTER</span> <span class="k">TABLE</span> <span class="k">public</span><span class="p">.</span><span class="n">book</span>
<span class="k">OWNER</span> <span class="k">TO</span> <span class="k">admin</span><span class="p">;</span>
</code></pre></div></div>
<p>As you can see the script will create a new table in our database for the book entity which we created previously.</p>
<p>Now we can start our Spring Boot Application for the first time. You can open pgAdmin and see that the there will be now a table named <code class="language-plaintext highlighter-rouge">book</code>. There is also a table named flyway_schema_history, which holds and manage the current version and state of the database. If there is a new migration script which is not marked in the table, then flyway will execute the script and bring the database to the newest state.</p>
<p>Next I added a new entity named <code class="language-plaintext highlighter-rouge">Author</code>.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">com.lasseschultebraucks.flyway.demo.model</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">javax.persistence.*</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.ArrayList</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.Collection</span><span class="o">;</span>
<span class="nd">@Entity</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Author</span> <span class="o">{</span>
<span class="nd">@Id</span>
<span class="nd">@GeneratedValue</span><span class="o">(</span><span class="n">strategy</span> <span class="o">=</span> <span class="nc">GenerationType</span><span class="o">.</span><span class="na">AUTO</span><span class="o">)</span>
<span class="kd">private</span> <span class="nc">Long</span> <span class="n">id</span><span class="o">;</span>
<span class="nd">@Column</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"author_name"</span><span class="o">)</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="n">name</span><span class="o">;</span>
<span class="nd">@OneToMany</span><span class="o">(</span><span class="n">mappedBy</span> <span class="o">=</span> <span class="s">"author"</span><span class="o">,</span> <span class="n">cascade</span> <span class="o">=</span> <span class="nc">CascadeType</span><span class="o">.</span><span class="na">DETACH</span><span class="o">)</span>
<span class="kd">private</span> <span class="nc">Collection</span><span class="o"><</span><span class="nc">Book</span><span class="o">></span> <span class="n">bookCollection</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o"><>();</span>
<span class="kd">public</span> <span class="nc">Long</span> <span class="nf">getId</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">id</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setId</span><span class="o">(</span><span class="nc">Long</span> <span class="n">id</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">id</span> <span class="o">=</span> <span class="n">id</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getName</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">name</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setName</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="nc">Collection</span><span class="o"><</span><span class="nc">Book</span><span class="o">></span> <span class="nf">getBookCollection</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">bookCollection</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setBookCollection</span><span class="o">(</span><span class="nc">Collection</span><span class="o"><</span><span class="nc">Book</span><span class="o">></span> <span class="n">bookCollection</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">bookCollection</span> <span class="o">=</span> <span class="n">bookCollection</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Also the book entity gets an extra line:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="c1">// ...</span>
<span class="nd">@ManyToOne</span>
<span class="kd">private</span> <span class="nc">Author</span> <span class="n">author</span><span class="o">;</span>
<span class="c1">//...</span>
</code></pre></div></div>
<p>As you can see, there is now a Many to One relationship between Author and book.</p>
<p>Because we have a new entity and also a new relationship between our entities we have to update our database schema with a second migration script:</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="k">public</span><span class="p">.</span><span class="n">author</span><span class="p">(</span>
<span class="n">id</span> <span class="nb">BIGINT</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
<span class="n">author_name</span> <span class="nb">CHARACTER</span> <span class="nb">varying</span><span class="p">(</span><span class="mi">255</span><span class="p">),</span>
<span class="k">CONSTRAINT</span> <span class="n">author_pkey</span> <span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="p">(</span><span class="n">id</span><span class="p">)</span>
<span class="p">);</span>
<span class="k">ALTER</span> <span class="k">TABLE</span> <span class="k">public</span><span class="p">.</span><span class="n">author</span>
<span class="k">OWNER</span> <span class="k">TO</span> <span class="k">admin</span><span class="p">;</span>
<span class="k">ALTER</span> <span class="k">TABLE</span> <span class="k">public</span><span class="p">.</span><span class="n">book</span>
<span class="k">ADD</span> <span class="n">author_id</span> <span class="nb">bigint</span><span class="p">,</span>
<span class="k">ADD</span> <span class="k">CONSTRAINT</span> <span class="n">author_id</span> <span class="k">FOREIGN</span> <span class="k">KEY</span> <span class="p">(</span><span class="n">author_id</span><span class="p">)</span>
<span class="k">REFERENCES</span> <span class="k">public</span><span class="p">.</span><span class="n">author</span> <span class="p">(</span><span class="n">id</span><span class="p">)</span> <span class="k">MATCH</span> <span class="k">SIMPLE</span><span class="p">;</span>
<span class="k">CREATE</span> <span class="n">SEQUENCE</span> <span class="k">public</span><span class="p">.</span><span class="n">hibernate_sequence</span>
<span class="k">INCREMENT</span> <span class="mi">1</span>
<span class="k">MINVALUE</span> <span class="mi">1</span>
<span class="k">MAXVALUE</span> <span class="mi">9223372036854775807</span>
<span class="k">START</span> <span class="mi">1</span>
<span class="k">CACHE</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">ALTER</span> <span class="k">TABLE</span> <span class="k">public</span><span class="p">.</span><span class="n">hibernate_sequence</span>
<span class="k">OWNER</span> <span class="k">TO</span> <span class="k">admin</span><span class="p">;</span>
</code></pre></div></div>
<p>The first two queries will create an author table and create a foreign key constraint in book for the author id.</p>
<p>The last query will create a hibernate sequence. A hibernate sequence manage the id numbers in our database, so that no entity has equals ids. We need this because in our next step we will insert data in our database:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">com.lasseschultebraucks.flyway.demo</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.lasseschultebraucks.flyway.demo.model.Author</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.lasseschultebraucks.flyway.demo.model.Book</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.lasseschultebraucks.flyway.demo.repository.AuthorRepository</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.lasseschultebraucks.flyway.demo.repository.BookRepository</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.beans.factory.annotation.Autowired</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.boot.CommandLineRunner</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.boot.SpringApplication</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">org.springframework.boot.autoconfigure.SpringBootApplication</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.Arrays</span><span class="o">;</span>
<span class="nd">@SpringBootApplication</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">DemoApplication</span> <span class="kd">implements</span> <span class="nc">CommandLineRunner</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="nc">AuthorRepository</span> <span class="n">authorRepository</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="nc">BookRepository</span> <span class="n">bookRepository</span><span class="o">;</span>
<span class="nd">@Autowired</span>
<span class="kd">public</span> <span class="nf">DemoApplication</span><span class="o">(</span><span class="nc">AuthorRepository</span> <span class="n">authorRepository</span><span class="o">,</span> <span class="nc">BookRepository</span> <span class="n">bookRepository</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">authorRepository</span> <span class="o">=</span> <span class="n">authorRepository</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">bookRepository</span> <span class="o">=</span> <span class="n">bookRepository</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">SpringApplication</span><span class="o">.</span><span class="na">run</span><span class="o">(</span><span class="nc">DemoApplication</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="n">args</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">run</span><span class="o">(</span><span class="nc">String</span><span class="o">...</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
<span class="n">clearTables</span><span class="o">();</span>
<span class="nc">Author</span> <span class="n">author</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Author</span><span class="o">();</span>
<span class="n">author</span><span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="s">"J.K. Rowling"</span><span class="o">);</span>
<span class="nc">Book</span> <span class="n">book</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Book</span><span class="o">();</span>
<span class="n">book</span><span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="s">"Harry Potter and the Philosopher’s Stone"</span><span class="o">);</span>
<span class="n">book</span><span class="o">.</span><span class="na">setAuthor</span><span class="o">(</span><span class="n">author</span><span class="o">);</span>
<span class="nc">Book</span> <span class="n">book1</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Book</span><span class="o">();</span>
<span class="n">book1</span><span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="s">"Harry Potter and the Chamber of Secrets"</span><span class="o">);</span>
<span class="n">book1</span><span class="o">.</span><span class="na">setAuthor</span><span class="o">(</span><span class="n">author</span><span class="o">);</span>
<span class="n">author</span><span class="o">.</span><span class="na">setBookCollection</span><span class="o">(</span><span class="nc">Arrays</span><span class="o">.</span><span class="na">asList</span><span class="o">(</span>
<span class="n">book</span><span class="o">,</span> <span class="n">book1</span>
<span class="o">));</span>
<span class="n">authorRepository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">author</span><span class="o">);</span>
<span class="n">bookRepository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">book</span><span class="o">);</span>
<span class="n">bookRepository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">book1</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kt">void</span> <span class="nf">clearTables</span><span class="o">()</span> <span class="o">{</span>
<span class="n">authorRepository</span><span class="o">.</span><span class="na">deleteAll</span><span class="o">();</span>
<span class="n">bookRepository</span><span class="o">.</span><span class="na">deleteAll</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>After executing once again our Spring Boot application we will now have a new state of our database and also initial data in our database. You can check you state of your database once again in pgAdmin.</p>
<p>As mentioned earlier, you can find the whole code on my <a href="https://github.com/LSchultebraucks/FlywayMigrationDemoSpringBoot">GitHub</a>.</p>Lasse SchultebraucksIn the last month I worked a lot with migrations in a Spring Boot application. I used Flyway as a version control tool to manage migration scripts. Flyway is a great and easy to use tool to deal with migrations in a Java project with a SQL database.Basic Authentication2019-01-22T00:00:00+00:002019-01-22T00:00:00+00:00http://lasseschultebraucks.com/rest/security/basic-authentication<p>In one of my latest blog posts I talked about <a href="https://lasseschultebraucks.com/security/2019/01/18/introduction-to-authentication-and-authorization.html">authentication and authorization</a>.</p>
<p>Now I want to dive deeper and tackle common authentication methods for REST APIs.
In this blog post I start with one of the most common and easiest way to implement authentication methods.</p>
<h1 id="basic-authentication-ba">Basic Authentication (BA)</h1>
<p>One of the most common and easiest ways to secure a REST API is by using Basic authentication. Its a protocol which current standard is written down in <a href="https://tools.ietf.org/html/rfc7617">RFC 7617</a> (2015).</p>
<p>Technical you use the HTTP headers to send information in the form of</p>
<p><code class="language-plaintext highlighter-rouge">Authorization: Basic <credentials</code></p>
<p>where credentials is base64 encoded username (or id) and password are joined by a colon.</p>
<p>So e.g. a User with username <code class="language-plaintext highlighter-rouge">user</code> and password <code class="language-plaintext highlighter-rouge">user</code> is represented in the HTTP header in the following way:</p>
<p><code class="language-plaintext highlighter-rouge">Authorization: Basic dXNlcjp1c2Vy</code></p>
<p><code class="language-plaintext highlighter-rouge">dXNlcjp1c2Vy</code> is a encoded base64 string of <code class="language-plaintext highlighter-rouge">user:user</code>.</p>
<h2 id="security">Security</h2>
<p>Basic Authentication is not confidential, which means that the information can be viewed by everyone and is not private. Because Base64 can simply be encoded and decoded it is not secured information like hashed or encrypted information.</p>
<p>Nevertheless Basic Authentication can be used in a confidential way by simply using HTTPS instead of HTTP.</p>
<p>If you are using Basic Authentication in production, be sure to always use HTTPS!</p>
<h2 id="mechanism">Mechanism</h2>
<p>Because of the technical conditions the browser is required to cache the the credentials of the user. This is necessary, because the headers has to be sent within every HTTP request.</p>
<p>Also the server has no direct way to logout a user of his session. The server can’t just declare the credentials of the user as expired or invalid. But instead he can redirect the client to a URL of the site where the credentials are incorrect by purpose. Another possibility is to call a JavaScript method to clear stored credentials. But this is dependent from browser.</p>
<p>The most and easiest way to create a log out mechanism is to send the user a 401 if the client clicked on log out and then direct him to wrong credentials like a blank user and password. In this way his previous credentials will be deleted from cache and he is successfully unauthorized.</p>
<h2 id="implementation">Implementation</h2>
<p>The actual implementation of Basic Authentication on client and server side is easy compared to other authentication methods.</p>
<p>Plain JavaScript actually provides with <code class="language-plaintext highlighter-rouge">window.btoa</code> a method to encode a string in base64. To save the credentials you can use the local storage in your browser.</p>
<p>On server side you can also just decode the credentials and match them with the actual password. If you are using frameworks like Spring Boot you can write your whole Security configuration at one place. The server side code implementation of Basic Authentication is probably more costly than the client side implementation, but this also heavily depends on your chosen technologies for your backend. For most technologies you can find a fitting implementation on the internet.</p>
<h1 id="conclusion">Conclusion</h1>
<p>Basic Authentication is an easy and fast way to implement authentication for your API and or web application. Be sure to always use HTTPS if you are in production and you are using Basic Authentication. SSL certificates are free therefore there is no excuse not to have one for your web application.</p>Lasse SchultebraucksIn one of my latest blog posts I talked about authentication and authorization.