<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tomas Tulka</title>
    <description>The latest articles on DEV Community by Tomas Tulka (@ttulka).</description>
    <link>https://dev.to/ttulka</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F285264%2F16f89d1e-e231-48ce-88b6-8b963d09ed06.jpg</url>
      <title>DEV Community: Tomas Tulka</title>
      <link>https://dev.to/ttulka</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ttulka"/>
    <language>en</language>
    <item>
      <title>Learning WebAssembly</title>
      <dc:creator>Tomas Tulka</dc:creator>
      <pubDate>Tue, 12 Jan 2021 09:21:49 +0000</pubDate>
      <link>https://dev.to/ttulka/learning-webassembly-series-34hd</link>
      <guid>https://dev.to/ttulka/learning-webassembly-series-34hd</guid>
      <description>&lt;p&gt;A series of learning texts covering the first steps with WebAssembly for complete beginners.&lt;/p&gt;




&lt;p&gt;Some time ago I started learning WebAssembly as an absolute beginner. It has been an exciting but not so simple journey.&lt;/p&gt;

&lt;p&gt;I decided to publish my continuous and probably neverending notices to make your learning path a little easier.&lt;/p&gt;

&lt;p&gt;Here is the actual list of already finished posts. I will constantly update and extend it.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://blog.ttulka.com/learning-webassembly-1-hello-world-of-wasm"&gt;Hello, World of Wasm!&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Let’s try WebAssembly for the first time. We will create a simple program in the Wat text format, compile it into Wasm binary, and finally execute it in a browser and as a server application.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://blog.ttulka.com/learning-webassembly-2-wasm-binary-format"&gt;Wasm Binary Format&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;We will explore the structure of the Wasm binary format byte by byte.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://blog.ttulka.com/learning-webassembly-3-wat-programming-basics"&gt;Wat Programming Basics&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Finally some real programming! We will learn the very basics of the Wat text format, how to work with functions and variables, write conditions, and loops.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://blog.ttulka.com/learning-webassembly-4-wasm-memory-and-working-with-strings"&gt;Wasm Memory and Working with Strings&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The concept of memory objects is very important know-how in Wasm. We will use it to deal with strings.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://blog.ttulka.com/learning-webassembly-5-running-wasm-in-the-browser"&gt;Running Wasm in the Browser&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;WebAssembly is part of the web platform, thus it is important to understand interactions between Wasm and JavaScript. We will learn about shared memory and global variables.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://blog.ttulka.com/learning-webassembly-6-running-wasm-in-nodejs"&gt;Running Wasm in Node.js&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Browser is not the only environment that Wasm can run in. We will also learn how to execute Wasm in Node.js, the popular backend platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://blog.ttulka.com/learning-webassembly-7-introducing-wasi"&gt;Introducing WASI&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;WebAssembly System Interface (WASI) provides access to several operating-system-like features from Wasm. We will learn how to write programs that use WASI.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://blog.ttulka.com/learning-webassembly-8-compiling-into-wasm"&gt;Compiling into Wasm&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;There are plenty of languages that can be compiled into Wasm. We will take a look at some of them.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://blog.ttulka.com/learning-webassembly-9-assemblyscript-basics"&gt;AssemblyScript Basics&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;AssemblyScript syntax is very close to JavaScript and as such is an ideal candidate to write Wasm in. We will explore the basics of AssemblyScript and create a few neat programs.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://blog.ttulka.com/learning-webassembly-10-image-processing-in-assemblyscript"&gt;Image Processing in AssemblyScript&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;WebAssembly is a great fit for computation-intensive tasks like generating and processing graphics. We will experiment in this field a little.&lt;/p&gt;




&lt;p&gt;You are welcome to join me on the exciting journey of learning WebAssembly!&lt;/p&gt;

</description>
      <category>webassembly</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Junior Software Architect</title>
      <dc:creator>Tomas Tulka</dc:creator>
      <pubDate>Wed, 16 Dec 2020 15:36:17 +0000</pubDate>
      <link>https://dev.to/ttulka/junior-software-architect-58pc</link>
      <guid>https://dev.to/ttulka/junior-software-architect-58pc</guid>
      <description>&lt;p&gt;Let me get this straight, software architect is no job title to me, it's a role. A role assigned to one or more persons in the team.&lt;/p&gt;

&lt;p&gt;In my experience, the architectural role is taken very naturally by the most experienced or capable developer with great communication skills. Usually, the best ones from us.&lt;/p&gt;

&lt;p&gt;Charisma, respect, and natural authority is a good driver for picking up the right person. The role comes with great responsibility and must be accepted by the whole team to succeed.&lt;/p&gt;

&lt;p&gt;The hat could be handed over with the time, there could be different architects for different topics or project slices, and so forth.&lt;/p&gt;

&lt;p&gt;Are you with me so far? All right, let's move on.&lt;/p&gt;

&lt;p&gt;In some (rare) cases, the role can match the job title. For example, the software architect must step out of the team when dealing with outsourcing or open-source community projects.&lt;/p&gt;

&lt;p&gt;But I would still expect great programming skills, a lot of experience, and natural authority, right?&lt;/p&gt;

&lt;p&gt;Now, let me tell you a true story.&lt;/p&gt;

&lt;p&gt;My company hired a new developer. He had almost no experience, poor technical skill, and, worse, no motivation.&lt;/p&gt;

&lt;p&gt;I really enjoy working with juniors. They are eager to learn, have plenty of ideas, and brilliant thinking out of the box. Having juniors in the team is always a big benefit (and fun). I advise organizations to hire more of them. All in all, we all used to be juniors once.&lt;/p&gt;

&lt;p&gt;This guy was no junior anymore, but hard skills poorer than most of the coding bootcamp graduates. But the worst thing was, he was bullshiting so much! &lt;/p&gt;

&lt;p&gt;His constant lying and excuses made each and every coworker boil blood, and our guy was finally fired. With a lot of drama and emotions, of course.&lt;/p&gt;

&lt;p&gt;After several months I saw his profile on LinkedIn. He's got a new job as a &lt;em&gt;Software Architect&lt;/em&gt; in an international financial institution. &lt;/p&gt;

&lt;p&gt;Wow.&lt;/p&gt;

&lt;p&gt;Leaving aside the question of how badly the interview process failed, I have to ask how can anyone with such poor technical skills manage this position for more than a few days?&lt;/p&gt;

&lt;p&gt;Maybe, the title &lt;em&gt;Software Architect&lt;/em&gt; has nothing to do with actual &lt;em&gt;software architecture&lt;/em&gt;. It's just somehow good to have this position in an organization that is facing a digital transformation, but there is no actual need for him to do anything useful.&lt;/p&gt;

&lt;p&gt;Create a few PowerPoint slides, skitch some generic diagrams, don't bother the development team, and don't argue with the management. You'll be happy, everybody will be happy. Win-win. An instant recipe for success. Cool!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BNCjiiy4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ztms58lf73g14zgxwiqs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BNCjiiy4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ztms58lf73g14zgxwiqs.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everyone knows the sad joke about bad managers to be recruited from good programmers. Has the time come for software architects to be recruited from bad developers?&lt;/p&gt;

&lt;p&gt;Is a &lt;em&gt;Junior Software Architect&lt;/em&gt; a real thing?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>career</category>
    </item>
    <item>
      <title>Microservices and Bounded Context </title>
      <dc:creator>Tomas Tulka</dc:creator>
      <pubDate>Tue, 15 Dec 2020 12:54:48 +0000</pubDate>
      <link>https://dev.to/ttulka/microservices-and-bounded-context-47ng</link>
      <guid>https://dev.to/ttulka/microservices-and-bounded-context-47ng</guid>
      <description>&lt;p&gt;Bounded context (DDD) is a good thing to start defining a service boundary with. But practically, it's just too coarse-grained to gain real benefits of microservices. &lt;/p&gt;

&lt;p&gt;A service per bounded context means having multiple monoliths. That could be perfectly fine as there's no problem with a monolith. However, with microservices, we want to go further. A bounded context can contain multiple services.&lt;/p&gt;

&lt;p&gt;So, what are the right boundaries for services? &lt;/p&gt;

&lt;p&gt;I believe it's business capabilities. The fine-grained a business capability can be while still remaining autonomous the small can a service be.&lt;/p&gt;

&lt;p&gt;A team per service or a team taking care of multiple services within one bounded context is a good practice. However, a single team should not be working across multiple bounded contexts.&lt;/p&gt;

&lt;p&gt;Services should be orthogonal, that is, one service won't affect another. &lt;/p&gt;

&lt;p&gt;How do you align your (micro)services?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>microservices</category>
      <category>architecture</category>
    </item>
    <item>
      <title>How much pragmatism is too much? </title>
      <dc:creator>Tomas Tulka</dc:creator>
      <pubDate>Mon, 14 Dec 2020 13:21:37 +0000</pubDate>
      <link>https://dev.to/ttulka/how-much-pragmatism-is-too-much-m83</link>
      <guid>https://dev.to/ttulka/how-much-pragmatism-is-too-much-m83</guid>
      <description>&lt;p&gt;There are circumstances when one has to "get things done" quickly. It's sad, but it's life. &lt;/p&gt;

&lt;p&gt;How much pragmatism is still okay and how much could kill the project in a long term? &lt;/p&gt;

&lt;p&gt;I believe, some degree of pragmatism on the lower level of code is just fine. I'm talking about one line of code more or less, one nanosecond more or less, &lt;code&gt;let&lt;/code&gt; or &lt;code&gt;const&lt;/code&gt;, things like that. &lt;/p&gt;

&lt;p&gt;On the other hand, using shortcuts in design is not just pragmatic, it's simply wrong. It creates technical debt that will grow exponentially, hard to fix in the future. &lt;/p&gt;

&lt;p&gt;The point is, design (architecture) has an overall impact, while implementation is quite isolated. &lt;/p&gt;

&lt;p&gt;Recently, I had a discussion with a software architect, who described himself as pragmatic. As that, he believes the opposite: compromises in design can save a lot of effort, but code must be as clean and efficient as possible. &lt;/p&gt;

&lt;p&gt;What are your thoughts? &lt;/p&gt;

</description>
      <category>discuss</category>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Good and Bad Monolith</title>
      <dc:creator>Tomas Tulka</dc:creator>
      <pubDate>Mon, 14 Dec 2020 07:48:45 +0000</pubDate>
      <link>https://dev.to/ttulka/good-and-bad-monolith-13mh</link>
      <guid>https://dev.to/ttulka/good-and-bad-monolith-13mh</guid>
      <description>&lt;p&gt;After several years of the &lt;a href="https://blog.ttulka.com/you-are-not-gonna-need-microservices" rel="noopener noreferrer"&gt;microservice hype&lt;/a&gt;, &lt;a href="https://blog.christianposta.com/microservices/istio-as-an-example-of-when-not-to-do-microservices/" rel="noopener noreferrer"&gt;it&lt;/a&gt; &lt;a href="https://twitter.com/kelseyhightower/status/940259898331238402" rel="noopener noreferrer"&gt;now&lt;/a&gt; &lt;a href="https://www.infoq.com/news/2020/04/microservices-back-again/" rel="noopener noreferrer"&gt;seems&lt;/a&gt; monoliths are cool again! Does it mean, we have learned a lesson?&lt;/p&gt;

&lt;p&gt;I guess at least we accepted what Neal Ford stated in his book Building Evolutionary Architectures:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you can’t build a monolith, what makes you think microservices are the answer?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The disturbing question is: Why is monolith synonymous with a bad design for some and yet the right thing to do for others?&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Kinds of Monolith
&lt;/h2&gt;

&lt;p&gt;The reason is, &lt;strong&gt;there are two different kinds of monolith&lt;/strong&gt;: physical and logical. While one is mostly a good thing, the other is pure evil.&lt;/p&gt;

&lt;h3&gt;
  
  
  Physical Monolith
&lt;/h3&gt;

&lt;p&gt;The first kind of monolith is what we usually picture under the word: a physical block of software, typically running as a single process.&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;physically monolithic&lt;/em&gt; system is developed and built as a single artifact, deployed all at once and falling down in its entirety. Resources such as a database are often shared, communication is local, interprocess.&lt;/p&gt;

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



&lt;p&gt;The opposite is then a &lt;em&gt;distributed system&lt;/em&gt; composed of multiple physically independent components each running in its own process. Each component owns its resources and communication is performed in a remote manner.&lt;/p&gt;

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



&lt;p&gt;A &lt;strong&gt;physical monolith is no anti-pattern&lt;/strong&gt;, it is a good thing to start with as it is easy to build, deploy, operate, and reason about.&lt;/p&gt;

&lt;p&gt;Physically monolithic applications are pretty performant as there are no additional overheads in communication. Cross-cutting aspects are much simpler because no special platform (such as a service mesh) is needed.&lt;/p&gt;

&lt;p&gt;As the system gets bigger, further partitioning is possible. A popular option is to apply “satellite” architecture where bottleneck services are separated from the monolithic base.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmgttcv26ep8x0g3sy1s5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmgttcv26ep8x0g3sy1s5.png" alt="Monolith with satellites"&gt;&lt;/a&gt;&lt;/p&gt;
Monolith with satellites



&lt;h3&gt;
  
  
  Logical Monolith
&lt;/h3&gt;

&lt;p&gt;The second kind is a &lt;em&gt;logically monolithic&lt;/em&gt; system. Other names used are Big ball of mud, Spaghetti code, etc. Logically monolithic codebases lack boundaries (technologies are not service boundaries!), everything is coupled to everything and no visible architecture is to be found.&lt;/p&gt;

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



&lt;p&gt;&lt;strong&gt;Logical monoliths are evil&lt;/strong&gt; and dangerous constructs that cause high complexity and tight coupling of building blocks making development expensive and error-prone.&lt;/p&gt;

&lt;p&gt;Logically monolithic software is unmaintainable on a scale and exponentially corrodes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modular and Distributed Monoliths
&lt;/h2&gt;

&lt;p&gt;By doing things right or very wrong, you will end up with one of two types of systems: modular or distributed monolith, respectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modular Monolith (Modulith)
&lt;/h3&gt;

&lt;p&gt;The opposite of a logical monolith is a &lt;em&gt;modular monolith&lt;/em&gt; (or, if you like, &lt;em&gt;modulith&lt;/em&gt;). In a modular codebase business capabilities are worked out by services with explicit logical (not necessarily physical) boundaries.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;modular monolith is probably the best architectural approach&lt;/strong&gt; for most applications. It is easy to extend, maintain, and reason about.&lt;/p&gt;

&lt;p&gt;That means, moduliths are really cool!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffe2oazeo9hi8ha5pd96c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffe2oazeo9hi8ha5pd96c.png" alt="Modular monolith (modulith)"&gt;&lt;/a&gt;&lt;/p&gt;
Modular monolith (modulith)



&lt;p&gt;Although the logical and physical natures of monoliths are independent, they often go hand in hand. That is why people easily confuse them with each other.&lt;/p&gt;

&lt;p&gt;As the boundaries in monolithic codebases are typically not physical it is easy to cross them. A monolithic codebase, therefore, requires great discipline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Distributed Monolith
&lt;/h3&gt;

&lt;p&gt;A logically, but not physically, monolithic system is called a &lt;em&gt;distributed monolith&lt;/em&gt;. Distributed monoliths have all the drawbacks of distributed systems with almost none of the benefits.&lt;/p&gt;

&lt;p&gt;While dealing with the Big ball of mud is a pain, &lt;strong&gt;distributed monoliths are a real disaster&lt;/strong&gt;.&lt;/p&gt;

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



&lt;p&gt;Systems often end up as distributed monoliths while adapting the microservices approach incorrectly.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Microservices to Monolith
&lt;/h2&gt;

&lt;p&gt;In the last years the microservices movement promised us a lot. The catch is, &lt;strong&gt;microservices focus only on physical monoliths&lt;/strong&gt;, not logical ones.&lt;/p&gt;

&lt;p&gt;To understand why we have to take a closer look at what microservices really attempt to solve.&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;microservice&lt;/em&gt; is a service with some technical additions (independent development cycle). It is important to note the word “technical” — as the logically monolithic design is obviously a logical, not technical, issue, there is nothing microservices could potentially do for us!&lt;/p&gt;

&lt;p&gt;Microservices propose a solution to tackle physical monoliths only. That is the reason so many attempts to build microservices failed badly, simply because the wrong issue was addressed and the true problem only got bigger (and, even worse, distributed).&lt;/p&gt;

&lt;p&gt;With the logically monolithic design, microservices do not come to the rescue, more the opposite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Services First
&lt;/h2&gt;

&lt;p&gt;We can think of microservices as a specific approach to Service-oriented architecture (SOA).&lt;/p&gt;

&lt;p&gt;There are several definitions of SOA, but we will focus mainly on the concept of a service, because it is the most significant. I use this modified service definition from &lt;a href="http://udidahan.com/2010/11/15/the-known-unknowns-of-soa/" rel="noopener noreferrer"&gt;Udi Dahan&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A service is the autonomous unit of logic for a specific business capability.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, it is obvious why microservices as such cannot really help us with the logically monolithic design: monolithically designed microservices are no services at all, they are mere physical components!&lt;/p&gt;

&lt;p&gt;Business alone has the key to &lt;a href="https://blog.ttulka.com/colored-services" rel="noopener noreferrer"&gt;defining our services&lt;/a&gt; correctly. &lt;strong&gt;Only well-designed services can tackle logical monoliths&lt;/strong&gt; and profit from the microservices approach.&lt;/p&gt;

&lt;p&gt;It is a hard task, but Domain-driven design can help us a lot!&lt;/p&gt;

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

&lt;p&gt;If you struggle with your monolithic system, the problem may likely lie in its logically monolithic design.&lt;/p&gt;

&lt;p&gt;The physical nature of the monolith is usually a secondary problem, easy to solve after the proper service-oriented design has been applied.&lt;/p&gt;

&lt;p&gt;Once the logical monolith is resolved, microservices architecture is just one step further...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9opzmn8nlg59p8y49jor.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9opzmn8nlg59p8y49jor.png" alt="Types of systems by physical and logical architecture"&gt;&lt;/a&gt;&lt;/p&gt;
Types of systems by physical and logical architecture






&lt;p&gt;Originally published on &lt;a href="https://blog.ttulka.com/good-and-bad-monolith" rel="noopener noreferrer"&gt;my blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>computerscience</category>
      <category>microservices</category>
      <category>programming</category>
    </item>
    <item>
      <title>Developer On A Job Interview</title>
      <dc:creator>Tomas Tulka</dc:creator>
      <pubDate>Fri, 11 Dec 2020 08:11:25 +0000</pubDate>
      <link>https://dev.to/ttulka/developer-on-a-job-interview-5h7p</link>
      <guid>https://dev.to/ttulka/developer-on-a-job-interview-5h7p</guid>
      <description>&lt;p&gt;In the last few months, I was looking for a new job as a software developer.&lt;/p&gt;

&lt;p&gt;I attended various interviews, talked to a lot of diverse people, had to solve different tasks, answered plenty of questions, and asked at least as many.&lt;/p&gt;

&lt;p&gt;In this post, I will share with you what I have learned, and tell you some useful tips for doing well at your interview to get the job of your dreams.&lt;/p&gt;

&lt;p&gt;I won’t give you an exhaustive list of technical questions, brainteasers, and riddles. Instead, I’ll tell you how to make the most sense out of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Software Today
&lt;/h2&gt;

&lt;p&gt;Software development nowadays is &lt;strong&gt;less about technology and more about people&lt;/strong&gt;. Good communication skills, knowledge sharing, and team spirit are essential qualities of software professionals in modern organizations. Software becomes more and more a people problem.&lt;/p&gt;

&lt;p&gt;Good code is driven by simple, easy-to-understand design with human factors in mind. Perfectly &lt;strong&gt;working code is no more enough&lt;/strong&gt;, as far as it is incomprehensible to other teammates. Great programming skills are not sufficient as far as you’re unable to &lt;strong&gt;communicate your work&lt;/strong&gt; clearly.&lt;/p&gt;

&lt;p&gt;This fact has been slowly understood by software companies and the interview process has been adapted accordingly. That is, a flawlessly coded quick-sort algorithm is no guarantee for getting a job offer anymore, and it is actually good.&lt;/p&gt;

&lt;p&gt;You spend a great piece of life at work. Not only is it no fun to spend this time with asocial, uncommunicative, or even rude, geeks; it is also pretty unproductive at the same time. Software development became too extensive to fit into a single head entirely, and there are &lt;a href="https://blog.ttulka.com/devops-ad-absurdum"&gt;no unicorns&lt;/a&gt;. &lt;strong&gt;Teamwork is a fundamental prerequisite for a successful (software) product&lt;/strong&gt;. From experience, just one unsuitable person on a team could cause immeasurable damage to the outcome. I bet you know exactly what I'm talking about.&lt;/p&gt;

&lt;p&gt;The extra effort at the interview to ensure you’re a good match for the team means the team is a good fit for you, too.&lt;/p&gt;

&lt;p&gt;Soft skills became an important part of your professional profile. Some of them are even more significant than the hard skills you put first in your resume. In fact, &lt;strong&gt;any technology can be learned, but it’s really difficult to unlearn being a jerk&lt;/strong&gt;. Deep knowledge of a particular programming language is not as valuable if you can’t use your potential as a team member to create a great product together. &lt;strong&gt;Crucial is the ability and will to learn, communicate, and exchange knowledge&lt;/strong&gt; with others.&lt;/p&gt;

&lt;p&gt;Reputable organizations today are not looking for lone wolves or cowboy developers. Rather, team players and excellent communicators are appreciated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tell me about yourself
&lt;/h2&gt;

&lt;p&gt;A few honest sentences about yourself, your background, &lt;strong&gt;personal values&lt;/strong&gt;, and what you are looking for, a nice photo, hobbies and interests are more valuable than an overwhelming list of technologies and programming languages you touched since your studies.&lt;/p&gt;

&lt;p&gt;Of course, hard skills are still very important, but your professional profile should tell your potential employer &lt;em&gt;who&lt;/em&gt; you are. Forget things like UML or XML, no one is interested, strike off all exotic languages you used to be programming in as a kid, you barely remember them, focus on what’s important and &lt;strong&gt;relevant to the position&lt;/strong&gt; you currently apply for.&lt;/p&gt;

&lt;p&gt;Structure your profile hierarchically, start with concepts and then go deeper. Have you designed distributed systems or developed machine learning algorithms? Start with telling that. Continue by diving into concrete technologies, languages, methods. Mention them in the list of working experiences, too. &lt;strong&gt;Be consistent and integrous&lt;/strong&gt;. Focus, structure, remove fluff.&lt;/p&gt;

&lt;p&gt;Your professional profile is a sample of your work. Being done poorly tells your potential employer you’re probably no good worker. Your professional profile must be professional.&lt;/p&gt;

&lt;p&gt;Sometimes an obligatory question comes up:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Characterize yourself using only three words.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Albeit such a question would fit more to an interview for a job in the marketing department, it’s a good idea to be able to characterize yourself with a few significant properties or values. &lt;em&gt;Open, creative and focusing&lt;/em&gt; could be a good try. You can explain those in detail afterward, ideally with some practical examples.&lt;/p&gt;

&lt;p&gt;I personally characterize myself with the help of three values I identify with: &lt;em&gt;people, quality and learning&lt;/em&gt;. People stands for teamwork, knowledge exchange, trust, and intensive transparent communication not only within the team, but also between teams; quality stands for simplicity, maintainability, product-thinking, and focus on purpose; and finally learning stands for continuous improvement, and exploring new things.&lt;/p&gt;

&lt;p&gt;Also, it might be nice to have a life motto that drives your personal characteristics on a very abstract level. Like this one by Albert Einstein: &lt;em&gt;“Everything should be made as simple as possible, but no simpler.”&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Personal integrity
&lt;/h2&gt;

&lt;p&gt;It’s easy to make things up. There’s mostly no way how the interviewers could possibly check if all that you say is true. Well, there is a way. We can call it an &lt;em&gt;integrity check&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;there’s no point in lying&lt;/strong&gt;. Don’t do that, I mean it. If you make a different person from yourself, that person would be expected to remain as such afterward. But one can’t lie forever. Soon or later, the truth comes up and the consequences are drastic. Losing the job and all the opportunities that you had to cancel due to this one and that could’ve matched your dreams much better. Broken trust, shame, and a black hole in your resume. Definitely not worth it. What’s more, telling the truth is much easier as you don’t have to memorize anything.&lt;/p&gt;

&lt;p&gt;Even if everything you say is true, you have to be ready to prove it. You have to watch the integrity of your words. For each and every statement there must be a concrete example from your experience.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You say, you’re creative? Tell me about your best ideas in your previous work. You say, you’re a leader? Tell me a story where you take over a control. Are you good at conflicts resolving? Tell me about a conflict in your team and how you managed to resolve it. You like learning new things? Tell me about a piece of technology you read about recently.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Questions about resolving conflicts and disagreements in the team or on the organization level are very popular among interviewers. They help them to test your integrity as a team player. A true &lt;strong&gt;team player welcomes diversity and disagreements&lt;/strong&gt;. Different opinions are opportunities for exchange, to learn something new, or to refine your own thoughts. Conflicts should never become purely emotional and must be resolved rationally through discourse with the whole team.&lt;/p&gt;

&lt;p&gt;As the ability and will to learn is one of the most important characteristics of a good developer, you may expect a lot of questions touching on this aspect:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How do you learn new things? What was the last lecture you attended and what did you learn? How would you explain a particular technology to a younger coworker?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another interesting sort of questions focuses on legacy software. While, as the old joke says, a new JavaScript framework is born every day, a successful software product could live over ten years. This means most stable &lt;strong&gt;companies deal with legacy systems of some kind&lt;/strong&gt;. A question about how you get on with this is definitely about to come.&lt;/p&gt;

&lt;p&gt;While it is good to be keen on shiny new stuff, it’s necessary not to forget about the purpose. You should not adopt a new technology just because of the technology itself, but because &lt;strong&gt;it solves a problem you actually have&lt;/strong&gt;. &lt;a href="https://blog.ttulka.com/you-are-not-gonna-need-microservices"&gt;Microservices&lt;/a&gt; or machine learning are cool, but not a silver bullet. You should aim to use good and &lt;strong&gt;appropriate technology that fits your context&lt;/strong&gt;, and communicate it so towards your interviewers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be honest with your weaknesses&lt;/strong&gt; as well. Don’t be afraid to admit that you don’t know everything. It’s perfectly fine to be aware of room for improvements and way better than being caught lying. Much more important is to show the will to learn and to get continuously better.&lt;/p&gt;

&lt;h2&gt;
  
  
  What, how and why
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;What&lt;/em&gt; and &lt;em&gt;how&lt;/em&gt; questions are familiar to every developer. There are plenty of interview questions over the Internet everyone can just print and learn at bedtime as a poem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How does merge-sort work? What transaction isolation levels do you know? How to check two strings for equality? What does &lt;a href="https://blog.ttulka.com/solid-principles-in-java-by-example"&gt;SOLID&lt;/a&gt; mean?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I bet you have already been asked all of those questions and you definitely know the correct answers by heart. As this is good, it’s not enough.&lt;/p&gt;

&lt;p&gt;Good companies will test your &lt;strong&gt;understanding and solving skills rather than encyclopedic knowledge&lt;/strong&gt; of definitions and algorithms. That is, you should also expect why questions, such as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Why is bubble sort ineffective and why is it not possible to fix it? In which cases could bubble-sort do make sense? Why is the Repeatable reads isolation level not sufficient to avoid phantom reads? Why do we not use the Serializable level everywhere? Why is the == operator not adequate for checking strings equality in Java? Why does the Dependency inversion principle lead to loosely decoupled code?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Knowing what and how is necessary, but a good engineer must know why, too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analyze, be creative
&lt;/h2&gt;

&lt;p&gt;A lot of questions are not meant to be answered directly or even correctly. Many of them have an &lt;strong&gt;open ending or no solution&lt;/strong&gt; at all. Interviewers are interested more in your thought process and solving skills than in a precise answer.&lt;/p&gt;

&lt;p&gt;There is no shame in taking some time to think. Nobody expects you to come up with a brilliant solution instantly. Take a deep breath, &lt;strong&gt;analyze the question, be creative, and share your thoughts&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What profession would you do if you were not a developer? What is your favorite phone app? What color would you be?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is no correct answer to the above questions. They all test your creativity and ability to think out of the box. Analyze the hypothetical situation first:&lt;/p&gt;

&lt;p&gt;Maybe you always wanted to be a musician and now you have an opportunity to sell your dream. But if you always wanted to be a programmer it’s unlikely that you have a list of alternative professions in mind. Why would you be someone else? Maybe because there is no such job whatsoever! So, what would you likely be in medieval years? Or in a parallel universe where physical laws are not constant and humans communicate via music. Show that &lt;strong&gt;you’re not boring&lt;/strong&gt;. Nobody wants to work with a tedious person.&lt;/p&gt;

&lt;p&gt;Some questions are put unclearly on purpose and &lt;strong&gt;interviewers expect you to ask additional questions&lt;/strong&gt; to make the problem clear. Take the interviewers into account as equal partners, try to work it out together, collaborate:&lt;/p&gt;

&lt;p&gt;What does “favorite” actually mean? Most beloved or mostly used? What would be the app I would keep if I could keep only one? You can talk about the newest game you had really fun playing, or be practical saying that your favorite app is the internet browser because you can do practically everything with it.&lt;/p&gt;

&lt;p&gt;There is no need to study psychology and emotional values hidden under different colors. Your interviewers did certainly not. If you want, say you would like to be blue as it is your favorite color remaining you of the sky. Or maybe yellow like the dress of your child on its first school day. You may also say that you’d like to be white because white is used only little and by only true artists, which means you would participate in as many great paintings as possible. Options are infinite.&lt;/p&gt;

&lt;h2&gt;
  
  
  You’re supposed to be happy too
&lt;/h2&gt;

&lt;p&gt;The task of an interviewer is to find out if you’re a good fit for the team and the organization she represents. Your task is to figure out &lt;strong&gt;if the team and the organization is a good fit for you&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This aspect of the interview is often underrated which can easily lead to disappointment, or even anxiety and burnout. &lt;strong&gt;You spend at work way too much time to be unhappy there&lt;/strong&gt;. If nothing else, please, remember this.&lt;/p&gt;

&lt;p&gt;Make sure that the job fits your expectations and there is consistency in what the interviewer offers. &lt;strong&gt;Ask questions&lt;/strong&gt;. A lot of them. &lt;strong&gt;Show your interest&lt;/strong&gt; in the organization, the team, and the product. Ask about company values and check if they match yours. Ask about challenges and how they solve them. Check answers for openness and consistency. I used to ask this very same question to every interviewer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What is the worst thing about working for the company?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some companies would promise the earth but the reality turns out to be very different. Do they have concrete examples to share with you? How does the organization support your ambitions and needs? Do they offer lectures and training? Will you have time to experiment and try new things out?&lt;/p&gt;

&lt;p&gt;Interviewers often over-use buzzwords they barely understand. Try to address this as well:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;What do you understand under Agile? What does DevOps mean to you? How do you do Scrum?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s always a good idea to ask about your potential role and organizational structure. An unclear and inconsistent understanding of the role responsibilities, high and opaque hierarchy, or cumbersome processes are signs of a dysfunctional organization.&lt;/p&gt;

&lt;p&gt;To show interest brings points for you as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to do your homework
&lt;/h2&gt;

&lt;p&gt;Last but not least is a technical task, usually given as homework with limited time in the first phases of the interview process.&lt;/p&gt;

&lt;p&gt;This kind of examination became very popular the last time and replaced typical multiple-choice tests almost completely.&lt;/p&gt;

&lt;p&gt;The point is not only to see your skills in action, it’s also a good check of your thinking in an unusual situation.&lt;/p&gt;

&lt;p&gt;What is so different about such homework? The conditions are pretty unnatural. It’s no real problem you have to solve. You’re missing context and typically a lot of other information. You might ask additional questions, but &lt;strong&gt;you’re also supposed to make assumptions&lt;/strong&gt; by yourself.&lt;/p&gt;

&lt;p&gt;There are several rules I’d recommend:&lt;/p&gt;

&lt;p&gt;First, if you’ve got some code to extend, study it. &lt;strong&gt;Never do any changes&lt;/strong&gt;, except you have found a bug or been told otherwise.&lt;/p&gt;

&lt;p&gt;Don’t over-engineer. This is time to shine, but it doesn’t mean you should use every piece of technology you know. Rather, make your solution extensible, so it’s open for further improvements. You don’t have to use each design pattern from the GoF catalog, it’s much better to use only one, but properly. &lt;strong&gt;Use best practices, but keep it simple&lt;/strong&gt;. Think in terms of MVP (Minimal Viable Product): What’s the minimal solution it could possibly work?&lt;/p&gt;

&lt;p&gt;Always &lt;strong&gt;write tests&lt;/strong&gt;. Not only tests increase your assurance that the code is doing well, but they will also make you more productive and help you get things done quickly. Every change, every requirement and condition must be found in the test suite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use static code analysis tools&lt;/strong&gt;. In this case, the tool that comes along with your IDE will be sufficient. This will be probably the first thing your reviewers will do. Don’t let them find any code smells. It’s easy money.&lt;/p&gt;

&lt;p&gt;Consider options, make notes. Your solution will be discussed later, so it’s important to know why you did as you did. There could be more than one right solution, but it’s important to explain why you have chosen this over that. Everything is about trade-offs, you should &lt;strong&gt;understand the benefits&lt;/strong&gt; of your solution and &lt;strong&gt;be aware of its drawbacks&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Let’s summarize the most important points to be aware of when preparing for an interview as a software developer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Software today is less about technology and more about people.&lt;/li&gt;
&lt;li&gt;Working code is no more enough, you have to communicate your work.&lt;/li&gt;
&lt;li&gt;Teamwork is a fundamental prerequisite for success.&lt;/li&gt;
&lt;li&gt;Ability and will to learn is crucial.&lt;/li&gt;
&lt;li&gt;Your personal profile is at least as important as your hard skills.&lt;/li&gt;
&lt;li&gt;Be honest, consistent and integrous. Don’t lie.&lt;/li&gt;
&lt;li&gt;A good engineer must know why and understand trade-offs.&lt;/li&gt;
&lt;li&gt;Analyze, be creative, and share your thoughts.&lt;/li&gt;
&lt;li&gt;Ask questions, show interest.&lt;/li&gt;
&lt;li&gt;When working on a task, use best practices, but keep it simple.&lt;/li&gt;
&lt;li&gt;The job must fit you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wish you good luck with the interview, getting your dream job, and having a lot of fun developing software!&lt;/p&gt;

</description>
      <category>career</category>
      <category>agile</category>
      <category>programming</category>
    </item>
    <item>
      <title>Spring Boot Custom Components</title>
      <dc:creator>Tomas Tulka</dc:creator>
      <pubDate>Thu, 10 Dec 2020 07:47:43 +0000</pubDate>
      <link>https://dev.to/ttulka/spring-boot-custom-components-300h</link>
      <guid>https://dev.to/ttulka/spring-boot-custom-components-300h</guid>
      <description>&lt;p&gt;Spring Boot philosophy is to develop applications by composing &lt;strong&gt;independent&lt;/strong&gt;, &lt;strong&gt;modular&lt;/strong&gt; and &lt;strong&gt;highly configurable&lt;/strong&gt; &lt;strong&gt;components&lt;/strong&gt;. Spring Boot provides smart and simple mechanisms and conventions for building such components, that could be easily applied in custom projects.&lt;/p&gt;

&lt;p&gt;In this post, we will explore those ideas, and show how to create &lt;strong&gt;domain-oriented custom components&lt;/strong&gt; the Spring Boot way.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Spring Boot
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://spring.io/projects/spring-boot"&gt;Spring Boot&lt;/a&gt; takes an &lt;strong&gt;opinionated view&lt;/strong&gt; of the &lt;a href="https://spring.io"&gt;Spring platform&lt;/a&gt; and third-party libraries. This means, all necessary dependencies are included and pre-configured, and there is none or very little additional configuration most Spring Boot applications need to add.&lt;/p&gt;

&lt;p&gt;Dependencies are consistent with each other and tested in integration.&lt;/p&gt;

&lt;p&gt;For web applications, embedded servers (Tomcat, Jetty, Undertow) are included. Even the traditional deployment into an application container is possible, Spring Boot is self-contained as default, everything is included in the final JAR and no additional infrastructure is needed (except JDK, obviously).&lt;/p&gt;

&lt;p&gt;In addition, Spring Boot comes with a lot of &lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html"&gt;production ready features&lt;/a&gt;, such as loggers, metrics, auditing, tracing, and monitoring.&lt;/p&gt;

&lt;p&gt;A simple application skeleton can be easily prototyped by &lt;a href="https://start.spring.io"&gt;Spring Initializr&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build Systems
&lt;/h2&gt;

&lt;p&gt;Spring Boot offers &lt;a href="https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/htmlsingle"&gt;Gradle&lt;/a&gt; and &lt;a href="https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/htmlsingle"&gt;Maven&lt;/a&gt; plugins for packaging and running Spring Boot applications. It is also possible to create and publish Docker images via the plugins.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gradle
&lt;/h3&gt;

&lt;p&gt;Spring Boot comes with &lt;code&gt;org.springframework.boot&lt;/code&gt; and &lt;code&gt;io.spring.dependency-management&lt;/code&gt; plugins:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;plugins&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework.boot'&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s1"&gt;'2.5.0'&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="s1"&gt;'io.spring.dependency-management'&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s1"&gt;'1.0.11.RELEASE'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, only the dependency management could be used in isolation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;plugins&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="s1"&gt;'io.spring.dependency-management'&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s1"&gt;'1.0.11.RELEASE'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;dependencyManagement&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;dependency&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework:spring-core:5.3.0'&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Maven
&lt;/h3&gt;

&lt;p&gt;Typically, your Maven POM file inherits from the &lt;code&gt;spring-boot-starter-parent&lt;/code&gt; project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;parent&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-parent&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.5.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/parent&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The parent POM brings the Spring Boot plugin, dependency management and other sensible defaults. All default settings can be overwritten in your POM.&lt;/p&gt;

&lt;p&gt;Alternatively, only dependency management can be used without the parent POM by using an import scoped dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-dependencies&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.5.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;type&amp;gt;&lt;/span&gt;pom&lt;span class="nt"&gt;&amp;lt;/type&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;import&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencyManagement&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Features Overview
&lt;/h2&gt;

&lt;p&gt;Spring Boot introduces several features new to the Spring ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Spring Boot Application
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;SpringApplication&lt;/code&gt; class provides a convenient way to bootstrap a Spring application that is started from a &lt;code&gt;main()&lt;/code&gt; method.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When the annotation &lt;code&gt;@SpringBootApplication&lt;/code&gt; is included on the main class, the application is bootstrapped, auto-configuration enabled and Spring components scan is set to the current package as root.&lt;/p&gt;

&lt;p&gt;It is recommended to locate the application class in a root package above other classes. So the package defines the search base for the components scan.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;org.example.myshop
+- MyShopApplication
+- catalog
+- delivery
+- order
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Starters
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Starters are a set of convenient dependency descriptors that you can include in your application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Starters bring all necessary dependencies and configurations into the application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework.boot:spring-boot-starter-web'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All starters have the core starter &lt;code&gt;spring-boot-starter&lt;/code&gt; a direct dependency, which includes auto-configuration support, logging and YAML.&lt;/p&gt;

&lt;p&gt;Starters are part of Spring Boot philosophy, a convenient way to include components into your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Auto-Configuration
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies that you have added.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When auto-configuration is enabled, components found on the classpath are automatically loaded and configured.&lt;/p&gt;

&lt;p&gt;Most standard Spring auto-configurations are highly &lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html"&gt;configurable via properties&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Application Properties
&lt;/h3&gt;

&lt;p&gt;Spring Boot automatically finds and loads &lt;code&gt;application[-profile].(properties|yaml|yml)&lt;/code&gt; from the classpath and other default &lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-files"&gt;locations&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Properties from the loaded files are added into Spring environment.&lt;/p&gt;

&lt;p&gt;Application properties form a configuration structure of a Spring Boot application with default values, which are meant to be overwritten in runtime from the environment or other &lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config"&gt;external sources&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Configuration properties are grouped into trees by the context, typically prefixed by the component name and feature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# application.yml&lt;/span&gt;

&lt;span class="na"&gt;spring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jdbc:postgresql://db:5432/test&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;admin&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;secret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Custom Components
&lt;/h2&gt;

&lt;p&gt;Features of Spring Boot can serve as a conventional template for custom components. To do things right, a deeper knowledge of Spring Boot concepts and mechanisms is needed.&lt;/p&gt;

&lt;p&gt;In the following section, we take a look at techniques for creating a modular application with independent domain-driven components. The components can be assembled into a single monolithic application or separate applications as microservices afterwards.&lt;/p&gt;

&lt;p&gt;For each component a Spring Boot starter with auto-configuration will be created.&lt;/p&gt;

&lt;p&gt;Assembling of components into an application is achieved simply by adding the component onto the classpath. Practically, by putting the component starter into the application dependencies.&lt;/p&gt;

&lt;p&gt;Spring Boot &lt;strong&gt;components are logically defined by auto-configurations&lt;/strong&gt;, starters are an additional mechanism to bring components into the application conveniently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Structure
&lt;/h3&gt;

&lt;p&gt;We will use Java packages for structuring code by the domain and Maven modules or Gradle sub-projects for technical cuts.&lt;/p&gt;

&lt;p&gt;Every component is a &lt;strong&gt;self-contained business capability service&lt;/strong&gt;, exposing multiple artifacts for API and implementation, formed by physical modules.&lt;/p&gt;

&lt;p&gt;A typical component source code structure looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;delivery/   -- comp. root
+- domain/  -- domain API
+- events/  -- events API
+- jdbc/    -- JDBC impl
+- rest/    -- Restful API
+- spring-boot-starter/ -- starter
+- pom.xml
+- build.gradle
\- settings.gradle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, auto-configurations can live in a separate module, which the starter includes as its dependency.&lt;/p&gt;

&lt;p&gt;In a single-application scenario a separate module for a Spring Boot application is created on the root level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;myshop/
+- application/
+- catalog/
+- delivery/
+- order/
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a microservices scenario, each component has its own application module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;myshop/
+- catalog/
|  +- application/
|  +- domain/
|  +- jdbc/
|  +- rest/
|  \- spring-boot-starter/
+- delivery/
|  +- application/
|  +- domain/
|  +- events/
|  +- jdbc/
|  +- rest/
|  \- spring-boot-starter/
+- order/
|  +- application/
|  +- domain/
|  +- events/
|  +- jdbc/
|  +- rest/
|  \- spring-boot-starter/
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For both scenarios, the separation of concerns is the structure driver. Every module has its own unique role in the final application.&lt;/p&gt;

&lt;p&gt;Starters bring Spring Boot auto-configuration, applications bring Spring Boot application main classes, but all other modules has no Spring Boot concerns or dependencies.&lt;/p&gt;

&lt;p&gt;For example, even if the REST module is built upon Spring Web, only the corresponding Spring framework dependency should be included:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="c1"&gt;// rest/build.gradle&lt;/span&gt;

&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework:spring-web'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Spring Boot Web starter will be included into the starter module only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="c1"&gt;// spring-boot-starter/build.gradle&lt;/span&gt;

&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework.boot:spring-boot-starter-web'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Java Packages
&lt;/h3&gt;

&lt;p&gt;As we build &lt;strong&gt;domain-oriented&lt;/strong&gt; components, packages should be domain-driven as well.&lt;/p&gt;

&lt;p&gt;All the modules of a component should share a root package. The modules could be further structured by the domain feature or a technical aspect. Same features should be included in an identical package.&lt;/p&gt;

&lt;p&gt;This strategy enables information hiding of implementation classes using Java package accessibility. Consider an example, where &lt;code&gt;○&lt;/code&gt; and &lt;code&gt;●&lt;/code&gt; mean &lt;em&gt;public&lt;/em&gt; and &lt;em&gt;package-protected&lt;/em&gt;, respectively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;delivery/
+- domain/
|  \- src/main/java/
|     \- org.example.myshop.delivery
|        \- ○DeliveryService.java
+- events/
|  \- src/main/java/
|     \- org.example.myshop.delivery
|        \- ○DeliveryDispatched.java
+- jdbc/
|  \- src/main/java/
|     \- org.example.myshop.delivery.jdbc
|        \- ●DeliveryServiceJdbc.java
+- rest/
|  \- src/main/java/
|     \- org.example.myshop.delivery.rest
|        \- ●DeliveryRestController.java
\- spring-boot-starter/
   \- src/main/java/
      \- org.example.myshop.delivery
         \- jdbc
            \- ●DeliveryJdbcConfig.java
         \- rest
            \- ●DeliveryRestConfig.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Classes &lt;code&gt;DeliveryServiceJdbc&lt;/code&gt; and &lt;code&gt;DeliveryRestController&lt;/code&gt; are in the same package as &lt;code&gt;DeliveryJdbcConfig&lt;/code&gt; and &lt;code&gt;DeliveryRestConfig&lt;/code&gt;, respectively. This makes them accessible to the configuration classes, which is the only one place they have to be accessible from, and hidden for the rest of the world.&lt;/p&gt;

&lt;p&gt;This kind of protection based on the basic language features is a great asset to the overall modularity, preventing the temptation to access implementation details of a foreign component, and violate its sovereignty so.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom Spring Boot Starter
&lt;/h3&gt;

&lt;p&gt;A typical Spring Boot starter contains auto-configuration code and declared dependencies, and it’s extensible via configuration properties in a dedicated namespace (prefix).&lt;/p&gt;

&lt;p&gt;By convention, the name of a starter starts with the component name followed by &lt;code&gt;-spring-boot-starter&lt;/code&gt; suffix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;org.example.myshop:delivery-spring-boot-starter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Auto-Configurations
&lt;/h4&gt;

&lt;p&gt;The entry point to a Spring Boot starter is the &lt;code&gt;META-INF/spring.factories&lt;/code&gt; file. Spring Boot checks for the presence of the file within your published JAR. The file should list component auto-configuration classes under the &lt;code&gt;EnableAutoConfiguration&lt;/code&gt; key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;org.springframework.boot.autoconfigure.EnableAutoConfiguration&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;  &lt;span class="s"&gt;org.example.myshop.delivery.DeliveryConfiguration&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Auto-configurations must be loaded that way only. Make sure that they are defined in a specific package space and that they are never the target of component scanning.&lt;/p&gt;

&lt;p&gt;Under the hood, auto-configuration is implemented with standard &lt;code&gt;@Configuration&lt;/code&gt; classes. Multiple configuration classes could be composed via the &lt;code&gt;@Import&lt;/code&gt; annotation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="nd"&gt;@Import&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JdbcDeliveryConfiguration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DeliveryConfiguration&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The auto-configuration creates and registers all necessary Spring beans for the particular component.&lt;/p&gt;

&lt;p&gt;A component starter is the only place configurations should exist. Other modules serve different purposes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Dependencies
&lt;/h4&gt;

&lt;p&gt;A Spring Boot starter contains all dependencies required by the component as whole.&lt;/p&gt;

&lt;p&gt;If, for example, a component has a module with Spring Web restful controllers, the starter should contain the corresponding Spring Boot Starter for web:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework.boot:spring-boot-starter-web'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The minimal dependency every Spring Boot starter must include is Spring Boot core starter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'org.springframework.boot:spring-boot-starter'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The component starters are then added as dependencies into the application module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'org.example.myshop:catalog-spring-boot-starter'&lt;/span&gt;
&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'org.example.myshop:delivery-spring-boot-starter'&lt;/span&gt;
&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'org.example.myshop:order-spring-boot-starter'&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuration Properties
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Spring Boot provides an alternative method of working with properties that lets strongly typed beans govern and validate the configuration of your application.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ConfigurationProperties&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;prefix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"myshop.delivery"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Setter&lt;/span&gt;
&lt;span class="nd"&gt;@Getter&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DeliveryProperties&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;cargoName&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;dateFormat&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configuration properties are meant to be a convenient way for initializing auto-configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="nd"&gt;@EnableConfigurationProperties&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
&lt;span class="nc"&gt;DeliveryProperties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DeliveryConfiguration&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@Bean&lt;/span&gt;
  &lt;span class="nc"&gt;DeliveryService&lt;/span&gt; &lt;span class="nf"&gt;deliveryService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="nc"&gt;DeliveryProperties&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt;
  &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DeliveryServiceImpl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCargoName&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
      &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDateFormat&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Spring Boot application defines the configuration structure with default values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# application.yml&lt;/span&gt;

&lt;span class="na"&gt;myshop&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;delivery&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cargo-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PPL&lt;/span&gt;
    &lt;span class="na"&gt;date-format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yyyy-mm-dd&lt;/span&gt;
  &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;prefix-id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OrderID&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Defaults can be overwritten in runtime, for example via environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;MYSHOP_DELIVERY_CARGO_NAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;DHL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Spring Boot is a great tool for developing &lt;strong&gt;modular monolithic&lt;/strong&gt; and &lt;strong&gt;microservices&lt;/strong&gt; applications.&lt;/p&gt;

&lt;p&gt;Auto-configurations provide a convenient mechanism for creating independent components in isolation.&lt;/p&gt;

&lt;p&gt;Spring Boot starters contain configurations and dependencies for components and define configuration structure via configuration properties with dedicated namespaces.&lt;/p&gt;

&lt;p&gt;A Spring Boot application assemblies the components and provides cross-cutting concerns in addition.&lt;/p&gt;

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

&lt;p&gt;An example code of a rich modular Spring Boot application can be found on &lt;a href="https://github.com/ttulka/ddd-example-ecommerce-microservices"&gt;my GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html"&gt;Spring Boot Reference Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/htmlsingle"&gt;Spring Boot Gradle Plugin Reference Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/htmlsingle"&gt;Spring Boot Maven Plugin Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html"&gt;Getting Started With Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html"&gt;Using Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html"&gt;Spring Boot How-to Guides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-developing-auto-configuration"&gt;Creating Your Own Auto-configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://start.spring.io"&gt;Spring Initializr&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Originally published on &lt;a href="https://blog.ttulka.com/spring-boot-custom-components"&gt;my blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>architecture</category>
      <category>java</category>
      <category>gradle</category>
    </item>
    <item>
      <title>You Aren’t Gonna Need Microservices</title>
      <dc:creator>Tomas Tulka</dc:creator>
      <pubDate>Wed, 09 Dec 2020 14:42:40 +0000</pubDate>
      <link>https://dev.to/ttulka/you-aren-t-gonna-need-microservices-5ed1</link>
      <guid>https://dev.to/ttulka/you-aren-t-gonna-need-microservices-5ed1</guid>
      <description>&lt;p&gt;&lt;em&gt;You Aren’t Gonna Need It&lt;/em&gt; (YAGNI) is one of the most important principles in software development.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Perfection is achieved not when there is nothing more to add, but when there is nothing more to take away.&lt;/em&gt; ~ Antoine de Saint-Exupery&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can see YAGNI as a special case of the &lt;em&gt;Keep It Simple Stupid&lt;/em&gt; (KISS) principle. YAGNI applies to a higher level as it tells us to cut off any unnecessary part while KISS advises making the rest as simple as possible.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Everything should be made as simple as possible, but no simpler.&lt;/em&gt; ~ Albert Einstein&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Violation of YAGNI is sometimes called &lt;em&gt;overengineering&lt;/em&gt;. A feature for every possible case, functions/methods with a lot of input parameters, multiple if-else branches, rich and detailed interfaces, all those could be a smell of overengineering. It’s the opposite of the famous UNIX-mantra: &lt;em&gt;Do one thing well&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To avoid this trap, always ask yourself a question: &lt;em&gt;“Is it really needed right now?”&lt;/em&gt; If the answer is &lt;em&gt;“Well, maybe”&lt;/em&gt; then probably not.&lt;/p&gt;

&lt;p&gt;Often, significant architectural decisions must be made to implement a feature. This is a problem because the earlier a decision is made the less information we have and the more likely a wrong decision is to be made. Therefore, it is a good practice to &lt;strong&gt;defer difficult decisions&lt;/strong&gt; until the last possible moment. Ignoring YAGNI leads to a violation of this practice.&lt;/p&gt;

&lt;p&gt;The main point of YAGNI is to &lt;strong&gt;pay the costs first when the feature is actually needed&lt;/strong&gt;, and not right now, just in case. YAGNI violations make development always expensive because the complexity behind each feature must be paid, even though the feature is not necessary (yet). In other words, accidental complexity rises. And complexity is expensive. Complexity is no fun.&lt;/p&gt;

&lt;p&gt;The same reasoning can be applied to microservices. But, don’t take me wrong: there are plenty of highly useful benefits that the microservices style can bring you and a lot of &lt;a href="https://12factor.net"&gt;great principles&lt;/a&gt; you can apply even to your monolith. However, the actual question remains the same: &lt;strong&gt;Do you really need them right now?&lt;/strong&gt; Do you really need to scale every service up to a thousand instances? Do you need a Kubernetes cluster, Kafka stream-processing platform, and Istio service mesh? Once again: maybe, but probably not right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fallacies of microservices
&lt;/h2&gt;

&lt;p&gt;Let's take a look at some typical fallacies I've observed so far among teams adopting microservices:&lt;/p&gt;

&lt;h3&gt;
  
  
  Microservices help you find boundaries
&lt;/h3&gt;

&lt;p&gt;This is probably the most dangerous misunderstanding of microservices and a very expensive mistake you can make. Remember: &lt;strong&gt;Microservices are about technology, boundaries are about business&lt;/strong&gt;. No technology can help you define your boundaries, only proper understanding of your business does.&lt;/p&gt;

&lt;p&gt;Microservices are just one option for how to physically separate components once boundaries are correctly defined. At the same time, they make the boundaries hard to change if they are found to be wrong, which often happens, especially in the early phases of product development.&lt;/p&gt;

&lt;p&gt;Try to define your service boundaries without any concerns of technology, build a team around them, implement a few product iterations. As you gain some confidence, you can turn them into microservices, if it will solve an actual problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Microservices make your system modular
&lt;/h3&gt;

&lt;p&gt;Microservices don't make your system modular out of the box. &lt;a href="https://blog.ttulka.com/good-and-bad-monolith"&gt;Modularity&lt;/a&gt; means &lt;em&gt;logical separation&lt;/em&gt; of business concepts. Microservices make this separation visible and difficult to cross over. While this is good, it does not come without drawbacks such as resistance to refactoring the structure of the modules.&lt;/p&gt;

&lt;p&gt;Anyway, there are much cheaper options such as using &lt;a href="https://github.com/ttulka/ddd-example-ecommerce"&gt;packages/namespaces&lt;/a&gt;, &lt;a href="https://github.com/ttulka/ddd-example-ecommerce/tree/modulith"&gt;modules/artifacts&lt;/a&gt;, etc. Those solutions provide a good level of physical separation along with ease to change.&lt;/p&gt;

&lt;h3&gt;
  
  
  Microservices make your system performant
&lt;/h3&gt;

&lt;p&gt;The possibility to scale every single service independently is one of the most emphasized advantages of microservices. While this is true, it comes with costs. Running every service as a separate process can't be done without supporting infrastructure. Things like service mesh, service discovery, or load balancer come to mind first.&lt;/p&gt;

&lt;p&gt;Cloud providers offer a working solution for you, but one has to bear in mind that remote calls are always more expensive than inter-process communication. Do you really need to scale all your services? Maybe one or two most loaded would be enough. Vertical scaling or scaling the whole system are options that usually just work and that are much cheaper than microservices.&lt;/p&gt;

&lt;p&gt;Another aspect is good modularity. When service boundaries are incorrectly defined and multiple remote calls must be done to process a request, the overall performance is likely to decrease when turning such a system into microservices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Microservices are cheaper to operate
&lt;/h3&gt;

&lt;p&gt;A typical example of this fallacy is Serverless computing. While there definitely are use-cases where the serverless approach can be beneficial and cheap to develop and operate, the amount of such use-cases is pretty limited. What's more, it's easy to get an impression that going serverless means just writing code and taking no care of how it's being operated. This is usually not true. For example, monitoring is still an important and hard problem no one else will solve for you.&lt;/p&gt;

&lt;p&gt;Serverless is an extreme case. An application running in the cloud in the same way as previously in your own server warehouse is likely to be much more expensive. This is very true, especially for so-called Lift&amp;amp;Shift solutions.&lt;/p&gt;

&lt;p&gt;One idea behind microservices is to move a piece of complexity from development into operations, where it is easier (and cheaper) to tackle. Yes, by doing microservices right, you might save some money on development but your operation costs will probably increase rapidly. This is not necessarily a bad thing as you do save some bucks at the end of the day, it's just something to be aware of.&lt;/p&gt;

&lt;h3&gt;
  
  
  Microservices are easier to develop
&lt;/h3&gt;

&lt;p&gt;Because a lot of complexity is moved to operations, great Ops skills are required inside the teams when taking the microservices-oriented approach. As the need for communication between Devs and Ops becomes crucible, there's no room for traditional separation by technical responsibilities. All members of the team must work together on a whole business feature, preferably colocated in the same room.&lt;/p&gt;

&lt;p&gt;Microservices are a practical approach to Agile development and require a real DevOps mindset, where the whole team is responsible for the product from the first sketches to running the production environment.&lt;/p&gt;

&lt;p&gt;If &lt;a href="https://blog.ttulka.com/devops-ad-absurdum"&gt;"DevOps"&lt;/a&gt; in your organization is done by that guy sitting in the last office on the second floor, then you shouldn't even think about microservices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Microservices are small
&lt;/h3&gt;

&lt;p&gt;Very popular topic and a big misconception. "Micro" does mean small or even smaller, right? Small is good, small is easy. Easy to understand, easy to develop, easy to operate… Well, no. &lt;strong&gt;"Micro" is not about size, it is about responsibility&lt;/strong&gt;. Anecdotes such as &lt;em&gt;two pizza teams&lt;/em&gt; or &lt;em&gt;code that fits on my screen&lt;/em&gt; might work in some organizations, however, they are no general rules.&lt;/p&gt;

&lt;p&gt;A service should be minimal in its responsibility and API. A service should implement just a single business capability. Nothing more, nothing less. The contract must be simple and clear. No unnecessary pollution, no implementation details.&lt;/p&gt;

&lt;p&gt;The implementation can be big, even huge at the beginning. The bounded context (from Domain-driven development) defines the biggest possible service. That is the boundary to start with. Other services will emerge by themselves as the domain becomes clearer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Always ask yourself: &lt;em&gt;"Do I really need this right now? Is this the simplest thing that can possibly work?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Don't go microservices just because they look cool and everybody is talking about them - they are no silver bullet. Doing so would be a violation of the YAGNI principle on the architecture level. That is, don't do it.&lt;/p&gt;

&lt;p&gt;All in all, you aren't gonna need it!&lt;/p&gt;




&lt;p&gt;Originally published on &lt;a href="https://blog.ttulka.com/you-are-not-gonna-need-microservices"&gt;my blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>architecture</category>
      <category>programming</category>
    </item>
    <item>
      <title>How Cohesion and Coupling Correlate</title>
      <dc:creator>Tomas Tulka</dc:creator>
      <pubDate>Wed, 09 Dec 2020 08:27:15 +0000</pubDate>
      <link>https://dev.to/ttulka/how-cohesion-and-coupling-correlate-4pbj</link>
      <guid>https://dev.to/ttulka/how-cohesion-and-coupling-correlate-4pbj</guid>
      <description>&lt;p&gt;As I was finishing my blog post about &lt;a href="https://blog.ttulka.com/monolithic-objects"&gt;defining service boundaries&lt;/a&gt;, I had a very strong feeling that there must be some abstract concept of what I was trying to explain using actual examples…&lt;/p&gt;

&lt;p&gt;Of course, there is! It is the concept of &lt;em&gt;cohesion&lt;/em&gt; and &lt;em&gt;coupling&lt;/em&gt; that I will discuss in this post.&lt;/p&gt;

&lt;p&gt;I will start with some definitions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Cohesion_(computer_science)"&gt;Cohesion&lt;/a&gt; is the degree to which the elements inside a module belong together.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Coupling_(computer_programming)"&gt;Coupling&lt;/a&gt; is the degree of interdependence between software modules.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;High cohesion and loose coupling are the most important principles in software engineering. They manifest themselves everywhere from code to team organization.&lt;/p&gt;

&lt;p&gt;Cohesion and coupling are tightly related. Why are they so important? Both help us reduce complexity, the true fun killer of software development.&lt;/p&gt;

&lt;p&gt;To a lot of people, sadly, the concepts sound too academic and are therefore often poorly understood.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is cohesion, anyway?
&lt;/h2&gt;

&lt;p&gt;Tough question. The definition is pretty broad and there are several interpretations out there. Not all of them are necessarily wrong, the more valid question is: which one is  most beneficial? I use the following definition as I believe it always leads to cohesive components with tight coupling inside and loose coupling outside, which is exactly what we want:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The degree of cohesion of a component by a particular key equals the number of elements cohesive by the key within the component divided by the sum of the total number of elements cohesive by the key in the whole system and the number of elements not cohesive by the key inside the component.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This long definition can be expressed as a simple formula:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AihMylfg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uggijqa4pf4tnkhb4nlk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AihMylfg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uggijqa4pf4tnkhb4nlk.png" alt="The cohesion formula"&gt;&lt;/a&gt;&lt;/p&gt;
The cohesion formula



&lt;p&gt;Where &lt;code&gt;c&lt;/code&gt; stands for the component, &lt;code&gt;k&lt;/code&gt; stands for the key, and &lt;code&gt;N&lt;/code&gt; stands for the number of elements. Obviously, the maximal cohesion of a component is equal to one. This is what we strive for.&lt;/p&gt;

&lt;p&gt;I want to emphasize that &lt;strong&gt;cohesion does not depend on the number of connections&lt;/strong&gt; between elements, which is what coupling is all about. Cohesion is more about &lt;em&gt;belonging together&lt;/em&gt;. However, cohesive components do tend to have a higher degree of coupling within the component, but that is just a symptom of high cohesion, not the cause.&lt;/p&gt;

&lt;p&gt;The definition above might look complicated, but it is actually quite easy. It can be illustrated by some examples. We measure the degree of cohesion by the &lt;em&gt;violet&lt;/em&gt; key for the components bordered with a dashed line in the following systems:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MtDuVaBd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fedfhmecdmgutnisohcl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MtDuVaBd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fedfhmecdmgutnisohcl.png" alt="Example measurements of cohesion"&gt;&lt;/a&gt;&lt;/p&gt;
Example measurements of cohesion



&lt;p&gt;Functionality (business) is always the right key to use. Violet and blue can stand for sales and accounting, a product and an invoice, or user registration and ordering.&lt;/p&gt;

&lt;p&gt;My definition may be a bit oversimplified as the boundaries are not always as solid and obvious. This is why business experts must be involved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Myth busted
&lt;/h2&gt;

&lt;p&gt;Cohesion and coupling are almost always discussed together as they tightly correlate. The relation is sometimes a source of confusion as well, although its understanding is very useful to gain the utmost for the software system under development.&lt;/p&gt;

&lt;p&gt;A typical myth, I often hear people believe in, puts cohesion and coupling in opposition. Practically, they say that &lt;em&gt;“the higher the cohesion the tighter the coupling”&lt;/em&gt;. I will show you how wrong this statement is.&lt;/p&gt;

&lt;p&gt;This is usually illustrated with an example: Consider the highest possible cohesion of the system where every module is represented by a single line of code (or a single function, an object with a single method, etc.). Such a degree of cohesion will inevitably increase the coupling between modules to the maximum.&lt;/p&gt;

&lt;p&gt;As the conclusion is true, there is a small problem in the prerequisite. To discover it, we must recall the definition of cohesion once again. It talks about &lt;em&gt;belonging together&lt;/em&gt;, the strength of &lt;em&gt;relationship&lt;/em&gt; of elements, and a &lt;em&gt;common purpose&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;What does it mean in practice? In fact, splitting elements that belong together actually makes cohesion lower. So, in the example above, the system really does not have the highest possible cohesion, just the opposite: breaking modules into the smallest possible elements will separate related concepts and will lead to pretty low cohesion.&lt;/p&gt;

&lt;p&gt;The moral here is: &lt;strong&gt;Cohesion is not something you can create automatically&lt;/strong&gt;. &lt;strong&gt;Cohesion is discovered in a particular context&lt;/strong&gt;. That is why it is so hard for cohesion to be reliably measured. We will discuss this in detail later, stay tuned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cohesion and coupling
&lt;/h2&gt;

&lt;p&gt;Let me show you some pictures. In each figure below, there are the very same elements with the very same dependencies. Those are further differently organized. Related domain concepts are represented with the same color:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t3Eq7mQZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/j8ts8qilytl5ne8irw44.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t3Eq7mQZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/j8ts8qilytl5ne8irw44.png" alt="Low cohesion, tight coupling"&gt;&lt;/a&gt;&lt;/p&gt;
Low cohesion, tight coupling



&lt;p&gt;Elements in the first picture have no explicit boundaries; they are an example of so-called coincidental cohesion. Such architecture is known as the Big Ball of Mud or the God Object (in OOP code).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sWlAazEa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9ojm41ku67q5ddt6gfkw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sWlAazEa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9ojm41ku67q5ddt6gfkw.png" alt="High cohesion, tight coupling"&gt;&lt;/a&gt;&lt;/p&gt;
High cohesion, tight coupling



&lt;p&gt;The second picture shows a system with three modules and a lot of dependencies between them. Although the modules are highly cohesive, they are cohesive by the &lt;em&gt;wrong key&lt;/em&gt;. This happens when code is organized by other than a domain relationship. A typical example is a logical organization of code in the &lt;a href="https://en.wikipedia.org/wiki/Multitier_architecture"&gt;Layered Architecture&lt;/a&gt;: just imagine modules such as controllers, repositories, services, etc. Have you seen these already somewhere? Hell yeah!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2LpcuLTb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z1itjkzs1wfg2qnadusf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2LpcuLTb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z1itjkzs1wfg2qnadusf.png" alt="High cohesion, loose coupling"&gt;&lt;/a&gt;&lt;/p&gt;
High cohesion, loose coupling



&lt;p&gt;The system in the third picture shows the ideal scenario: correctly organized modules leading to high cohesion and loose coupling. The right key for organization is functionality, in other words, a business domain. &lt;strong&gt;The domain defines abstractions with a stable purpose the cohesion is driven upon.&lt;/strong&gt; By the way, that is the main idea of the &lt;a href="https://en.wikipedia.org/wiki/Domain-driven_design"&gt;Domain-Driven Design&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Focus on cohesion, not coupling
&lt;/h3&gt;

&lt;p&gt;We have exhausted all variants except one: a system with low cohesion and loose coupling. Is it even possible to have such architecture? Unfortunately, it is, and it is actually pretty common.&lt;/p&gt;

&lt;p&gt;Systems with low cohesion and loose coupling are the result of incorrect understanding of the domain and applying purely technical approaches to decouple the modules in an arbitrary way. &lt;em&gt;Interfaces everywhere&lt;/em&gt; with no abstraction representing a domain purpose are typical for systems built in this way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.ttulka.com/too-many-interfaces"&gt;Misuse of interfaces&lt;/a&gt; will not actually reduce coupling anyway, it just moves it into the runtime.&lt;/p&gt;

&lt;p&gt;Striving for loose coupling at any cost can (and will) harm cohesion. As &lt;strong&gt;loose coupling is driven by high cohesion&lt;/strong&gt;, we should strive for high cohesion in the first place.&lt;/p&gt;

&lt;h3&gt;
  
  
  Level of abstraction
&lt;/h3&gt;

&lt;p&gt;Yes, high cohesion does not only make the system easy to understand and change, it also &lt;strong&gt;reduces the level of coupling&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;How is this even possible? Common sense says that the dependencies do not disappear simply by reorganizing elements. While this is true for the overall system dependencies, high cohesion does reduce dependencies on a higher level of abstraction.&lt;/p&gt;

&lt;p&gt;That is, although the absolute amount of dependencies remains the same, the coupling is tackled on different levels of abstraction.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The whole is greater than the sum of the parts.&lt;/em&gt; ~ Aristotle&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Indeed, we can ignore the interdependencies inside modules and thus get a simplified big picture with only three loosely coupled elements:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aAdLrHUd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/01x22ajwkxlpi4bma45l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aAdLrHUd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/01x22ajwkxlpi4bma45l.png" alt="Coupling on the higher level of abstraction is dramatically reduced"&gt;&lt;/a&gt;&lt;/p&gt;
Coupling on the higher level of abstraction is dramatically reduced



&lt;p&gt;Neat. As we see, &lt;strong&gt;high cohesion actually results in loose coupling&lt;/strong&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Talk to me in code!
&lt;/h2&gt;

&lt;p&gt;Pictures are nice, but as software developers, we trust only code, don’t we? Alright, I have some code for you. Consider a simple class for a Book Store (in JavaScript, whatever):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;BookStore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;sale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;receiptFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This class does literally everything. Its cohesion is pretty low and all clients, whatever their needs are, will be coupled to it. It is an example of a God Object. We can do better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Inventory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Sales&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;sale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;receiptFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Inventory&lt;/code&gt; class looks fine, but what about &lt;code&gt;Sales&lt;/code&gt;? Must sales and accounting really be so tightly related? Maybe it would be better to split the functionalities into more cohesive classes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Sales&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;sale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Accounting&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;receiptFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But what if our Book Store is just a small family business with one clerk handling sales together with accounting on one old cash desk? We have just hit the nail on the head: we cannot really know what the right cohesion key is unless we know the domain really well. True &lt;strong&gt;cohesion is defined by the clients&lt;/strong&gt;. High cohesion is achieved when there is no way to split the module any further while still satisfying the needs of the client. By the way, this is exactly what the &lt;a href="https://en.wikipedia.org/wiki/Single-responsibility_principle"&gt;Single Responsibility Principle&lt;/a&gt; teaches us.&lt;/p&gt;

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

&lt;p&gt;High cohesion and loose coupling are the main design drivers towards simple system architecture, which is easy to understand, change, and maintain. High cohesion and loose coupling help us reduce accidental complexity and create modules with well-defined boundaries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Coupling is about connections, cohesion is about belonging together.&lt;/li&gt;
&lt;li&gt;Cohesion cannot be created automatically; instead it is discovered in a context.&lt;/li&gt;
&lt;li&gt;Cohesion is defined by the clients.&lt;/li&gt;
&lt;li&gt;True cohesion is domain-driven.&lt;/li&gt;
&lt;li&gt;High cohesion results in loose coupling.&lt;/li&gt;
&lt;li&gt;High cohesion is to die for. It enables all others, loose coupling included.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Originally published on &lt;a href="https://blog.ttulka.com/how-cohesion-and-coupling-correlate"&gt;my blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>computerscience</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
