<?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: Milos Bugarinovic</title>
    <description>The latest articles on DEV Community by Milos Bugarinovic (@milosbugarinovic).</description>
    <link>https://dev.to/milosbugarinovic</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%2F1113134%2F89411e3e-0f73-4ab9-b16f-a285ea2fbfe8.jpeg</url>
      <title>DEV Community: Milos Bugarinovic</title>
      <link>https://dev.to/milosbugarinovic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/milosbugarinovic"/>
    <language>en</language>
    <item>
      <title>Balancing - Code, Choices and Sanity</title>
      <dc:creator>Milos Bugarinovic</dc:creator>
      <pubDate>Wed, 21 Feb 2024 21:40:05 +0000</pubDate>
      <link>https://dev.to/milosbugarinovic/balancing-code-choices-and-sanity-2lle</link>
      <guid>https://dev.to/milosbugarinovic/balancing-code-choices-and-sanity-2lle</guid>
      <description>&lt;p&gt;As time passes, I hear more and more often people say the phrase "balance is the solution", although I'm not entirely sure they understand the meaning of these words. I am starting to believe that balance is indeed the solution. And not just in one aspect of my life, but in nearly all of them. Just like the well-known phrase "work-life balance", where it's necessary to create a balance between professional and personal life, there is also a need to make the balance between physical and mental development, a balance between time for oneself and time for others...&lt;/p&gt;

&lt;p&gt;When I say something is in balance, it doesn't mean I've spent the same amount of energy on two or more things I'm balancing. On the contrary, balance means that at the moment of balancing, I'm satisfied with the balanced ratio between the sides, which doesn't have to be equal. It could be 60/40, 70/30, or even 90/10. I deliberately said "at the moment of balancing" because balancing is an ongoing process; otherwise, I would call it measuring.&lt;/p&gt;

&lt;p&gt;Just as the human body balances many systems daily, including blood pressure and heart rate per minute, I believe that balancing is a natural concept. On the other hand, society tends to construct ideologies and tries to find a single solution that can be applied in as many places as possible.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Ideologies are substitutes for true knowledge, and ideologues are always dangerous when they come to power, because a simple-minded I-know-it-all approach is no match for the complexity of existence."&lt;/em&gt;&lt;br&gt;
&lt;em&gt;— Jordan B. Peterson, 12 Rules for Life: An Antidote to Chaos&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm not immune to this behaviour either. I've been learning a lot about programming lately, so I'll find examples there most easily to explain what I mean.&lt;/p&gt;

&lt;p&gt;I remember when I entered the world of design patterns how I saw a pattern as a solution to all problems. This happened to me the most with the Strategy Pattern. The Strategy Pattern is very convenient and can be applied in many more places than necessary, thus increasing code complexity. Fortunately, I did this on a smaller project that wasn't in production, so I quickly and easily corrected this mistake. In this example, I learned from my mistakes, which is very useful. The only better scenario would have been if I had learned the same thing from someone else's mistake.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Don't fall into the Design Patterns trap&lt;/em&gt;&lt;br&gt;
&lt;em&gt;It would be best to be warned that you will probably fall into the Design Patterns trap when you first learn design patterns. This means you will try to squeeze a pattern in every solution, and your codebase will become over-engineering and unusable very soon."&lt;/em&gt;&lt;br&gt;
&lt;em&gt;— Interesting quote from Dr Milan Milanović in the article: &lt;a href="https://newsletter.techworld-with-milan.com/p/how-to-select-a-design-pattern" rel="noopener noreferrer"&gt;How to select a Design Pattern?&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvfes630x0j49iw6042y6.png" alt="How much you learn" width="800" height="800"&gt;&lt;/th&gt;
&lt;th&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2x6kwild8ma9d1f1aae4.jpg" alt="How much you learn updated" width="800" height="916"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Recently I saw this image but it looked like something is missing 🤔&lt;/td&gt;
&lt;td&gt;And I'm glad I found that someone shares my thoughts 😂, and I didn't need to go through making the same image again 🤣&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Lately, I've heard from various sources that the &lt;a href="https://en.wikipedia.org/wiki/SOLID" rel="noopener noreferrer"&gt;SOLID&lt;/a&gt; principle is no longer popular and good. When I'm programming, I use SOLID principles, but I don't apply them 100% of the time. As I mentioned at the beginning of this article, balance is important. I believe that one solution cannot solve every problem. If I try to solve all problems in the same way, I'm not actually solving them but rather transforming them into a new problem.&lt;/p&gt;

&lt;p&gt;I believe dissatisfaction with the SOLID principle stems from lack of understanding. If I take, for example, the &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself" rel="noopener noreferrer"&gt;DRY&lt;/a&gt; principle, which states, "&lt;strong&gt;D&lt;/strong&gt;on't &lt;strong&gt;R&lt;/strong&gt;epeat &lt;strong&gt;Y&lt;/strong&gt;ourself," and if I try to apply it in 100% of cases, I'm no longer solving business problems. Instead, I focus on a single principle, attempting to encapsulate every instance of code repetition, thereby creating more complex code that is not as readable and, therefore, not as flexible.&lt;/p&gt;

&lt;p&gt;In order to write flexible, sustainable, and functional code, it's not enough to just balance SOLID principles; I need to incorporate other principles like &lt;a href="https://en.wikipedia.org/wiki/KISS_principle" rel="noopener noreferrer"&gt;KISS&lt;/a&gt; (&lt;strong&gt;K&lt;/strong&gt;eep &lt;strong&gt;I&lt;/strong&gt;t &lt;strong&gt;S&lt;/strong&gt;imple, &lt;strong&gt;S&lt;/strong&gt;tupid). Of course, I don't want to overdo it with the KISS principle either, because I can't always solve a complex problem in a simple way.&lt;/p&gt;

&lt;p&gt;I firmly believe it's first necessary to identify the problem before I can proceed to solve it. Recognising the importance of balancing things and understanding that this balance can change as time goes on and I learn new things has helped me not only in my professional life but also in my personal life. It's also crucial to expand our knowledge and broaden our perspectives to balance things even better.&lt;/p&gt;

&lt;p&gt;It's true that the more I learn new things, the harder it becomes to balance because I have more things to balance. On the other hand, having more things to balance can lead to a better balance. Because if I don't have enough things to balance, it's possible to end up trying to balance things that are impossible to balance.&lt;/p&gt;

&lt;p&gt;If you're struggling with achieving balance, consider broadening your knowledge and expanding your horizons. Even though it may seem harder to balance more things, I would consider it a challenge; therefore, achieving balance will have greater value and satisfaction because more effort has been invested.&lt;/p&gt;

</description>
      <category>cleancode</category>
      <category>balance</category>
    </item>
    <item>
      <title>Code Craftsmanship in the Age of AI: Embracing Assistance, Not Dependency</title>
      <dc:creator>Milos Bugarinovic</dc:creator>
      <pubDate>Sun, 17 Dec 2023 08:44:15 +0000</pubDate>
      <link>https://dev.to/milosbugarinovic/code-craftsmanship-in-the-age-of-ai-embracing-assistance-not-dependency-3m0j</link>
      <guid>https://dev.to/milosbugarinovic/code-craftsmanship-in-the-age-of-ai-embracing-assistance-not-dependency-3m0j</guid>
      <description>&lt;p&gt;
  Table of content
  &lt;ul&gt;
&lt;li&gt;Disclaimer&lt;/li&gt;
&lt;li&gt;Intro&lt;/li&gt;
&lt;li&gt;Sloppy code&lt;/li&gt;
&lt;li&gt;
Conclusion
&lt;/li&gt;
&lt;/ul&gt;



&lt;/p&gt;
&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;Recently I’ve watched a video &lt;a href="https://www.youtube.com/watch?v=SN51H_q9wBg"&gt;JetBrains AI Launch Event&lt;/a&gt; that actually triggered me to write this article. Before I go on, I just want to state that I’m well aware that this video actually reminded me of some previous experiences and I want to point out that my intention here is not to criticise JetBrains. I’ve actually been using JetBrains tools for a long time and I will continue to use them. In general, I like the AI tools that are being developed today and I love how I can benefit from them in writing, coding and generating images for blog posts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rzJ0-8zx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pit4bb43pozlclgt3gdm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rzJ0-8zx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pit4bb43pozlclgt3gdm.jpg" alt="AI assistant at work" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;
AI assistant at work


&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;The video &lt;a href="https://www.youtube.com/watch?v=SN51H_q9wBg"&gt;JetBrains AI Launch Event&lt;/a&gt; explains how the JetBrains team integrated AI into their IDE to improve user experience and help developers with everyday work. And I encourage everyone to watch the whole video. The thing in the video that didn’t resonate with me was the marketing pitch. I’m talking about promoting AI tools to solve the issue of writing sloppy code which is hard to read and/or understand. I don’t think that this was their intention, but this is something that I’m afraid of and something that I went through with different technologies and practices.&lt;/p&gt;

&lt;p&gt;In the video, there is a talk about how AI can help us understand the code that someone wrote poorly. This is a great feature when facing such poorly written code. I fear that new generations of developers will not see clearly the problem of poorly written code because they will have a tool that will partially solve this problem, making it easier to understand and not forcing us to improve it. I fear that in similar scenarios, AI will become a crutch instead of a solution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/live/SN51H_q9wBg?si=ibKTE9HKUedDJ-Ob&amp;amp;t=894"&gt;JetBrains AI Launch Event - 14:54&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.youtube.com/live/SN51H_q9wBg?si=ibKTE9HKUedDJ-Ob&amp;amp;amp%3Bt=894" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--FuYEReaf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.ytimg.com/vi/SN51H_q9wBg/maxresdefault.jpg" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.youtube.com/live/SN51H_q9wBg?si=ibKTE9HKUedDJ-Ob&amp;amp;amp%3Bt=894" rel="noopener noreferrer" class="c-link"&gt;
          JetBrains AI Launch Event - YouTube
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          JetBrains AI Assistant is now publicly available! To find out more about AI Assistant, including our current plans, visit https://jetbrains.com/aiIn this spe...
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ob9E8PNH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.youtube.com/s/desktop/e4d15d2c/img/favicon.ico" width="16" height="16"&gt;
        youtube.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“… this part is really interesting for me, someone else wrote the code, maybe I wrote the code a long time ago and you walk up to like what is this code doing, you just spent a lot of time looking through the entire code base because, Jody this includes the context, right …”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I understand that marketing aims to make products and services desirable, presenting them as solutions that can address various needs. I believe we should constantly remind ourselves of things that can enhance our collective growth. It's my belief that we should strive to learn from the mistakes of others rather than repeating them. Here are some mistakes that I have experienced in my career.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sloppy code
&lt;/h2&gt;

&lt;p&gt;Whenever I write sloppy code, it always comes back to haunt me. I find myself struggling to read or comprehend it after some time. To assess the quality of my code, I adopt the strategy of temporarily switching off my analytical mind and swiftly reviewing the newly written code to understand its flow.&lt;/p&gt;

&lt;p&gt;At times, the code I produce is difficult to extend or test. Heavy refactoring seems to be the only remedy in such cases, but a more effective solution to this problem lies in proactive planning. This involves creating diagrams  (I’m using &lt;a href="https://plantuml.com/"&gt;PlantUML&lt;/a&gt;) because we all know that "months of programming can save us hours of planning."&lt;/p&gt;

&lt;p&gt;In the context of project development, it's widely acknowledged that comprehensive test coverage is essential. With unit tests, integration tests, and end-to-end tests at our disposal, ensuring the robustness of a project is a common practice. However, I encountered challenges such as issues, bugs, and a low-performing development team while working on a project with many integrated tests. This realisation became apparent to me after watching &lt;a href="https://vimeo.com/80533536"&gt;J.B. Rainsberger's presentation titled "Integrated Tests Are A Scam"&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://player.vimeo.com/video/80533536" width="710" height="399"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;When I’m thinking about sloppy code, a paragraph written by &lt;a href="https://www.amazon.com/Clean-Agile-Basics-Robert-Martin/dp/0135781868"&gt;Robert C. Martin (“Uncle Bob”) in the book Clean Agile: Back to Basics&lt;/a&gt; comes to mind:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Chapter 1: Introduction to Agile&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Agile Overview&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Decreasing Quality&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Everyone knows that you can go much faster by producing crap. So, stop writing all those tests, stop doing all those code reviews, stop all that refactoring nonsense, and just code you devils, just code. Code 80 hours per week if necessary, but just code!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I’m sure you know that I’m going to tell you this is futile. Producing crap does not make you go faster, it makes you go slower. This is the lesson you learn after you’ve been a programmer for 20 or 30 years. There is no such thing as quick and dirty. Anything dirty is slow.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The only way to go fast, is to go well.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;So we’re going to take that quality knob and turn it up to 11. If we want to shorten our schedule, the only option is to increase quality.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hdkrhmQ---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a8bz67xsdvcsk6jj9etb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hdkrhmQ---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a8bz67xsdvcsk6jj9etb.jpg" alt="Working with sloppy code" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;
Working with sloppy code



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

&lt;p&gt;I hope this article will shed light on the potential problems that may arise when relying on AI tools to solve our problems and the importance of education and developing skills. While AI undoubtedly offers valuable assistance in deciphering complex code, developers must strike a balance, avoiding dependency on these tools at the expense of understanding and addressing the root causes of sloppy code. The key takeaway here is that in the pursuit of efficiency, developers must view AI as a supportive tool rather than a substitute for the craftsmanship required to produce clean, maintainable code.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>developer</category>
      <category>cleancode</category>
      <category>testing</category>
    </item>
    <item>
      <title>Venturing into the Architectural Wilderness</title>
      <dc:creator>Milos Bugarinovic</dc:creator>
      <pubDate>Tue, 04 Jul 2023 20:40:04 +0000</pubDate>
      <link>https://dev.to/milosbugarinovic/venturing-into-the-architectural-wilderness-5h65</link>
      <guid>https://dev.to/milosbugarinovic/venturing-into-the-architectural-wilderness-5h65</guid>
      <description>&lt;h2&gt;
  
  
  A Guide to Navigating Development, Avoiding Bugs, and Conquering Spaghetti Monsters
&lt;/h2&gt;

&lt;p&gt;
  Table of content
  &lt;ul&gt;
&lt;li&gt;Overview&lt;/li&gt;
&lt;li&gt;
App Boot Layer (ABL)

&lt;ul&gt;
&lt;li&gt;
Example:

&lt;ul&gt;
&lt;li&gt;Starting up&lt;/li&gt;
&lt;li&gt;Shutting down&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Controller Layer (CL)&lt;/li&gt;
&lt;li&gt;
Business Layer (BL)

&lt;ul&gt;
&lt;li&gt;
Use Case Layer (UCL)

&lt;ul&gt;
&lt;li&gt;Example:&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Service Layer (SL)&lt;/li&gt;
&lt;li&gt;
Component Layer (CompL)

&lt;ul&gt;
&lt;li&gt;Example:&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Repository Layer (RL)&lt;/li&gt;
&lt;li&gt;
Model Layer (ML)

&lt;ul&gt;
&lt;li&gt;Entity&lt;/li&gt;
&lt;li&gt;Transport Object&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Data Access Layer (DAL)&lt;/li&gt;
&lt;li&gt;Library Layer (LL)&lt;/li&gt;
&lt;li&gt;Util Layer (UL)&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;
Folder structure example for node.js application
&lt;/li&gt;
&lt;/ul&gt;




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



&lt;p&gt;In this article, I’ll guide you through the ever changing world of development that may cause anxiety. I’m going to share my experience in navigating through different requirements, choosing the right architecture, and adapting it as the project grows. My goal as a developer is to create maintainable, readable, and flexible code, which I hope to share with you in this article.&lt;/p&gt;

&lt;p&gt;
  Disclaimer
  &lt;blockquote&gt;
&lt;p&gt;I have been working with JavaScript/TypeScript since 2014, and my coding style has been influenced by the free and expressive nature of these languages. The principles and concepts I discuss in this article are applicable not only to JavaScript and TypeScript, but can be adapted to other programming languages as well.&lt;br&gt;
Also, I think It's important to note that there are numerous approaches to solving problems and implementing software solutions. When faced with opposing opinions or different ways of doing something, finding a balance between them can lead to a more optimal solution. I believe that the answer often lies in the middle ground, as I will show in this article.&lt;br&gt;
I know that each developer may have their own unique way of accomplishing tasks, and there is no one-size-fits-all solution. Your experiences and perspectives are valuable, and I welcome your input and feedback. If you have alternative approaches, suggestions, or additional insights, please feel free to leave a comment or reach out. Collaboration and sharing of ideas contribute to the growth and improvement of the development community as a whole.&lt;br&gt;
The purpose of this article is to offer insights, theoretical perspectives, and principles that can enhance your software development journey. I encourage you to adapt and modify these principles to suit your specific needs and context. Software development is a creative process, and finding your own path within the spectrum of opinions can lead to remarkable outcomes.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;

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



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



&lt;p&gt;In this article, I’ll walk you through layered architecture, one layer at a time. This won't be your typical, by-the-book layered architecture; instead, it incorporates additional layers that aim to find a middle ground by combining the best aspects of existing architectures. We'll start at the top, adopting the layered or onion approach, and gradually transition to a hybrid component architecture as the complexity of the business logic intensifies. Rest assured, we'll maintain the integrity of the Business Layer (BL) throughout this transformation.&lt;br&gt;
Before diving into the specific layers, it's important to note that while this approach primarily focuses on backend applications, it can also be used for frontend development. However, it is important to acknowledge that this approach lacks sections/layers for UI components, screens, and screen routers. With that in mind, let's explore each layer and its theoretical foundations to gain a deeper understanding of their roles and significance.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;App Boot Layer (ABL):&lt;/strong&gt; This layer is important for setting the stage for the application. In my explanation, I'll delve into the theoretical foundations and discuss why proper initial start up and shut down processes are essential. Understanding the significance of this layer will help you appreciate the smooth start and graceful exit of the application you are developing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Controller Layer (CL):&lt;/strong&gt; Further on, I'll discuss the role and significance of the entry point in an application. I'll explore the theoretical aspects of how actions and requests are received and processed in this layer. By understanding the central hub's purpose and the separation of business logic from the transport framework, we'll gain insights into designing efficient and maintainable software.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Business Layer (BL):&lt;/strong&gt; This is the heart of the application containing the business logic. In this section, I'll explore the theoretical concepts of the Use Case Layer (UCL) and Service Layer (SL). I'll discuss the importance of orchestrating functions and implementing reusable, value-driven code that drives the core functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data Access Layer (DAL):&lt;/strong&gt; Descending deeper into the architecture, I'll explore the theoretical aspects of interacting with various data sources. I'll explain the significance of the DAL as a bridge between our business logic and the data. Understanding the theoretical foundations of seamless interaction and manipulation will give you the knowledge to design robust data access mechanisms.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Library Layer (LL):&lt;/strong&gt; Here I’ll talk about the theoretical benefits of the code snippets and utilities. I'll discuss the art of creating modular, reusable code without over-engineering or compromising simplicity. Understanding the theoretical principles of this layer gives you the opportunity to leverage existing resources and enhance your efficiency as a developer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Util Layer (UL):&lt;/strong&gt; Finally, I'll explore the theoretical foundations of the utility functions. I'll discuss the significance of tools like logging, environment management, and error handling. Understanding the theoretical aspects of these functions empowers you to make informed decisions and adopt best practices throughout the development process.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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


&lt;h2&gt;
  
  
  App Boot Layer (ABL)
&lt;/h2&gt;

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



&lt;p&gt;In the vast jungle of application development, there are moments when I need to prepare the application before it can emerge into the world. Similarly, when the time comes to shut down the application, I often find myself needing to perform necessary cleanup or conceal my creation from the outside world until all ongoing processes are completed.&lt;br&gt;
Within the ABL, I have the power to execute processes asynchronously, whether in sequential order or in parallel. This layer allows me to define various methods of initiating the application. For instance, in the realm of backend development with Node.js, I can make decisions such as excluding the RestAPI interface during unit testing or bypassing database connections when they are not necessary.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example:
&lt;/h3&gt;

&lt;p&gt;Let's consider an example scenario:&lt;/p&gt;
&lt;h4&gt;
  
  
  Starting up
&lt;/h4&gt;

&lt;p&gt;When I launch an application, my first priority is to establish a seamless connection to the database and to execute any necessary database migrations. This ensures that the data infrastructure is ready for action. While the connection to the database is being established, I take the opportunity to register an internal EventBus, powered by the reliable RxJS library. I have full confidence in registering it because internal EventBus is triggered by the code that is located in business logic.&lt;br&gt;
Moving on to the next phase of initialization, I focus on activating interfaces that allow the application to interact with the outside world. This entails enabling RestAPI, MessageQueue, and CronJob functionalities simultaneously. By doing so, I unlock the full potential of the application, enabling it to effectively communicate and serve various external systems and users.&lt;/p&gt;
&lt;h4&gt;
  
  
  Shutting down
&lt;/h4&gt;

&lt;p&gt;When the time comes to shut down my application, such as during a version release, it is never advisable to forcefully terminate it. Doing so would risk a potential loss of valuable information and terminating unfinished processes.&lt;br&gt;
While some environments, like AWS, Azure, or Google may provide mechanisms for redirecting traffic to new instances, they are not foolproof solutions, these mechanisms may not cover all incoming signals. For instance, message queues or cron jobs may still be active in the background, while only RestAPI calls are redirected.&lt;br&gt;
The safest approach to shutting down a Node.js application is to deactivate all listeners and let ongoing processes finish gracefully.&lt;br&gt;
Lastly, it is wise to log any errors that occur during the application shut down process. This practice helps to identify and address potential issues, even in the final moments of the application's lifecycle.&lt;/p&gt;
&lt;h2&gt;
  
  
  Controller Layer (CL)
&lt;/h2&gt;

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



&lt;p&gt;In the CL, I aim to consolidate all entry points of the application. Meaning that any action invoked within the application must first pass through the CL. By establishing the centralised control, it becomes much easier to track the origin of any process. Furthermore, this established control serves as an effective boundary, preventing any transport framework I use from invading my business logic.&lt;br&gt;
My application has various entry points, including RestAPI, MessageQueue, CronJob, and EventBus. In this layer, I establish a router that directs messages or invocations to their respective functionalities. In my opinion, it is essential to create readable routes and consolidate them in one location to avoid overlooking any of them. Each route is associated with a handler, which should exclusively execute a single function from the BL. This separation is crucial because multiple transports may trigger the same handler, such as both RestAPI and MessageQueue invoking the identical functionality. By keeping the business logic out of the controller, I avoid code duplication and minimize code smell.&lt;br&gt;
Controller handlers play a crucial role in handling data received from end users. This is where I perform validation and, if necessary, transform the data. It is essential to conduct these validation and transformation steps within the handlers themselves. The reason is that each controller is tailored to its specific transport system, be it RestAPI, MessageQueue, or any other. Consequently, the data structure associated with each transport system may differ, needing specific validation and transformation procedures within the respective handlers. By encapsulating these processes within the handlers, we ensure that the data is appropriately validated and transformed based on the requirements of each individual controller and its associated transport system.&lt;/p&gt;
&lt;h2&gt;
  
  
  Business Layer (BL)
&lt;/h2&gt;

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



&lt;p&gt;The BL is responsible for handling the core business logic. It is important to keep this layer independent of any frameworks to ensure that the business logic stays unaffected by the specific implementation details of any frameworks. To effectively manage the complexity of the BL layer, I have adopted an approach inspired by the Onion Architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Case Layer (UCL):&lt;/strong&gt; focuses on defining and orchestrating the specific use cases or business scenarios of the application. It represents the high-level actions or operations that the system needs to perform to fulfil the business requirements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Service Layer (SL):&lt;/strong&gt; encapsulates less complex, technical solutions that are reusable across the BL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Component Layer (CompL):&lt;/strong&gt; encapsulates complex reusable logic, combining the rules and principles of both the UCL and the SL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Repository Layer (RL):&lt;/strong&gt; responsible for abstracting the data persistence and retrieval operations from the underlying data storage. It provides an interface to interact with the data storage while shielding the BL from the specific details of the data storage mechanism.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Model Layer (ML):&lt;/strong&gt; it represents the domain-specific data structures used within the BL. It encapsulates the core concepts of the application domain, ensuring a cohesive representation of the business objects and their relationships.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Use Case Layer (UCL)
&lt;/h3&gt;

&lt;p&gt;Every time I dive deep into the development process, I’m reminded of the importance of having good and descriptive names for functions. I'm trying to enforce this rule consistently, although I am aware that it may not be possible to follow it 100% of the time. With this understanding, I have introduced a dedicated layer - Use Case Layer (UCL) - to accommodate situations where the naming convention can be relaxed. The UCL serves as a repository for functionalities derived from the product owner, encapsulating the dynamic business logic that can evolve based on market demands.&lt;br&gt;
Through the establishment of the UCL, I am able to strike a balance between the need for clear and descriptive function names and the reality of complex functions that may require more concise names. This specialised layer enables me to effectively accommodate both scenarios. Furthermore, I embrace the inclusion of comments within the UCL, as they enhance the documentation and understanding of the code within this layer.&lt;br&gt;
The main distinction I've observed between the SL and the UCL is that the UCL undergoes changes driven by dynamic market demands, while the SL represents the technical solutions for the current market requirements, and ideally, when the market demands shift, ideally,  new functionalities are introduced in SL to meet these evolving needs. In the UCL, I ensure that I don't include code that should be in the SL; instead, I focus on calling and orchestrating functions from the SL. My goal is to make the functionality of a UCL function evident by simply reading the names of the SL functions it calls, creating a seamless narrative flow similar to reading a book. Although the names of UCL functions can be short and unclear, I try to accompany them with thorough documentation and requirements to ensure that it’s clear how the intended feature functions. &lt;/p&gt;

&lt;h4 id="example-1"&gt;Example:&lt;/h4&gt;

&lt;p&gt;In my backend system, I have an authorization endpoint that handles various tasks. Its responsibility is to verify the existence of a user with the provided password, check if the user is active, and validate the 2FA code entered during the login process. While naming this function based on all the tasks it performs would result in a lengthy name, I've decided to simply call it &lt;code&gt;login&lt;/code&gt; for simplicity and ease of understanding. I'll place this function in the &lt;code&gt;authorization-use-case.ts&lt;/code&gt; file, which is located in UCL. It's important to note that I won't provide the actual implementation code here which belongs in the SL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/business/use-case/authorization-use-case.ts&lt;/span&gt;
&lt;span class="nx"&gt;expose&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authorizationUseCase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;userName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;code2fa&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;code2fa&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findUserBy&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;userName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Username or password incorrect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isUserActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verifyActiveUser&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isUserActive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User is not active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isCodeValid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;code2faService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;code2fa&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isCodeValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Two factor code invalid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;authorizationService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateAuthToken&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A great example of the business logic that belongs in the SL is the &lt;code&gt;verifyActiveUser&lt;/code&gt; function. This logic is not subject to frequent changes based on market demands. The status of a user's activity is stored within the user business model, making it inherently tied to the business model itself. Since every part of the application depends on the business model, it becomes apparent that market demands can indirectly influence changes in the SL. However, I firmly believe that if I define my business model effectively, market demands will have minimal impact on the SL.&lt;br&gt;
This underscores the importance of dedicating sufficient effort and time to defining a robust and reliable business model. By investing in the initial stages of creating a solid foundation, I can minimise the need for frequent changes in the SL, ensuring stability and consistency throughout the application.&lt;/p&gt;
&lt;h3&gt;
  
  
  Service Layer (SL)
&lt;/h3&gt;

&lt;p&gt;In the SL, I focus on writing reusable code with business value. My goal is to ensure that the logic implemented here is simple and serves a single purpose - keeping complexity low. It is crucial to follow a naming convention here, function name needs to accurately describe the function's purpose. If a function's name becomes too long, it is an indication that the function may be too complex. Although it may not always be possible to strictly stick to this rule when following a horizontal layer architecture, there might come a time when we need to transition to a component based architecture of writing.&lt;/p&gt;
&lt;h3&gt;
  
  
  Component Layer (CompL)
&lt;/h3&gt;

&lt;p&gt;In the UCL and SL, I follow some straightforward rules and make a conscious effort not to mix them. However, I understand that it can be challenging to write code that fully follows these rules. That's where the CompL comes into play as a helpful solution. In this layer, I combine the rules from the UCL and SL, employing UCL rules in the public parts of the code and SL rules in the private parts of the code. The main idea behind this approach is to encapsulate complex and reusable logic, ensuring its modularity and integrity.&lt;/p&gt;

&lt;h4 id="example-2"&gt;Example:&lt;/h4&gt;

&lt;p&gt;In this scenario, I have an &lt;code&gt;invoice&lt;/code&gt; entity with a &lt;code&gt;status&lt;/code&gt; property. The available statuses for this entity are: &lt;code&gt;DRAFT&lt;/code&gt;, &lt;code&gt;CREATED&lt;/code&gt;, &lt;code&gt;SUBMITTED&lt;/code&gt;, and &lt;code&gt;CANCELLED&lt;/code&gt;. Given the strict rules governing status changes, which are already complex, I find it beneficial to encapsulate the status rules within a dedicated component. By doing so, I can expose a validation function that checks if the current invoice can be updated to a desired new status.&lt;br&gt;
To achieve this, I create an &lt;code&gt;invoiceStatus&lt;/code&gt; component that exposes a function named &lt;code&gt;canChangeTo({invoice: Invoice, status: string})&lt;/code&gt;. The purpose of this function is to hide the intricate logic that determines whether a particular status change is allowed. It's important to note that the logic behind &lt;code&gt;canChangeTo&lt;/code&gt; function is not intended to be reusable in other layers; it should only be accessed through the exposed entry points of the component. &lt;br&gt;
Ideally, this component would not use the logic from other layers, including layers below and next to it (RL, SL), because the result may generate one big spaghetti monster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;src
...
├── business
│   ├── component
│   │   └──invoice-status
│   │      ├──rule
│   │      │   ├──draft.ts
│   │      │   ├──created.ts
│   │      │   ├──submitted.ts
│   │      │   └──cancelled.ts
│   │      ├──index.ts   &lt;span class="c"&gt;# here we hae all exposed endpoints&lt;/span&gt;
│   │      └──service.ts &lt;span class="c"&gt;# has a switch by rule to select rule&lt;/span&gt;
│   ├── model
│   ├── repo
│   ├── service
│   └── use-case
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Repository Layer (RL)
&lt;/h3&gt;

&lt;p&gt;The RL is where I take responsibility for abstracting the data persistence and retrieval operations from the underlying data storage. It's my job to provide an interface that allows me to interact with the data storage while shielding the BL from the specific intricacies of the data storage mechanism.&lt;br&gt;
Within the RL, I focus on implementing the business logic responsible for persisting and retrieving data. Regarding RL for storing data, the underlying method used is not as crucial as the ability to store it securely and retrieve it whenever needed. I can have a range of options available, including databases, files, memory, FTP, third-party systems, RestAPIs, GraphQL, and more.&lt;br&gt;
It's also important for me to establish boundaries and keep frameworks at bay when it comes to our business logic. To achieve this, I have DAL that offers this flexibility. This allows me to switch the data type of any entity simply by changing the DAL implementation.&lt;br&gt;
During my work in this layer, I recognized the need to introduce a custom light Object-Relational Mapping (ORM) framework. This framework is specifically designed for my business logic and doesn't rely on the third-party ORMs used in the applications. While it may not be a perfect solution, it serves well for handling simple queries. For more complex queries, I turn to the DAL to find an appropriate solution.&lt;/p&gt;
&lt;h3&gt;
  
  
  Model Layer (ML)
&lt;/h3&gt;

&lt;p&gt;As a developer, I understand that ML plays a key role in the application. It serves as the foundation that defines and shapes the entire application. Any changes made to the ML can potentially impact every other layer, as they all depend on it.&lt;br&gt;
Initially, when the application is not yet complex, I may not need to differentiate between the Model, Entity, and Transport Object. However, it's important to be aware of these tools and their potential usage at any given moment. I must be cautious to ensure that I don't inadvertently compromise my model without evaluating whether the solution lies in modifying the Entity or Transport Object.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Entity:&lt;/strong&gt; represents the object definition for the DAL. It serves as a means to represent the data stored in the application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Transport Object:&lt;/strong&gt; represents the object definition for the CL. It comes into play when I need to redefine what is sent to the end user without modifying the underlying Model.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These distinctions give the flexibility to tailor the data representation according to specific requirements without directly altering the model.&lt;/p&gt;
&lt;h4&gt;
  
  
  Entity
&lt;/h4&gt;

&lt;p&gt;In the overview diagram, I have defined entities in the DAL. When it comes to storing models in a database, I consider which properties are necessary to store and which ones can be calculated or derived. For instance, if I have a model with properties like &lt;code&gt;firstName&lt;/code&gt;, &lt;code&gt;lastName&lt;/code&gt;, and &lt;code&gt;fullName&lt;/code&gt;, I don't necessarily need to store the &lt;code&gt;fullName&lt;/code&gt; in the database. I can always calculate it by concatenating the &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt; values. This approach allows me to optimise the storage and retrieval process while maintaining the necessary data integrity.&lt;/p&gt;
&lt;h4&gt;
  
  
  Transport Object
&lt;/h4&gt;

&lt;p&gt;As for the Transport Object, it serves as an object definition that responds to requests made through the CL. It provides a way for me to format data differently or conceal certain information before sending it to the end client. The Transport Object allows me to tailor the data presentation according to specific requirements or privacy considerations. By doing so, I ensure that the client receives the most relevant and appropriate information while maintaining data security and confidentiality.&lt;/p&gt;
&lt;h2&gt;
  
  
  Data Access Layer (DAL)
&lt;/h2&gt;

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



&lt;p&gt;This layer is dedicated to managing the storage and retrieval of data. It provides flexibility to store data in various ways, including databases, files, memory, FTP, third-party systems, RestAPIs, GraphQL, and more.&lt;br&gt;
It's crucial to understand that this layer serves as a wrapper for the frameworks I use to manipulate data. The framework's implementation should remain contained within this layer and should not spill into the RL where the business logic resides. By maintaining this separation, I ensure that the core business logic remains unaffected by the specifics of the data manipulation framework.&lt;br&gt;
Furthermore, I mentioned that I use a custom Object-Relational Mapping (ORM) implementation in the RL. As a result, I need to map my ORM implementation with any third-party ORM that I utilise in the DAL. This mapping ensures compatibility and seamless integration between the custom ORM and the external ORM, allowing for efficient data access and manipulation throughout the application.&lt;/p&gt;
&lt;h2&gt;
  
  
  Library Layer (LL)
&lt;/h2&gt;

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



&lt;p&gt;In this layer, my focus is on encapsulating code that has the potential to be used in other applications, making it easily extractable. I approach it as if I'm developing a third-party library, ensuring that the code is modular and reusable. By doing so, I can extract and reuse modules from this layer in other applications without unnecessary complications.&lt;br&gt;
It's important to strike a balance between convenience and over-engineering. While I aim to make the code convenient to write and extract, I must avoid creating a completely separate external library for every reusable piece of code. I also want to avoid embedding code directly into my business logic, because embedded code is hard to reuse.&lt;br&gt;
Finding the middle ground is key. I want to identify and encapsulate code that has broad applicability and can benefit multiple projects. By doing this, I can maximise code reuse, simplify maintenance, and streamline development across different applications.&lt;/p&gt;
&lt;h2&gt;
  
  
  Util Layer (UL)
&lt;/h2&gt;

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



&lt;p&gt;In this layer, I focus on storing functionalities that don't contain any specific business logic. These functions are designed to be used across all layers of the application without any restrictions. Some common examples of functionalities that belong to the UL include a logger, environment variables management, and basic error messages.&lt;br&gt;
The UL serves as a central repository for these utility functions, providing convenient access to commonly used features that are not tightly coupled to any particular business domain. By separating these functionalities into a dedicated layer, we promote code reusability, maintainability, and modularity throughout the application.&lt;br&gt;
For instance, a logger utility allows us to easily log messages and events across various components and layers of the application, providing valuable insights during development, debugging, and monitoring. Similarly, an environment variables utility helps manage configuration settings specific to different deployment environments, enabling greater flexibility and scalability. Additionally, a basic error handling utility assists in capturing, handling, and reporting errors consistently throughout the application.&lt;br&gt;
By consolidating these non-business-specific functionalities in the UL, I create a cohesive set of tools that can be utilised across the application, streamlining development and promoting efficient code organisation. &lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

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



&lt;p&gt;In this article, I have explored the architectural layers of software development and discussed strategies for creating robust and maintainable systems. I began by understanding the importance of the App Boot Layer (ABL), where I start up and shut down the application efficiently. Moving to the Controller Layer (CL), I established a centralised control point for all entry points and separated business logic from transport frameworks. In the Business Layer (BL), I orchestrated use cases and implemented reusable, value-driven code. The Data Access Layer (DAL) acted as a bridge between business logic and data sources, while the Library Layer (LL) encapsulated modular, reusable code. Finally, the Util Layer (UL) focused on essential tools like logging and basic error handling. I hope that navigating through these layers gives you insights into building scalable and resilient software architectures.&lt;/p&gt;
&lt;h2&gt;
  
  
  Folder structure example for node.js application
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;src
├── app-boot
│   └── init
├── business
│   ├── component
│   ├── model
│   ├── repo
│   ├── service
│   └── use-case
├── controller
│   └── express
├── dal
│   └── typeorm
│        └── entity
├── lib
│   └── typeorm
│        ├── migration
│        └── subscriber
└── util
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;
  Art Disclaimer
  &lt;blockquote&gt;
&lt;p&gt;Art credit in this post goes to the dynamic duo of human creativity and artificial intelligence, with a special shoutout to &lt;a href="https://dream.ai" rel="noopener noreferrer"&gt;Dream by WOMBO&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;br&gt;


</description>
      <category>javascript</category>
      <category>programming</category>
      <category>typescript</category>
      <category>node</category>
    </item>
  </channel>
</rss>
