<?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>Forem: Alex Kondov</title>
    <description>The latest articles on Forem by Alex Kondov (@alexkondov).</description>
    <link>https://forem.com/alexkondov</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%2F109994%2F9974adf7-f708-4beb-8632-4153b7b3cf33.jpg</url>
      <title>Forem: Alex Kondov</title>
      <link>https://forem.com/alexkondov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/alexkondov"/>
    <language>en</language>
    <item>
      <title>How a Chrome Extension Broke My Side Project</title>
      <dc:creator>Alex Kondov</dc:creator>
      <pubDate>Fri, 17 Jul 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/alexkondov/how-a-chrome-extension-broke-my-side-project-5fme</link>
      <guid>https://forem.com/alexkondov/how-a-chrome-extension-broke-my-side-project-5fme</guid>
      <description>&lt;p&gt;After a long break from personal projects, the situation around the virus inspired me to build something on the side again. I’ll spare you the details but I decided to build a new kind of job board that would let developers browse open positions based on the technologies they are interested in.&lt;/p&gt;

&lt;p&gt;It’s a straight forward full-stack JavaScript application that uses React in the browser, Express on the server and Dynamo for storage. As much as I wanted to give Go, or Svelte a try I wanted to ship something fast. Learning a new technology on the go wasn’t compatible with that goal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The First Tests
&lt;/h2&gt;

&lt;p&gt;So I invested around 40-50 hours in an alpha version that had all the basic functionality in place. It wasn’t visually fascinating but it got the job done. I decided to Heroku for the Express app and Vercel for the React one.&lt;/p&gt;

&lt;p&gt;Once the alpha version was ready, I entered a few commands in the terminal and I it deployed for the world to see. I sent it to a couple of my friends to get some feedback. They told me what they liked and what they didn’t and uncovered a few bugs along the way. I had plenty of work to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  “Probably nothing serious…”
&lt;/h2&gt;

&lt;p&gt;One of the bugs they discovered was quite unfortunate. The most important feature of the app was a rich, long form which had a lot of client side functionality. It has different fields, WYSIWYG editors, file uploads, drag and drop elements and what not. Turns out the whole form didn’t on Chrome.&lt;/p&gt;

&lt;p&gt;The app was still in its infancy so I didn’t pay much attention to that. I had probably broken something small by accident just before deploying. I didn’t even open the console because I expected to see &lt;code&gt;cannot read property state of undefined&lt;/code&gt; or something in those lines. You know what I mean.&lt;/p&gt;

&lt;p&gt;Probably nothing serious. So did I think…&lt;/p&gt;

&lt;h2&gt;
  
  
  The Plot Thickens
&lt;/h2&gt;

&lt;p&gt;A couple of weeks later I had made some improvements and fixes. I settled on a name, picked fonts and colors and gave the app a bit of personality. It was time to ship the next version. I tested locally and everything worked fine, including the form.&lt;/p&gt;

&lt;p&gt;I run a few commands, type the domain name in the browser and there it is. Everything looks great. I send out the links again and wait for the responses, tapping my foot on the floor. The three dots signaling that someone is writing appeared in the chat box. A couple of seconds later the first message popped up - “The form doesn’t work again”.&lt;/p&gt;

&lt;p&gt;That’s not right I tested multiple times. I checked the console and there weren’t even warnings. I didn’t want this to be a blocker for the test so I rolled my sleeves up and started digging. I opened the form on the production environment. Wrote a few letters in one of the text fields - and the form didn’t work.&lt;/p&gt;

&lt;p&gt;There’s a small preview widget on the side that should be updated as you type but it wasn’t working. No errors in the console either. I run the app locally and everything works seamlessly. There’s something wrong with the production environment.&lt;/p&gt;

&lt;p&gt;But how could that impact the page? I didn’t use any environment variables there, nothing platform specific either. I decided to check the behavior in different browsers. Started Firefox, went to the app and opened the form. It worked. Everything was updated as expected. I started Safari and checked the form there. Everything works again.&lt;/p&gt;

&lt;h2&gt;
  
  
  We Knot Who, But We Don’t Know Why
&lt;/h2&gt;

&lt;p&gt;My friend experienced the same behavior - the bug was only in Chrome. I was completely puzzled. I never thought that Chrome of all browsers would be causing unexpected bugs. It’s usually the others that require special attention. At least I know where the problem is - time to dig.&lt;/p&gt;

&lt;p&gt;I rolled my sleeves up and opened the dev tools. I wasn’t using any unsupported browser APIs so it’s not that. No application errors but in the Network tab I see that some of the requests are marked as blocked without a status code for the response. Huh?&lt;/p&gt;

&lt;p&gt;Unsurprisingly, those requests are for the JavaScript bundles that make the form page functional. The other pages are working fine, though. Their JS gets downloaded successfully. The one for the form, however, is marked as blocked without any message or any response.&lt;/p&gt;

&lt;p&gt;My first thought was that a security rule in Chrome could be blocking the files for some reason. I did some reading around cookies, CORS, checked the configuration in Vercel but found no leads there. I scoured the web (and by that I mean Stack Overflow), searched for different phrases and problems that could give me some insight into what is happening.&lt;/p&gt;

&lt;p&gt;No thread, or documentation page held any answers for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  On The Verge Of Desperation
&lt;/h2&gt;

&lt;p&gt;What I thought would be a trivial problem related to a missing check in JavaScript turned out to be a massive blocker. I can’t ship the app without the form. If it was failing only in Safari I could live with it. But this is Chrome - everybody’s using it.&lt;/p&gt;

&lt;p&gt;At this point I had already spend my Saturday afternoon with no success. The wise thing here would be to call it a day and go back tomorrow with a clean mind. But since I was so invested I pressed on and continued to jam random words related to the problem in the search bar.&lt;/p&gt;

&lt;p&gt;Then something happened. Somehow I put the correct combination of words, the stars aligned and at the top of the list I saw a link. It still had the blue color of a page that I still hadn’t opened. It was a question on Stack Overflow, of course.&lt;/p&gt;

&lt;p&gt;I had already opened around 10 such threads, all with similar names, but hope dies last. I click on the link, hold my breath and start digging through the comments. Most of the responses and ideas I had already tried, they were of no help. But as I was about to click the back button, my eye was caught by one of the responses lower on the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  A New Hope
&lt;/h2&gt;

&lt;p&gt;It had the meager 7 upvotes but it was worth the try. All it said was to check the Chrome extensions since one of them could be interfering with the network call. Up until this moment I hadn’t even thought about them. They have access to everything on the page but in my 6 years of web development I hadn’t experienced any problems because of an extension.&lt;/p&gt;

&lt;p&gt;But at this point I couldn’t rule it out.&lt;/p&gt;

&lt;p&gt;I once again examined the unfortunate bundle. They are all named with an identifier, followed by a hash and the file extension - &lt;code&gt;index&lt;/code&gt;, &lt;code&gt;create&lt;/code&gt;, &lt;code&gt;listing&lt;/code&gt;, &lt;code&gt;advert&lt;/code&gt;. The blocked one that was breaking the form page was the &lt;code&gt;advert&lt;/code&gt; bundle. I looked at the name for a second. Then I looked at the line of extensions next to the address bar. I looked at the name again. Then back to the extensions. Oh no…&lt;/p&gt;

&lt;p&gt;A small red icon on the extension bar caught my attention - the AdBlocker. Could this be it? I disabled the AdBlocker and lo and behold - the page was fully functional. My friend got the same result. Apparently because the file contained the word &lt;strong&gt;advert&lt;/strong&gt; it was getting blocked by the extension.&lt;/p&gt;

&lt;p&gt;Everyone that tested on Chrome experienced the problem with the form. That’s because that’s their default browser and they most likely have some ad blocking add-on. Once they switched to another browser which they didn’t use and had no extensions installed, everything would work.&lt;/p&gt;

&lt;p&gt;I didn’t expect AdBlocker to be that unforgiving but as a person who is not that fond of ads, I should be careful what domain language I use in my applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Live To Tell The Tale
&lt;/h2&gt;

&lt;p&gt;So, this is it. The result of a Saturday afternoon spent debugging obscure problems. After such a session you usually go out of the room with a stern look on your face. Walking like a veteran with all your knowledge and the things you’ve seen. Well, I can’t say I learned anything new but I’ll be really careful with how I name my files from now on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Join the Newsletter
&lt;/h2&gt;

&lt;p&gt;Every few weeks I send out my &lt;a href="https://buttondown.email/kondov"&gt;newsletter&lt;/a&gt;. Usually it contains my latest article, some useful coding resources and a quote about software engineering to ponder. Drop your email if that sounds interesting to you. No ads or spam. Unsubscribe any time.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>sideprojects</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The Cost of Wrong Abstractions</title>
      <dc:creator>Alex Kondov</dc:creator>
      <pubDate>Mon, 18 May 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/alexkondov/the-cost-of-wrong-abstractions-261k</link>
      <guid>https://forem.com/alexkondov/the-cost-of-wrong-abstractions-261k</guid>
      <description>&lt;p&gt;You join a new team and after a brief onboarding you are given your first task. It’s a simple one - you need to display an additional input field on a page.&lt;/p&gt;

&lt;p&gt;After some digging you find out that most pages use the same generic component to display forms.&lt;/p&gt;

&lt;p&gt;“That’s easy” - you say - “I can just add another parameter to it”&lt;/p&gt;

&lt;p&gt;Then you open the file and you see that the four engineers before you had done the exact same thing. Multiple times. At this point you take a deep breath and realise that the next week is going to be interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrong Abstractions
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/alexkondov/art-details-and-abstractions-i91-temp-slug-1454157"&gt;Abstraction&lt;/a&gt; is a technique which is used to hide the implementation details of something behind a single idea. It allows us to use complex functionality through a simple interface.&lt;/p&gt;

&lt;p&gt;When we find that we are writing similar code, we usually look for a way to create an abstraction. To move the duplicated logic in a parent class, module or a function.&lt;/p&gt;

&lt;p&gt;So when is an abstraction wrong?&lt;/p&gt;

&lt;p&gt;Some abstractions can be misleading. Their interfaces may not communicate well enough what they do. But I would consider this a naming or a documentation problem.&lt;/p&gt;

&lt;p&gt;A truly wrong abstraction is created when we fail to solve a code duplication problem. Code that looks the same may not always change the same way. So seemingly identical logic may actually serve different purposes in the future.&lt;/p&gt;

&lt;p&gt;Putting ideas that evolve differently under the same abstraction is what makes it wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstractions Don’t Solve Duplication
&lt;/h2&gt;

&lt;p&gt;We as engineers have learned how to use abstraction to solve duplication problems. However this doesn’t mean that every such problem requires an abstraction.&lt;/p&gt;

&lt;p&gt;We design one based on the current state of the code but that may be misleading. Instead of focusing on the now, we should be thinking about the future state of the duplicated code.&lt;/p&gt;

&lt;p&gt;We may remove the duplication for the time being. But what will happen if the code that uses the abstraction needs to change differently in the future? We would have only replaced one problem with another. Instead of handling repetition we now need to take care of a faulty abstraction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrong Abstractions Don’t Scale
&lt;/h2&gt;

&lt;p&gt;We can’t predict the future but we can observe how logic evolves with time. If we rush to extract the duplications we risk putting together code that changes differently. When we try to unify different ideas our abstractions become too… &lt;em&gt;abstract&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;An abstraction that hides too many details in the end hides nothing. It becomes too generic. It will depend on many parameters to guide the logical flow and its details will bubble up to the surface.&lt;/p&gt;

&lt;p&gt;The implementation will be a mess of boolean flags, conditional statements and logic that branches off in different directions. Extending and modifying such code becomes taxing. The easiest way to get something done is to add yet another condition and contribute to the mess.&lt;/p&gt;

&lt;p&gt;At some point the benefits of the abstraction are diminished from all the &lt;strong&gt;extra work&lt;/strong&gt; and &lt;strong&gt;complexity&lt;/strong&gt; that comes with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rule of 3
&lt;/h2&gt;

&lt;p&gt;How can we remedy this? We must avoid going into extremes. We can’t wait for duplication to become unmaintainable. But at the same time we don’t want to abstract everything the instant two code blocks start looking the same.&lt;/p&gt;

&lt;p&gt;I find the &lt;strong&gt;Rule of 3&lt;/strong&gt; to be a sensible middle ground that I can agree with. It says that once you need to write the same code for the third time you should try to extract it.&lt;/p&gt;

&lt;p&gt;This gives us some breathing room and allows us to see if an actual pattern emerges. Seeing the same code in multiple places helps us to form a better API. Knowing the subtle differences between the different usages helps us to parametrise the abstraction properly.&lt;/p&gt;

&lt;p&gt;Of course, every rule has its exceptions. When you are faced with this decision you might decide to wait more to see how the API can evolve. In other cases you may create an abstraction without waiting for the code to be duplicated.&lt;/p&gt;

&lt;p&gt;It all depends on the specifics of the problem, the technologies and the business domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don’t Be Afraid to Break Out
&lt;/h2&gt;

&lt;p&gt;Imagine that you’re in the shoes of the engineer from the example in the beginning. The &lt;em&gt;easiest&lt;/em&gt; way to approach the problem would be to add an extra parameter to the common abstraction.&lt;/p&gt;

&lt;p&gt;But if every component introduces its specifics then the abstraction would stop bringing value. It would make the knowledge required to work with it higher. It would reduce the amount of details that it hides.&lt;/p&gt;

&lt;p&gt;If we find ourselves in a situation in which we want to add details to an API for a corner case then we need to reconsider.&lt;/p&gt;

&lt;p&gt;We can’t predict the future so when we find that some code is changing differently from the rest we shouldn’t add its details to the common abstraction. It’s better to break out of it. Take our the necessary code and duplicate it with the additional specific logic. Maintaining that would be less risky than building on top of the existing abstraction.&lt;/p&gt;

&lt;p&gt;That way the components that work the same still rely on a solid abstraction. And the specific case is left with an easy to maintain solution.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;A wrong abstraction is one which tries to unify ideas that change differently.&lt;/li&gt;
&lt;li&gt;We use abstractions to solve the problem of repetition. When we overdo it it becomes another burden that we need to take care of&lt;/li&gt;
&lt;li&gt;Wrongly designed abstractions don’t scale in the long term. They become too generic to the point of not hiding enough details.&lt;/li&gt;
&lt;li&gt;A solution for that is the Rule of 3 and not being afraid of breaking out of abstractions when necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Join the Newsletter
&lt;/h2&gt;

&lt;p&gt;Every few weeks I send out my my &lt;a href="https://buttondown.email/kondov"&gt;newsletter&lt;/a&gt;. Usually it contains my latest article, some useful coding resources and a quote about software engineering to ponder. Drop your email if that sounds interesting to you. No ads or spam. Unsubscribe any time.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>softwaredesign</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What Is Complexity?</title>
      <dc:creator>Alex Kondov</dc:creator>
      <pubDate>Tue, 31 Mar 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/alexkondov/what-is-complexity-dok</link>
      <guid>https://forem.com/alexkondov/what-is-complexity-dok</guid>
      <description>&lt;p&gt;What do we mean when we say that something is complex? A system, a module, a class - they can all have that quality. When we talk about software architecture we say that certain practices raise complexity. This argument is usually given as a warning that a decision needs to be reconsidered.&lt;/p&gt;

&lt;p&gt;Developers take pride in solving obscure problems and challenging puzzles. Yet, keeping a project simple is considered a virtue. But faced with a complicated business problem, is this even an option? Is there a difference between complicated and complex?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Nature of Complexity
&lt;/h2&gt;

&lt;p&gt;In “A Philosophy of Software Design”, John Ousterhout defines complexity as “anything related to the structure of a software system that makes it hard to understand and modify it”. It is an unwanted but sometimes unavoidable quality of a software.&lt;/p&gt;

&lt;p&gt;When classes are tightly coupled, changing one without affecting the other is hard. If the code is not easy to read or relies on unclear conventions, keeping track of the flow is no longer trivial. Badly written or missing documentation can hide important information.&lt;/p&gt;

&lt;p&gt;Put simply - in a complex system changes are hard. In a simple one, they are easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complex and Complicated
&lt;/h2&gt;

&lt;p&gt;The word &lt;em&gt;“complexity”&lt;/em&gt; is usually used in technical conversations. In a regular chat with a friend you’d normally use &lt;em&gt;“complicated”&lt;/em&gt;. The difference between the two is very subtle.&lt;/p&gt;

&lt;p&gt;Complex things are composed of many components and moving parts. They are hard to understand because of the way they are built. It was a decision to make something complex.&lt;/p&gt;

&lt;p&gt;When we say that something is complicated, we mean that it’s hard to understand by nature. It wasn’t an internal decision to make it that way. It’s a result of external forces.&lt;/p&gt;

&lt;p&gt;Usually when something is complicated, it will be complex as well. But software can be complex without the problem it’s solving being complicated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Causes of Complexity
&lt;/h2&gt;

&lt;p&gt;Ousterhout defines multiple causes of complexity. To me, two of them stand out the most are &lt;strong&gt;dependencies&lt;/strong&gt; and &lt;strong&gt;obscurity&lt;/strong&gt;. Besides them, &lt;strong&gt;bad documentation&lt;/strong&gt; and &lt;strong&gt;over-engineering&lt;/strong&gt; are at the top of my personal list.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependencies
&lt;/h3&gt;

&lt;p&gt;The first thing that come to mind when we say the word dependency is external libraries. Third party functionality that our code literally depends on to work properly.&lt;/p&gt;

&lt;p&gt;External code increases complexity because it introduces outside rules that we need to conform to. If our application is structured around a library or a framework, every developer needs to understand the third party APIs before they make changes.&lt;/p&gt;

&lt;p&gt;This increases the cognitive load that one needs to take in order to start working. Utility libraries don’t have that big of an impact, but unless abstracted with wrapper code, they can still influence the data flow and other APIs.&lt;/p&gt;

&lt;p&gt;A bigger problem than third party packages is when we introduce tight dependencies between our own classes and modules.&lt;/p&gt;

&lt;p&gt;Each component, no matter how big it is, has two parts - an interface and an implementation. The interface is what we expose to the world. The methods and properties that other components will communicate with in order to use the underlying functionality.&lt;/p&gt;

&lt;p&gt;There is a contract between the two components. If you call the interface with the required arguments, you’d get a response of a certain type.&lt;/p&gt;

&lt;p&gt;You don’t want the components to care about &lt;em&gt;how&lt;/em&gt; they do their job, as long as they respect the contract. If, by changing the implementation of one component you need to modify multiple others, then boundaries are not properly set.&lt;/p&gt;

&lt;p&gt;If you are not sure of the broader impact of a change in a class then you’d have to spend more time testing and validating. The more system specific knowledge you need to have, the higher the complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Obscurity
&lt;/h3&gt;

&lt;p&gt;The lack of clarity is another cause of higher complexity. More specifically - bad naming. Imagine a class named in a way that ends in &lt;em&gt;Helper&lt;/em&gt;, &lt;em&gt;Manager&lt;/em&gt; or &lt;em&gt;Utility&lt;/em&gt;. Can you guess what it does? Me neither.&lt;/p&gt;

&lt;p&gt;Names that are too generic don’t give enough information and lead to confusion. By being more clear we leave less for interpretation. We should aim to use descriptive identifiers or ones that are widely accepted for a specific purpose.&lt;/p&gt;

&lt;p&gt;Naming is important on a micro level as well. Being unclear with the purpose of variables is a leading cause of confusion. In a loop, a variable named &lt;em&gt;i&lt;/em&gt; usually carries the current index. Outside of that use case it’s better to be more verbose and spell out the full word - &lt;em&gt;index&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Magic constants are even worse. If you find a number being multiplied by &lt;em&gt;0.9384528&lt;/em&gt; - it probably carries some significance. If those constants are not given descriptive names then your guess about them is as good as any.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentation
&lt;/h3&gt;

&lt;p&gt;Documentation in the code is in the form of comments. They are widely appreciated when done properly. Sadly, often they are not. A comment should be part of the abstraction - it should provide a high level explanation of what the module or the method is doing.&lt;/p&gt;

&lt;p&gt;People say that good code is self-documenting but not everything can be expressed through code. Comments serve that purpose. They should be used to explain the things that are missing in the API - why, what, edge cases, unexpected behavior. They capture information that the code’s author couldn’t express without using a non-programming language.&lt;/p&gt;

&lt;p&gt;Comments should be used to explain &lt;em&gt;why&lt;/em&gt; we are doing something. In order to work on a product you need to know more than the technical details. You need to understand the domain. Business logic expressed in code can leave you with a lot of questions. A few helpful comments that explain why an operation has to happen before the other is incredibly useful.&lt;/p&gt;

&lt;p&gt;You shouldn’t need to read a method to know what it does. Looking at the API and the documentation should give you enough information. Having to read every function that you need to call is an unproductive way to spend your time.&lt;/p&gt;

&lt;p&gt;It’s possible to overdo them as well. If you find yourself repeating your code with comments that’s a red flag. Too many explanations lead to too much noise. There’s no benefit in explaining that you’re looping through a collection of database records or reading from a file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Over-Engineering
&lt;/h2&gt;

&lt;p&gt;Dependencies, obscurity and bad documentation are well-known causes of complexity. Many projects have been hurt by them so we know how to tackle them. But we mentioned that software can become complex even when the problem it’s solving is not complicated.&lt;/p&gt;

&lt;p&gt;This is known as over-engineering - when we design something in a more robust and complex way that it needs to be. But why do we do this? Since simplicity in software development is widely appreciated shouldn’t our problem be under-engineering?&lt;/p&gt;

&lt;p&gt;Often we try to look into the future and make guesses about how the project is going to evolve. We make decisions now that would help us to make modifications in the future. By putting certain abstractions in place early we can easily change the underlying implementation if we need to.&lt;/p&gt;

&lt;p&gt;The truth is that we are horrible at predicting the future. Most times the precautions we put in place wouldn’t be needed or they’d be wrong. This increases the levels of complexity that we need to deal with. It makes development slower and harder.&lt;/p&gt;

&lt;p&gt;We create complex architectures that can launch a space shuttle even though we’re still riding a bike. More projects fail from over-engineering rather than the opposite.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;When we say that something is complex it is because it is composed of many parts and connections between them.&lt;/li&gt;
&lt;li&gt;Even though we cherish simplicity, we can end up with complex projects that are hard to understand and work on.&lt;/li&gt;
&lt;li&gt;Complexity is unwanted but sometimes unavoidable.&lt;/li&gt;
&lt;li&gt;There are four major causes of complexity - dependencies, obscurity, bad documentation and over-engineering.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Join the Newsletter
&lt;/h2&gt;

&lt;p&gt;Every few weeks I send out my &lt;a href="https://buttondown.email/kondov"&gt;&lt;strong&gt;my newsletter&lt;/strong&gt;&lt;/a&gt;. Usually it contains my latest article, some useful coding resources and a quote about software engineering to ponder. Drop your email if that sounds interesting to you. No ads or spam. Unsubscribe any time.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>career</category>
      <category>softwaredesign</category>
      <category>philosophy</category>
    </item>
    <item>
      <title>The T-Shaped Engineer</title>
      <dc:creator>Alex Kondov</dc:creator>
      <pubDate>Thu, 12 Mar 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/alexkondov/the-t-shaped-engineer-3io3</link>
      <guid>https://forem.com/alexkondov/the-t-shaped-engineer-3io3</guid>
      <description>&lt;p&gt;The choice between being a specialist or a generalist is debated by many engineers. Nowadays, the industry may need something in between.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generalist
&lt;/h2&gt;

&lt;p&gt;As the saying goes, “A jack of all trades, but a master of none”. If you decide to go the path of the generalist your skills will grow horizontally. You will enjoy learning new concepts and will be able to satisfy your curiosity by working with different tools and languages.&lt;/p&gt;

&lt;p&gt;However, mastering anything will be hard. In order to become proficient with a technology you need to dedicate massive amounts of time to it. A generalist focuses on multiple things at once, so their attention is split up.&lt;/p&gt;

&lt;p&gt;In recent years, being called a jack of all trades has a slight negative connotation. Generalists cover a lot of area in their skills but many remain on the surface. Often, when challenging work needs to be done - engineers with deeper knowledge are needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Specialist
&lt;/h2&gt;

&lt;p&gt;Specialists devote their time and work to a narrow set of technologies and tools. They sacrifice the joy of exploring multiple disciplines by dedicating their time and efforts towards one area. That way they may lack knowledge beyond the fundamentals in supporting areas but become masters at what they do.&lt;/p&gt;

&lt;p&gt;Many developers are in this field because of the challenge. They like solving puzzles and untangling complex problems. It is often the specialists which are tasked with the most difficult but rewarding solutions.&lt;/p&gt;

&lt;p&gt;Their mastery gives them insight that other developers lack.&lt;/p&gt;

&lt;p&gt;Devoting all your time in one language, stack or technology can be limiting, though. If you decide to go the specialist route, you need to consider what investment will pay off the best in the long term.&lt;/p&gt;

&lt;h2&gt;
  
  
  Companies, Markets and Talent
&lt;/h2&gt;

&lt;p&gt;The software industry is experimenting and looking for ways to build more effectively. In recent years we’ve come to the realisation that software engineers are not burdened with the challenges of other industries. We don’t have to develop products the same way physical ones are done.&lt;/p&gt;

&lt;p&gt;We can ship faster, change frequently and most importantly - revert if we have to. Nowadays, projects rarely go as planned from start to finish. Modifications are made along the way. Sometimes whole features are abandoned and new ones are prioritised in their place.&lt;/p&gt;

&lt;p&gt;Those specifics lead companies to look for smarter ways to work. But in order to do that, the industry needs different talent.&lt;/p&gt;

&lt;h2&gt;
  
  
  How We Used to Work
&lt;/h2&gt;

&lt;p&gt;In the past, product work was prioritised based on what resources were available. If a feature required more back end engineers, but the Java developers were busy then development on it would be postponed.&lt;/p&gt;

&lt;p&gt;This could cause hiring problems. When the company expects more back end or front end work, it would hire specialists in the corresponding area. But if priorities shift we’d end up with unutilized engineering power.&lt;/p&gt;

&lt;p&gt;I’ve witnessed this more than once - product management trying to figure out how to keep the UI team busy. The next couple of months the back end team would focus on refactoring and improvements. So there is no one to implement the new required endpoints.&lt;/p&gt;

&lt;p&gt;In this scenario, engineers may get asked to take up tasks that they wouldn’t normally do. This can be frustrating for people that have spent their time mastering a different stack.&lt;/p&gt;

&lt;p&gt;While this could be a sign of bad planning, I don’t fully agree. People get hired because of their skill set but at some point direction shifts. Maybe a new competitor entered the market, maybe the users’s preferences changed, maybe it was something else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best of Both Worlds
&lt;/h2&gt;

&lt;p&gt;The business needs engineers that can adapt to the dynamics of the modern world. Professionals that are self-sufficient and won’t go into paralysis when the DevOps is out on holiday. Ideally, any person in the team should fill any other role if needed - from small tweaks on the UI, to debugging the CI pipeline.&lt;/p&gt;

&lt;p&gt;This is easier said than done, though. Acquiring the skills to be productive in multiple areas requires years. You also need to be exposed to different parts of the product. A company with strong silos between teams won’t give you that opportunity.&lt;/p&gt;

&lt;p&gt;At the same time, when complex work needs to be done, a team of generalists may lack the experience to take proper decisions. When the database’s performance needs improvement or architectural decisions need to be made you need a person that’s deeply focused on that topic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The T-Shaped Engineer
&lt;/h2&gt;

&lt;p&gt;The evolution of software development methodologies required a new kind of engineers - specialised generalists.&lt;/p&gt;

&lt;p&gt;Thus, the term “T-Shaped Specialist” was coined. It is used to describe a person whose knowledge distribution looks like the letter T. The horizontal line describes a broad working knowledge in multiple areas. The vertical one is for specialization in a topic.&lt;/p&gt;

&lt;p&gt;A back end engineer who can put up their own interface, style it reasonably and deploy it may fall into that category. A UI engineer that can spin up an Express service when needed and can debug an API endpoint could also be considered T-Shaped.&lt;/p&gt;

&lt;p&gt;Having a team of specialised generalists means that work can be prioritised without worrying about the available developers. This breaks the silos around teams and helps everyone to get more involved in the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems of T-Shaped Engineers
&lt;/h2&gt;

&lt;p&gt;Having T-Shaped specialists is not a silver bullet. It doesn’t mean that anyone can do any job and do it well. While they have broad knowledge this doesn’t mean that they can perform exceptionally everywhere.&lt;/p&gt;

&lt;p&gt;The business may sometimes falsely expect such engineers to be experts in everything. T-shaped engineers can adapt and get up to speed with different technologies. But they still have a main area of focus.&lt;/p&gt;

&lt;p&gt;Expecting a specialized generalist to be an expert on cloud, microservice architecture and user interfaces is not realistic. Developers can wear many hats and support each other but knowing each team member’s strong sides is crucial.&lt;/p&gt;

&lt;p&gt;Otherwise we are again in the situation in which we expect generalists to take decisions which require serious expertise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is It a Choice?
&lt;/h2&gt;

&lt;p&gt;I recently started a couple of discussions on LinkedIn about specialists and generalists. Which option should a professional pick nowadays? Some of the answers came from non-technical people which shows that this is not just a problem in the software industry but as a whole.&lt;/p&gt;

&lt;p&gt;The summary I can give from all the responses is that people are leaning more towards being a generalist or a T-Shaped specialist.&lt;/p&gt;

&lt;p&gt;I don’t think this is a trend. It’s a real need that the business has and being a generalist may no longer be an option but a requirement.&lt;/p&gt;

&lt;p&gt;Even if you devote your time to one topic it requires you to have knowledge in multiple supporting areas. Modern tooling has become so good that it allows us to be more involved in the full development process.&lt;/p&gt;

&lt;p&gt;But with that comes the responsibility to learn more. When you’re building something you need to write tests for it. Then comes the question about how you will deploy it. To do that, you need to decide what infrastructure would do the best job.&lt;/p&gt;

&lt;p&gt;Once the deployment process is done it opens the door to more challenges. You need to monitor and maintain the product you’ve shipped which is no easy task.&lt;/p&gt;

&lt;p&gt;To do all this properly you need more than just working knowledge with a broad set of tools. As culture shifts to a “You build it, you run it” mindset - specialising in one area is no longer enough.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Software developers need to make the choice between being a generalist or a specialist.&lt;/li&gt;
&lt;li&gt;Generalists have access to broader variety of work. Specialists are focused on a single area but problems they face are often more challenging&lt;/li&gt;
&lt;li&gt;Companies need to be flexible and adapt to market conditions. To do that they need talent that can easily shift priorities too.&lt;/li&gt;
&lt;li&gt;Specialists are too tightly focused. Generalists are flexible but they may lack the experience required for complicated tasks.&lt;/li&gt;
&lt;li&gt;A T-Shaped specialist is someone who has broad knowledge across multiple disciplines but focuses on one the most. Developers with this profile are highly valued across organizations. They are adaptable but can provide deep insight on the topics they have focused on. &lt;/li&gt;
&lt;li&gt;Chosing between being a generalist or a specialist may no longer be a choice. Modern tooling lowers the barrier of entry in other disciplines. Engineers are expected to do more beyond design and implementation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Join the Newsletter
&lt;/h2&gt;

&lt;p&gt;Every few weeks I send out &lt;a href="https://buttondown.email/kondov"&gt;&lt;strong&gt;my newsletter&lt;/strong&gt;&lt;/a&gt;. Usually it contains my latest article, some useful coding resources and a quote about software engineering to ponder. Drop your email if that sounds interesting to you. No ads or spam. Unsubscribe any time.&lt;/p&gt;

</description>
      <category>career</category>
      <category>programming</category>
      <category>philosophy</category>
    </item>
    <item>
      <title>Indentation Warfare - Tabs or Spaces</title>
      <dc:creator>Alex Kondov</dc:creator>
      <pubDate>Tue, 25 Feb 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/alexkondov/indentation-warfare-tabs-or-spaces-1098</link>
      <guid>https://forem.com/alexkondov/indentation-warfare-tabs-or-spaces-1098</guid>
      <description>&lt;p&gt;I don’t remember when I found out about the timeless debate on tabs and spaces. I’m a self taught developer and I’ve missed some of the common arguments that occur in an academic environment.&lt;/p&gt;

&lt;p&gt;My first job was quite forgiving for the uninitiated - no one was overzealous on engineering topics. After that I freelanced and worked for small startups. In that environment no time or energy could be spent on philosophical debates.&lt;/p&gt;

&lt;p&gt;I think it was at my first &lt;em&gt;real&lt;/em&gt; office job when I understood the gravity of the indentation topic. I casually joked that no one actually cares about this and it turned out to be false. I was faced with a wall of slightly raised eyebrows and looks of disappointment when I expressed my neglect to the topic.&lt;/p&gt;

&lt;p&gt;Now, if I had said something in favour of either side I would’ve gotten some allies. But I managed to alienate both groups by playing down the seriousness of the matter.&lt;/p&gt;

&lt;p&gt;As you can guess, I got educated on the matters of indentation warfare that day. Something that I thought was a matter of personal preference or habits, turned out to be a nuanced topic with solid reasoning from both sides.&lt;/p&gt;

&lt;p&gt;If you’re thinking like I was and you’re wandering what the big deal is, let me spare you a lecture or two with this article. I’ve never thought I’d be writing about whitespaces but the peculiarities of this industry are endless.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Conflict
&lt;/h2&gt;

&lt;p&gt;We use indentation to create visual hierarchies and improve the structure and readability of our code. Mainly we use it to show what lines of code belong inside a conditional, loop, method or class.&lt;/p&gt;

&lt;p&gt;Besides showing scope, it can also be used to break down longer logical operations. A ternary operator with a complicated condition can have its possible expressions on the next couple of lines indented to easily distinguish them.&lt;/p&gt;

&lt;p&gt;Chained method calls, if they are more than two, can be indented on new lines to show that they belong to the same flow of operations.&lt;/p&gt;

&lt;p&gt;Indentation is a tool that is useful only for the human - the developer reading and writing the code. The compiler benefits nothing from the amount of white spaces used at the beginning of each line (Python is an exception).&lt;/p&gt;

&lt;p&gt;The argument about tabs and spaces is not about the correct amount of indentation. It’s about the characters we use and their benefits and drawbacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tab Character
&lt;/h2&gt;

&lt;p&gt;Pressing the tab button on the keyboard outputs a tabulation character. It is interpreted by the editor as an amount of white space, usually 4 or 8 spaces.&lt;/p&gt;

&lt;p&gt;Files that are formatted with tabs are usually smaller, since a single tab character represents multiple whitespaces. Not that it’s much of a problem nowadays.&lt;/p&gt;

&lt;p&gt;The tab length is interpreted differently in IDEs and editors. It is also configurable, so if you would like to have tabulations of 6 spaces - you can. This makes tabs a great tool for people with visual impairments - they are customizable.&lt;/p&gt;

&lt;p&gt;Tabs are descriptive - they tell the editor the amount of indentation that should be added. But the decision about how to render them depends on who reads the code. In the mind of a tab user, they should be used for indentation and spaces should be used for alignment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Argument for Spaces
&lt;/h2&gt;

&lt;p&gt;The main arguments for spaces is the consistency. Different platforms and editors display tabs with varying sizes. Since they are configurable, there is no guarantee that the code you’ve written will be read the same way.&lt;/p&gt;

&lt;p&gt;You’ve probably copy/pasted code from somewhere and it appeared all messed up because of differences in indentation.&lt;/p&gt;

&lt;p&gt;Across all editors and platforms - a whitespace is always a whitespace. While tabs can be configured, the whitespace is the same no matter where it is shown. This means that the code will be displayed with the same formatting no matter the tab settings.&lt;/p&gt;

&lt;p&gt;The difference is that this decision is only made by the writer of the code, not the reader. Spaces bake the formatting decisions in the code itself. Reading code with different formatting does not change its behaviour but it’s not the way the developer meant it to be read.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not Just a Technical Debate
&lt;/h2&gt;

&lt;p&gt;In the begining of the article we said that the argument is about the characters used to create indentation. But the debate is not just technical - it’s a philosophical one.&lt;/p&gt;

&lt;p&gt;It’s about whose responsibility it is to specify indentation.&lt;/p&gt;

&lt;p&gt;Tabs supporters believe that should be left to the readers - let them decide the structure. Spaces advocates would prefer to specify them explicitly - consistency is most important.&lt;/p&gt;

&lt;p&gt;To me this is what all arguments and debates on the topic culminate in if we take personal preference aside.&lt;/p&gt;

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

&lt;p&gt;With each article I get more fascinated about the depth of the software development industry. The fact that we can have broad and ongoing discussions about things as basic as white spaces.&lt;/p&gt;

&lt;p&gt;You will meet zealots on both sides who will try to persuade you to join their ranks. They have solid arguments but in the end it comes to the preferences of the developers. It comes down to what you believe is right - should the author of the code specify its indentation or should that be left to the reader.&lt;/p&gt;

&lt;p&gt;If an approach was outright wrong, it would’ve been ruled out by now. The fact that the debate is still on means that the truth is up to us to decide.&lt;/p&gt;

</description>
      <category>career</category>
      <category>webdev</category>
      <category>programming</category>
      <category>philosophy</category>
    </item>
    <item>
      <title>The Economics of Technical Debt</title>
      <dc:creator>Alex Kondov</dc:creator>
      <pubDate>Tue, 04 Feb 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/alexkondov/the-economics-of-technical-debt-fm3</link>
      <guid>https://forem.com/alexkondov/the-economics-of-technical-debt-fm3</guid>
      <description>&lt;p&gt;Technical debt - a tool used to negotiate a refactor for the mess you made 6 months ago.&lt;/p&gt;

&lt;p&gt;It is often mentioned in the company of other negatively loaded terms, such as Legacy code, bugs and anti-patterns. Does that mean that legacy code is technical debt? Is badly written code considered that as well?&lt;/p&gt;

&lt;p&gt;Even though all the terms are used to express the faults in a piece of software, there are big differences between them.&lt;/p&gt;

&lt;p&gt;The term technical debt was first used by Ward Cunningham. He used it to explain the importance of refactoring to his business colleagues. More specifically - the need to set extra time aside to fix code written in a hurry. He compared rushing software to taking financial debt.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“With borrowed money, you can do something sooner than you might otherwise, but then until you pay back that money you’ll be paying interest. I thought borrowing money was a good idea, I thought that rushing software out the door to get some experience with it was a good idea, but that of course, you would eventually go back and as you learned things about that software you would repay that loan by refactoring the program to reflect your experience as you acquired it.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think that this is an excellent metaphor. It describes tech debt as a tool rather than the results of a team’s blunders.&lt;/p&gt;

&lt;h2&gt;
  
  
  Money and Bits
&lt;/h2&gt;

&lt;p&gt;We may need a large amount of money in advance to buy a house. Similarly, we may need some extra time in order to hit a deadline. In the first example we can take a loan to afford the purchase. In the second one, no one can give us extra time. However, we can disregard some best practices so we can move faster and meet the deadline.&lt;/p&gt;

&lt;p&gt;In financial sense - we’ve taken money so we need to repay them with an extra sum on top in the form of interest. In technological sense, we’ve taken time - so we need to repay it with extra time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Interest on Technical Debt
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://martinfowler.com/bliki/TechnicalDebt.html"&gt;This Martin Fowler article&lt;/a&gt; continues the financial metaphores. Much like monetary debt, the technical one accumulates interest. We gain more speed at the time being but in the long term we need to sacrifice speed in order to refactor it.&lt;/p&gt;

&lt;p&gt;This is the main argument against the use of tech debt - it’s slower than doing things right. However, sometimes we don’t mind being slower in the long term if we can get some extra features ready for an investor pitch.&lt;/p&gt;

&lt;p&gt;There is another way to look at the interest that is acquired. When we accumulate technical debt and continue development as usual, every new change will come a tad bit slower because of the interest rate.&lt;/p&gt;

&lt;p&gt;With every new feature we are paying off interest. But without paying off the principal and fixing the root cause, the problem won’t go away. The interest rate grows and even minor changes take a long time to come to fruition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bad Code is not Tech Debt
&lt;/h2&gt;

&lt;p&gt;Technical debt is not a matter of age. Many startups rewrite their software once they achieve stability. But it’s not a product of badly written code either. As Uncle Bob says - &lt;a href="https://sites.google.com/site/unclebobconsultingllc/a-mess-is-not-a-technical-debt"&gt;a mess is not a technical debt&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The decision to take tech debt should always be strategic and rational - it should have a purpose. Writing untested, undocumented and confusing code without a reason behind it is a sign of bad engineering culture.&lt;/p&gt;

&lt;p&gt;Are we writing bad code or creating tech debt? Well, do we plan to go back and refactor that component? Is there a reason for the code not to be written in a better way? Answering those questions can give us a good idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s the Difference?
&lt;/h2&gt;

&lt;p&gt;Starting a business can be hard unless there is a way to get some form of investment. Startup founders delight in the fact that they can operate with large amounts of money up front. However, in the software world, engineers strongly believe that the best amount of technical debt is zero. Why the difference in opinions?&lt;/p&gt;

&lt;p&gt;Because tech debt is invisible and it often gets left unpaid. That leaves the developers to deal with an ever growing interest rate in combination with business requirements.&lt;/p&gt;

&lt;p&gt;If we don’t repay a loan we will have to face the wrath of the entity that provided us with it. If we don’t repay the technical debt there will be no direct consequence. Feature development slows down a bit and developers become grumpy but nothing gets repossessed.&lt;/p&gt;

&lt;p&gt;There is no pressing need to go back and fix the problem. It’s most likely the opposite - now that this is done we can start looking into the future.&lt;/p&gt;

&lt;p&gt;It also depends on company size and the product being developed. Taking on tech debt is a decision that each time makes on its own. The organisation is not fully aware of the condition of each microservice or tool that is developed under its hood.&lt;/p&gt;

&lt;p&gt;Financial debt is not a decision made on a team by team basis. Technical one on the other hand is. Even though it was decided by a handful of people, its effects could impact the whole company. This is how a problematic component in the centre of a new feature could bottleneck a release.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech Grants
&lt;/h2&gt;

&lt;p&gt;There’s another major difference between financial and technical debt. If we never have to change that same code again the we’d never have to pay off the debt. In those rare situations it’s not debt but more of a grant.&lt;/p&gt;

&lt;p&gt;Outsourcing companies are prone to cut corners because they are not expected to support a product in the long term. If a project is going to be handed over in a few months, the tech debt becomes someone else’s worry.&lt;/p&gt;

&lt;p&gt;Startups, in their hopes to find market fit, need to iterate fast. They &lt;strong&gt;have&lt;/strong&gt; to take technical debt in order to see what features stick and what don’t. When you have a limited runway writing clean and maintainable code is a bit lower in the list of priorities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debt by Accident
&lt;/h2&gt;

&lt;p&gt;In theory, tech debt should only be used strategically. However, there is an exception to the rule and creating technical debt by accident is a possibility.&lt;/p&gt;

&lt;p&gt;Nowadays, when most companies are using agile methodologies, requirements and direction are not set in stone. Complete knowledge about the product up front is a rare occurrence.&lt;/p&gt;

&lt;p&gt;When we make design decisions we can only take into account the current requirements. As they shift, so does the need for different system or component design. Changing the direction in which we develop means that the current environment is longer be ideal.&lt;/p&gt;

&lt;p&gt;We try to think ahead into the future and make architectures that are flexible and resilient. But as time goes the common abstractions that we have in place won’t be enough. Some changes to the original design would be required to improve the way we implement new functionality.&lt;/p&gt;

&lt;p&gt;Tech debt is not caused by the age of the software but there is a correlation between the two. The older the product the higher the chance its architecture will need some improvement to accommodate new features. That’s why even organisations with strong technical culture need to budget time for continuous refactoring.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Like financial debt, tech debt allows us to achieve something faster. However, the interest for it is repaid with time rather than money.&lt;/li&gt;
&lt;li&gt;It is a tool that should be used strategically, only when there is a purpose for it. The reasons could be a deadline, investment pitch or a short runway.&lt;/li&gt;
&lt;li&gt;Badly written code is not technical debt. &lt;/li&gt;
&lt;li&gt;Unlike its financial counterpart, tech debt is often left unpaid. This is because it is less visible and its effects are indirect.&lt;/li&gt;
&lt;li&gt;Continuous refactoring is required even in the strongest of organisations. As products change, often the initial system design is no longer ideal for them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Join My Newsletter
&lt;/h2&gt;

&lt;p&gt;Every few weeks I send out a &lt;a href="https://buttondown.email/kondov"&gt;&lt;strong&gt;newsletter&lt;/strong&gt;&lt;/a&gt;. Usually it contains my latest article, some useful coding resources and a quote about software engineering to ponder. Drop your email if that sounds interesting to you. No ads or spam. Unsubscribe any time.&lt;/p&gt;

</description>
      <category>career</category>
      <category>techdebt</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Legacy Code and Chesterson's Fence</title>
      <dc:creator>Alex Kondov</dc:creator>
      <pubDate>Mon, 20 Jan 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/alexkondov/legacy-code-and-chesterson-s-fence-47oj</link>
      <guid>https://forem.com/alexkondov/legacy-code-and-chesterson-s-fence-47oj</guid>
      <description>&lt;p&gt;Ah, legacy code. Two words that can strike fear in the heart of any developer.&lt;/p&gt;

&lt;p&gt;Two words that if mentioned in front of your developer friends will immediately cause grimaces and sighs. One of them - a battle hardened veteran puts their hand on your shoulder and tells you to pull through until you get the chance to rewrite.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Therapist&lt;/strong&gt; : “What’s the most traumatic event in your life?”&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Developer&lt;/strong&gt; : “I’ve worked on a legacy system”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Why is the general opinion about legacy software negative? Is it so bad to work on a project which is 5 to 10 years old?&lt;/p&gt;

&lt;p&gt;Is the problem with legacy code only related to the age of the software? Perhaps the problem is more related to the technologies used? Can a 2 year old project cause the same desire in us to turn it off and rewrite it anew?&lt;/p&gt;

&lt;p&gt;The software field is dynamic, it changes fast and provides a good challenge for anyone that enjoys learning. But every coin has two sides.&lt;/p&gt;

&lt;p&gt;New technologies bring a lot of excitement but draw it away from older software. Finding better way to structure applications or design systems shows the faults in the older ones.&lt;/p&gt;

&lt;p&gt;Why is the software industry so disgusted by legacy code? Why aren’t other fields so obsessed about progress as well? My dentist has been using pretty much the same technology ever since I can remember.&lt;/p&gt;

&lt;p&gt;We’ve probably found better ways to build houses as well. Yet we don’t have the need to rebuild them every few years.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt; : “But I like my house!”&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Engineer&lt;/strong&gt; : “We found a better way to build it. Tear it down boys!”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Does Legacy Even Mean?
&lt;/h2&gt;

&lt;p&gt;The term &lt;strong&gt;&lt;em&gt;legacy system&lt;/em&gt;&lt;/strong&gt; means an old or outdated method, technology or program which is still in use. It may be in need of replacement but most importantly - it is still running in production.&lt;/p&gt;

&lt;p&gt;The first time the term &lt;strong&gt;&lt;em&gt;legacy&lt;/em&gt;&lt;/strong&gt; was used was some time in the 80s. There needed to be some distinction between previous software created in the 70s - hence the term was coined.&lt;/p&gt;

&lt;p&gt;Legacy systems are old - that’s implied by the name. But we don’t frown upon such systems only because of their age. Some legacy systems are stable and mature despite that. There are many old technologies that are actively maintained, tested and improved upon.&lt;/p&gt;

&lt;p&gt;However not many old software products manage to withstand the test of time. While it is still functional - the biggest problem with such software is that it uses designs and techniques which may now be considered obsolete.&lt;/p&gt;

&lt;p&gt;In other words - &lt;strong&gt;the stack is not one that we’d use to start a new project in today&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Often such systems are not well maintained and fall victim to software rot. If not kept up to date they fall behind the fast iterations in the software development world and become unappealing to work on.&lt;/p&gt;

&lt;p&gt;The software may depend on libraries or tools which are no longer maintained, so fixing problems related to them becomes troublesome.&lt;/p&gt;

&lt;p&gt;Especially in large legacy codebases it’s hard to get an understanding of the dependencies and connections between components. So, making changes can be a risky undertaking.&lt;/p&gt;

&lt;p&gt;Can we be sure that making a small modification to a method is not a decision that will haunt us at 3am on a Saturday?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Developer&lt;/strong&gt; : “How do we test if this works?”&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Legacy Code Veteran&lt;/strong&gt; : “We ship it to the customers and pray”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the code is extensible we can build upon it and rely on the foundations. If it’s not - making modifications becomes a delicate process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Legacy Code
&lt;/h2&gt;

&lt;p&gt;But this is what tests are for, I hear you say. This is right - the sole purpose of tests is to give us confidence that we are shipping working code. Unfortunately, most inherited projects written a long time ago lack a proper test suite.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Legacy code is code without tests.&lt;br&gt;&lt;br&gt;
— Michael Feathers, author of “Working Effectively with Legacy Code”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The book &lt;a href="https://www.goodreads.com/book/show/44919.Working_Effectively_with_Legacy_Code"&gt;Working Effectively with Legacy Code&lt;/a&gt; focuses on refactoring techniques and methodologies to make legacy code easier to work with. However, the core idea in the book is the importance of tests.&lt;/p&gt;

&lt;p&gt;Before we make any changes to legacy code we should write tests for it. Tests that could validate the proper output and functionality of that class or module. Then after every change we can validate if we have achieved the correct behaviour or we have broken something.&lt;/p&gt;

&lt;p&gt;If a project was written 2 years ago but is tightly coupled and lacks proper testing then it might as well be considered legacy too.&lt;/p&gt;

&lt;p&gt;This leads us to a conclusion - the problem with legacy code is not the lack of tests per se. It’s the &lt;strong&gt;insecurity&lt;/strong&gt; and &lt;strong&gt;discomfort&lt;/strong&gt; of making changes to it that the absence of tests brings.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Legacy Lives On
&lt;/h2&gt;

&lt;p&gt;If legacy systems are such a problem can’t we pull the plug on them? The reasons why legacy code continues to live go beyond its technical quality.&lt;/p&gt;

&lt;p&gt;The software may still be bringing enough value for customers as it is. The reasons may also be budgetary - it’s often cheaper to maintain old software rather than rewrite it.&lt;/p&gt;

&lt;p&gt;If a legacy codebase requires only minor changes here and there then a rewrite wouldn’t be justified. Another reason would be the lack of better options technology wise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can We Rewrite It?
&lt;/h2&gt;

&lt;p&gt;With all that said, we’d much rather replace the legacy codebase than work on it. So the most common question when discussing the future of such systems is whether they can be rewritten.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Developer&lt;/strong&gt; : “Why don’t we just rewrite it from scratch?”&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Manager&lt;/strong&gt; : “Oh, here we go…”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As engineers we don’t want to deal with old and neglected systems partially because we believe we’d do a better job than the people who built them. We hate going on safaris through miles long classes without a single comment.&lt;/p&gt;

&lt;p&gt;This is not the kind of work that one person writes and leaves behind. It’s code that many people worked on through time. Each with their own &lt;strong&gt;style&lt;/strong&gt; , &lt;strong&gt;preferences&lt;/strong&gt; and &lt;strong&gt;opinions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But it’s easy to see that the decisions are subpar now that we have the complete picture. That legacy system took years to build. The engineers before us had to make decisions based on budget, conflicting requirements and stressful deadlines.&lt;/p&gt;

&lt;p&gt;We have no proof that we would do a better job than the engineers before us if we are to work in the same conditions. We also have no proof that we’d do a better job at rewriting the system if we start now.&lt;/p&gt;

&lt;p&gt;It’s frighteningly easy to see possibilities for improvements when we are new to a project. A class doesn’t seem to be used. A function makes no sense. A mess of conditional checks looks like it can be rewritten in a single line.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;New Team Member&lt;/strong&gt; : “I deleted a method which wasn’t referenced anywhere in the codebase”&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Veteran&lt;/strong&gt; : “No! That method gets dynamically called by a cron job that runs once every quarter!”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Chesterson’s Fence
&lt;/h2&gt;

&lt;p&gt;There’s a mental model named after that - &lt;strong&gt;The Fallacy of Chesterson’s fence&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Chesterson’s fence is a principle that says we should never take a fence down until we know the reason why it is put up.&lt;/p&gt;

&lt;p&gt;As an engineer you notice some code that seems redundant or too complex - “This is nuts, I can’t see why it is done that way”.&lt;/p&gt;

&lt;p&gt;You strongly believe that you can rewrite the whole thing in a couple of lines.&lt;/p&gt;

&lt;p&gt;To which a more senior member of the team would say - “Show me why it’s done like this and then I’ll let you rewrite it”.&lt;/p&gt;

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

&lt;p&gt;There are many factors that contribute to the negative stigma of legacy software - &lt;strong&gt;age&lt;/strong&gt; , &lt;strong&gt;code quality&lt;/strong&gt; and the &lt;strong&gt;lack of tests&lt;/strong&gt; are the biggest ones.&lt;/p&gt;

&lt;p&gt;Projects which are not maintained and improved easily becomes victim of software rot.&lt;/p&gt;

&lt;p&gt;Such software is hard to work on for a variety of reasons - &lt;strong&gt;tight coupling&lt;/strong&gt; , &lt;strong&gt;lack of documentation&lt;/strong&gt; , &lt;strong&gt;high risk of failure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Rewriting seems to be the silver bullet but not always.&lt;/p&gt;

&lt;p&gt;We have no guarantee that we wouldn’t fall into the same pitfalls that the previous teams did.&lt;/p&gt;

</description>
      <category>career</category>
      <category>legacycode</category>
      <category>philosophy</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Philosophy of Software Development</title>
      <dc:creator>Alex Kondov</dc:creator>
      <pubDate>Fri, 03 Jan 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/alexkondov/the-philosophy-of-software-development-4gn</link>
      <guid>https://forem.com/alexkondov/the-philosophy-of-software-development-4gn</guid>
      <description>&lt;p&gt;Software development is considered a field ruled by logic. Every decision we make is guided by rules that we can follow and understand. Every problem has an engineering solution. Every opinion can be either true or false.&lt;/p&gt;

&lt;p&gt;If you’ve spent some time in the software industry you know that this is not true. We make decisions in an ever-changing environment and solving them requires more than pure technical knowledge. The same opinion can be true or false depending on the situation. The most common answer to a question is - “It depends”.&lt;/p&gt;

&lt;p&gt;We dive into endless debates on the maturity of technologies, the benefits of different code styles, the best amount of indentation - the list goes on. We still question whether established practices still provide the best value in the current state of software engineering.&lt;/p&gt;

&lt;p&gt;At my first job, a colleague gave me a precious piece of advice - to always ask the question &lt;strong&gt;“why”&lt;/strong&gt;. Recently I started a new job and the tech director there told me something similar - to not be afraid to ask as many questions as possible.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/60aa9f4fdfaf1cdf1961ff23b9a70dfb/1961c/why.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oNVxEHYS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://alexkondov.com/static/60aa9f4fdfaf1cdf1961ff23b9a70dfb/799d3/why.png" alt="Why?" title="Why?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I truly cherish working in a field in which everything is questioned because that’s the only way we can uncover the truth. But what does truth actually mean? Can something be true at all? Maybe the answers I get make sense for the problem we are solving but are completely faulted in a different environment.&lt;/p&gt;

&lt;p&gt;By continuously asking questions and debating different ideas we actually go into philosophical debates. We aim to uncover the final reason of things - the root cause. Of course, sometimes we just try to persuade the other side to believe the same as us but those conversations are not truly debates.&lt;/p&gt;

&lt;p&gt;Sometimes we philosophise about general engineering topics like tabs or spaces. For many of those big picture questions we need to accept an answer for ourselves and form our own reality.&lt;/p&gt;

&lt;p&gt;However there are questions which have less of an impact and therefore can be answered more specifically. Question whose truth only affects our company or our team. One of the commonly asked question is “Why is this done this way?”.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/43a57905ddd2ab6840f31896d8c1b41a/78e1e/winter.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2BwtbaDY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://alexkondov.com/static/43a57905ddd2ab6840f31896d8c1b41a/799d3/winter.png" alt="It all started..." title="It all started..."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We aim to challenge ideas and seek wisdom rather than solve engineering problems. Once the question becomes technical then solving it is easier. Reaching that point is hard.&lt;/p&gt;

&lt;p&gt;Instead of trying to find the answers ourselves should we just rely on already established opinions? When is a problem too specific for its solution to be decided by common knowledge?&lt;/p&gt;

&lt;p&gt;When asking philosophical questions we aim to challenge the beliefs, thoughts and feelings for a specific topic. So when someone asks about the philosophy of functional programming this is the sort of things they have in mind.&lt;/p&gt;

&lt;p&gt;Software engineering is a relatively new field and many truths about it are yet to be formed as a system. But we can’t spend our time arguing about what is right or wrong. In the end of the day we’ll have to make a few hard decisions and do our best to build a good software product.&lt;/p&gt;

&lt;p&gt;&lt;a href="///static/73afec396c6cfe28b9996ae7a34d4d5b/65b75/sprint.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D6tmg0oL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://alexkondov.com/static/73afec396c6cfe28b9996ae7a34d4d5b/799d3/sprint.png" alt="We'd like to spend the next sprint arguing" title="We'd like to spend the next sprint arguing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But how much context, opinions and thoughts do we want to exchange before we do that? This is another difficult question on its own.&lt;/p&gt;

&lt;p&gt;This article asks more questions than it gives answers to. I suppose this is the way with every deep discussion. You recursively ask the question “why” until you hit the bottom and the function returns.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;I am writing a series of articles that dele into the philosophical topics of software engineering. I will look at each one from different angles and try to find the root cause behind them. Here are a few examples that I have in the backlog:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What’s better - tabs or spaces?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;When can technical debt be good?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What code do we consider clean?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Join the Newsletter
&lt;/h2&gt;

&lt;p&gt;If this is something that you find interesting you can join my &lt;strong&gt;&lt;a href="https://buttondown.email/kondov"&gt;newsletter&lt;/a&gt;&lt;/strong&gt; to be notified when a new article gets published.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://alexkondov.com/the-pholosophy-of-software-development/"&gt;my blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>career</category>
      <category>philosophy</category>
    </item>
    <item>
      <title>My 2019 Year in Review</title>
      <dc:creator>Alex Kondov</dc:creator>
      <pubDate>Mon, 30 Dec 2019 00:00:00 +0000</pubDate>
      <link>https://forem.com/alexkondov/my-2019-year-in-review-9ih</link>
      <guid>https://forem.com/alexkondov/my-2019-year-in-review-9ih</guid>
      <description>&lt;p&gt;When I sat down in January I had quite the ambitious goals of where I want to be personally, professionally and spiritually in December. Looking back at them I could've gone a little lighter on the to-do list. I'm not fully satisfied with how the past 12 months went but I try to look at every failure as an opportunity to learn. This year brought me a lot of knowledge the hard way.&lt;/p&gt;

&lt;h2&gt;
  
  
  What went well
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Moved away from pure UI engineering
&lt;/h4&gt;

&lt;p&gt;I'm a big fan of front-end development and I have a soft spot when it comes to working on UIs. However, my new job moved me away from a purely UI role and more into a generalist position. I was a bit worried whether that would be the kind of work that I enjoy but in the end the decision paid off.&lt;/p&gt;

&lt;p&gt;I managed to expand my knowledge of software engineering by diving in topics like distributed systems (Microservices), infrastructure (Kubernetes, CI/CD) and cloud technologies (AWS). There were some days in which my brain was so smashed from taking in information that all I could do was go home and stare at the wall.&lt;/p&gt;

&lt;h4&gt;
  
  
  Reading
&lt;/h4&gt;

&lt;p&gt;I managed to read some really good books that changed the way I see the world - &lt;a href="https://www.goodreads.com/book/show/662.Atlas_Shrugged"&gt;Atlas Shrugged&lt;/a&gt; and &lt;a href="https://www.goodreads.com/book/show/36576608-flowers-for-algernon"&gt;Flowers for Algernon&lt;/a&gt; were the two most impactful. &lt;a href="https://www.goodreads.com/book/show/34536488-principles"&gt;Principles by Ray Dalio&lt;/a&gt; provided valuable insights when it comes to creating a successful company culture and making decisions beyond your intuition. I read a whole bunch of technical books - &lt;a href="https://www.goodreads.com/book/show/17985198-high-performance-browser-networking"&gt;High Performance Browser Networking&lt;/a&gt; and &lt;a href="https://www.goodreads.com/book/show/15499449-game-programming-patterns"&gt;Game Programming Patterns&lt;/a&gt; stand out. I stopped reading The Wheel of Time 5 books in - I understand why everyone loves the series but it just wasn’t my story.&lt;/p&gt;

&lt;h4&gt;
  
  
  Self Development
&lt;/h4&gt;

&lt;p&gt;I started training early in the morning on an empty stomach and felt a significant difference. When I go to the office I've already done something for myself and feel more energised and confident. The fact that I've done something beneficial in the early hours of the day gives me a small win that sets the mood for the rest of the day.&lt;/p&gt;

&lt;p&gt;I'm spending more time with friends and close people establishing meaningful relationships. Last but not least - I started journaling and writing short essays. Most of what I've written probably won't see the light of day but improving your writing pays off well in the long term.&lt;/p&gt;

&lt;h2&gt;
  
  
  What didn't go well
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Lack of Focus
&lt;/h4&gt;

&lt;p&gt;As my little sister told me: &lt;strong&gt;"You've got good ideas but you don't stick to them"&lt;/strong&gt;. Throughout the year I started multiple side projects and materialised ideas but I didn't stick to them. I started my personal blog at the beginning of the year with the hope of publishing an article every week but that didn't come to fruition. I was working on a podcast that got abandoned. I made a couple of YouTube videos and didn't continue with my vlogging career.&lt;/p&gt;

&lt;p&gt;I was trying to work on many things at once and in the end I didn't produce significant results in neither of them. I learned that I'm easily distracted by new opportunities and don't take the time to fully explore what I'm doing at the moment. Nothing brings results without going into depth and putting in the time and work required. If I try to focus on everything I focus on nothing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson learned&lt;/strong&gt; - Pick one focus area and leave everything else on the sidelines. Stick to it for at least an year to see results. For me this is writing.&lt;/p&gt;

&lt;h4&gt;
  
  
  Didn't complete a side project
&lt;/h4&gt;

&lt;p&gt;I had multiple ideas for side projects at the start of 2019. Sadly, those goals didn’t come to fruition. When I was writing an app I fell into the trap of working on tooling and infrastructure rather than the actual business logic. I spent a couple of months over-engineering the setup in which I wanted to write the project but in the end it was so convoluted that I had no desire to do anything in it.&lt;/p&gt;

&lt;p&gt;I picked new technologies that I didn’t know well with the idea of learning them. This was a bad decision because I wasn’t productive and I spent valuable time on reading documentation and GitHub issues as well as resolving problems. When you are on the bleeding edge it’s you that is bleeding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson learned&lt;/strong&gt; - If you plan on shipping pick the boring technology that you know well and are productive with.&lt;/p&gt;

&lt;h4&gt;
  
  
  Procrastination
&lt;/h4&gt;

&lt;p&gt;I’m not a fan of the term procrastination because I believe it’s just a symptom of a different problem. When we are faced with a challenge we have no desire to tackle our mind finds ways to get us distracted. So instead of doing the unpleasant activity we watch a YouTube video, browse social media or clean our desk. I’ve taken up reading and watching self development content as a form of procrastination whenever I have to do something I’m not excited about.&lt;/p&gt;

&lt;p&gt;It took me some time to realise it because I felt like I was doing something useful for myself. However, I was just postponing my actual work by tricking my brain that this is still something beneficial for me. The bad thing about binging self development material is that we can reap the rewards only if we apply the mentioned principles. We don’t gain much just by reading about insights and useful practices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson learned&lt;/strong&gt; - Don’t use self development material as a procrastination mechanism and create more than I consume&lt;/p&gt;

&lt;h2&gt;
  
  
  My plans for 2020
&lt;/h2&gt;

&lt;p&gt;My theme for the the next 12 months will be about going &lt;strong&gt;back to basics&lt;/strong&gt;. I intend on writing more, sharing my work, meeting with new people and creating meaningful relationships. I usually take the first days of the new year to formulate my goals and intentions. This year I plan on sharing them somewhere on the blog so they can be public.&lt;/p&gt;

&lt;p&gt;I plan on starting a podcast about the intersection of programming and philosophy. It’s going to be called &lt;strong&gt;Code Philosophy&lt;/strong&gt; and I’m working on it right now. The plan is to create 10 episodes in 2020 that will dig deeper into software engineering topics. The more we ask the question “why” the better we understand. The better we understand the wiser we become.&lt;/p&gt;

&lt;p&gt;Engineering is a logical and practical field but often there is no &lt;strong&gt;right&lt;/strong&gt; answer or solution. Those are the most important yet difficult decisions that we have to make. In the podcast we will try to broaden our perspectives, get more context and understand the philosophy behind modern software engineering. I’ll keep you up to date in the &lt;a href="http://buttondown.email/kondov"&gt;newsletter&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank you for being a reader
&lt;/h2&gt;

&lt;p&gt;At the time of this writing there are around 400 people subscribed to the newsletter and some that read the blog silently. I’ve had the chance to talk with some of you and am looking forward to getting to know the rest. Thank you for reading my articles and you are welcome to reach out on &lt;a href="https://www.linkedin.com/in/alexander-kondov-2a8b25a9/"&gt;LinkedIn&lt;/a&gt; or &lt;a href="https://twitter.com/alexanderkondov"&gt;Twitter&lt;/a&gt; (even though I’m not that active there).&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>To UI Engineering and Back Again</title>
      <dc:creator>Alex Kondov</dc:creator>
      <pubDate>Mon, 07 Oct 2019 00:00:00 +0000</pubDate>
      <link>https://forem.com/alexkondov/to-ui-engineering-and-back-again-2n1m</link>
      <guid>https://forem.com/alexkondov/to-ui-engineering-and-back-again-2n1m</guid>
      <description>&lt;p&gt;This is going to be one of those &lt;em&gt;once upon a time&lt;/em&gt; articles so buckle up and prepare for a story.&lt;/p&gt;

&lt;p&gt;When I wrote my first lines of code I wasn’t quite convinced that I would be able to do that for a living. For me it was something that people with extraordinary math and logical abilities could handle. Nevertheless I pressed on. I went through a &lt;strong&gt;bootcamp&lt;/strong&gt;, got some projects in my &lt;strong&gt;portfolio&lt;/strong&gt; and managed to land an &lt;strong&gt;internship&lt;/strong&gt; at a small digital agency.&lt;/p&gt;

&lt;p&gt;At this point I found everything in the software world amazing so I was more than eager to face any challenge that came my way. However, nothing grabbed my interest as much as &lt;strong&gt;AJAX&lt;/strong&gt; and &lt;strong&gt;Single Page Applications&lt;/strong&gt; did. This was way back when the first version of Angular (AngularJS) was the framework to use. This tool revealed the true power of the web to me.&lt;/p&gt;

&lt;h2&gt;
  
  
  To UI Engineering...
&lt;/h2&gt;

&lt;p&gt;Back then I worked mainly with back-end technologies but I held a soft spot for JavaScript and crafting dynamic UIs. I loved that I was able to see a more &lt;strong&gt;visual result&lt;/strong&gt; of my work.&lt;/p&gt;

&lt;p&gt;I could create shapes, forms, animations and interactions with code. The ability to add and remove &lt;strong&gt;elements&lt;/strong&gt; from the DOM &lt;strong&gt;dynamically&lt;/strong&gt;, to send and receive data in real-time based on user input - it blew me away.&lt;/p&gt;

&lt;p&gt;I realised that I had the power in my hands to create a fully &lt;strong&gt;immersive&lt;/strong&gt; experience for the people that use my applications. To leave them with a good feeling after they close the browser tab. So at the end of 2017 I realised that I wanted to work full-time with &lt;strong&gt;JavaScript&lt;/strong&gt; and &lt;strong&gt;React&lt;/strong&gt;. I wanted to focus entirely on UIs.&lt;/p&gt;

&lt;p&gt;Ever since I started programming professionally I’ve loved the connection with the people on the receiving end of the product. I love to see how they use the tool, how they interact with it. I enjoyed getting feedback and discovering new ways to make the product even better. We have certain constraints put on us so we need to do everything we can with the options that we have available to provide good UX.&lt;/p&gt;

&lt;p&gt;The rapid development of JavaScript technologies arms us with the best tools to create complex real-time applications that seemed unsustainable a few years ago. The big technological companies are investing quite a lot in the evolution of the UI tools as well.&lt;/p&gt;

&lt;p&gt;But "&lt;em&gt;With great power comes great responsibility&lt;/em&gt;" - as uncle Ben says. This complexity introduces a lot of potential problems which we need to deeply consider when building rich front-end applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenges of UI Engineering
&lt;/h2&gt;

&lt;p&gt;Being an UI engineer comes with its own set of problems. Working on the first thing that the user sees about a product means that you don't have much room for mistakes. Your work is what the users interact with. Even though they are using the whole technical stack under the hood - the UI is the &lt;strong&gt;gateway&lt;/strong&gt; through which they are doing it. Let's discuss some of the challenges that UI engineers face.&lt;/p&gt;

&lt;h3&gt;
  
  
  It's Not Just About Style
&lt;/h3&gt;

&lt;p&gt;Yes, working on the UI you need to have an understanding of what looks good and what doesn't. However, having a pretty interface doesn't make it usable. It's not just about having the proper colours, animations and shades but about providing consistency and intuitiveness. &lt;/p&gt;

&lt;p&gt;Don't take me wrong - it's important for a product to please the eye. But it's critical for it to be intuitive first and use styling only as a way to make it even better. There are numerous applications that look stunning but are hard to use because the creators paid more attention to looks rather than usability. As UI engineers we don't want to be in this boat.&lt;/p&gt;

&lt;p&gt;We need to provide a seamless and consistent user experience. Every person that uses our product goes through a subconscious phase of exploration. The way that we position elements on the screen teaches the user what they can expect. In other words - if we put a primary button on the right we need to stick to that decision throughout the app. We can't change our design philosophy every month because that frustrates the users.&lt;/p&gt;

&lt;h3&gt;
  
  
  Give Feedback to the User
&lt;/h3&gt;

&lt;p&gt;We touched on that in the previous point but it's important to reiterate on how critical giving proper feedback is. Often times our products work in unreliable conditions. We need to send and receive data across the network which opens a lot of possibilities for something to fail. Now the user doesn't have to know about everything that is going. They need to know whether their action is successful or not and if they have to do anything about it.&lt;/p&gt;

&lt;p&gt;When things work as expected and the status is green then subtle marks are okay. The real problems are when something fails. I find that sending a generic message in the lines of "Ops, something failed!" is a really bad thing to do. The user can't know if it's because of their input, because of the network or a failure on our side. So more specific messages with a call to action to the user are clearer - "Looks like our servers are getting hammered. Could you please send this request again in a couple of minutes?".&lt;/p&gt;

&lt;p&gt;If they do some action which takes time because it goes on a queue or something it's worth to keep track of it and give feedback about the progress. If they expect to see something on the page but instead it is empty they would most likely try submitting again and queue another action. It's better to signal that their request is still being processed.&lt;/p&gt;

&lt;p&gt;Also as UI Engineers we can bend time and space a bit. We can show data in the UI before it is actually persisted in the storage or do changes that we expect to eventually become consistent. With tools like &lt;strong&gt;Redux&lt;/strong&gt; it's easy to keep track of what action we're handling and do some UX shenanigans to make our app seem faster - optimistic updates, loading screens, transitions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Guiding the Experience
&lt;/h3&gt;

&lt;p&gt;We need to guide our users through the different actions that they can take. We can't just put a giant form in front of the user - we need to make the process interactive, enjoyable and safe. The users know what they want to achieve but if they haven't interacted with your product they are probably not sure how to do it. By styling the UI and using certain layouts we can guide them to what action they should take. Having a lot of elements on the screen leads to noise so we can blur or darken the rest of the UI when the user is focusing on something important.&lt;/p&gt;

&lt;p&gt;Let's get back to the form for a second. Maybe we can split it in multiple steps that get stored in local storage in case they leave the site halfway through. Putting a progress bar shows the person how far in the process they are and lets them know long it will take. We can also give them immediate feedback when they are filling the fields so they know that the data they've put is valid. We can prompt them when they are closing the tab to make sure that they don't close the app on accident. Those are just some simple considerations - in reality it depends a lot on the aim of the product and the audience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Consistency
&lt;/h3&gt;

&lt;p&gt;Most applications are about some form of data presentation - text, images or something else. It's critical to provide consistency when someone is reading or updating the data that they are storing with us. Imagine updating some record, then going to another screen and seeing old data. This is quite tricky because it depends on components that are not in the UI layer. Maybe the user's request is stuck in a queue (again) or for some other reason hasn't been processed yet. &lt;/p&gt;

&lt;p&gt;Imagine that you update your profile image and open a list of posts that displays your name and photo. Shockingly it still shows your old profile picture even though you updated it. As a developer you're not immediately worried because you know that the app may use a third party service for them. As a user you most likely let out a four-letter word and go back to update the image again. With modern tools it's quite easy to keep track of state in the UI. We can bend time a little and add the new image to it before we get confirmation that it is stored.&lt;/p&gt;

&lt;p&gt;Again - data consistency is a challenging problem in distributed systems as a whole and it's deffinitely not up to UI engineers to solve it. However we can still go the extra mile for the sake of UX.&lt;/p&gt;

&lt;h2&gt;
  
  
  ... and Back Again
&lt;/h2&gt;

&lt;p&gt;I truly love working on the front-end because I feel that my work provides immediate value for the users. Dan Abramov also has a really good article on the &lt;a href="https://overreacted.io/the-elements-of-ui-engineering/"&gt;Elements of UI Engineering&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But as time went on I understood that while the UI was the closest part of the application to the user, this didn’t mean that the other pieces in the puzzle produced less value. If the interface creates the main part of the user’s impression no program can be complete if a single piece is not working properly.&lt;/p&gt;

&lt;p&gt;I decided to take everything I’ve learned so far in the software industry and all the product knowledge I’ve acquired while working for startups and once again move to a more full-stack role. A position in which I’d be able to touch multiple parts of the stack at once and make sure that our users get the best experience possible.&lt;/p&gt;

&lt;p&gt;While I still hold affinity for polished user interfaces, I now deeply admire &lt;strong&gt;well designed&lt;/strong&gt; distributed systems. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highly Available&lt;/strong&gt; services that make sure that even if there is a missing piece from the picture our users will still be able to reach their data. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Secure&lt;/strong&gt; systems that protect the users from harming themselves. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scalable&lt;/strong&gt; products that can seamlessly scale and potentially serve millions of people without breaking a sweat.&lt;/p&gt;

&lt;p&gt;A good UI is &lt;strong&gt;just the start&lt;/strong&gt;. In order to create a truly amazing product you need to apply the same principles and responsibilities all across the stack. The whole organisation, every team should look at their work this way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Join My Newsletter
&lt;/h2&gt;

&lt;p&gt;I'm running a small &lt;a href="https://buttondown.email/kondov"&gt;newsletter&lt;/a&gt;. Join 300+ others to get my thoughts and musings on software engineering and philosophy every now and then. No news, tutorials, ads or spam.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How Good is TypeScript?</title>
      <dc:creator>Alex Kondov</dc:creator>
      <pubDate>Thu, 05 Sep 2019 00:00:00 +0000</pubDate>
      <link>https://forem.com/alexkondov/how-good-is-typescript-48c3</link>
      <guid>https://forem.com/alexkondov/how-good-is-typescript-48c3</guid>
      <description>&lt;p&gt;You may be asking yourself if using TypeScript for a project is a worthwhile investment of your time. The hype around it is high - frameworks and tools are supporting it and companies are adopting it.&lt;/p&gt;

&lt;p&gt;I've been using TS on and off since the second generation of Angular came out and nowadays I write more TypeScript than regular JavaScript. It is currently the best choice for large codebases and I'm saying that even though I started as a sceptic.&lt;/p&gt;

&lt;p&gt;With that said, TS is no silver bullet. You shouldn't mindlessly use it everywhere. It's learning curve can be steep for developers with no background in statically typed languages. Its biggest wins are only felt with time and you still need to be disciplined.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So let's see how good TypeScript actually is.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tipping Point
&lt;/h2&gt;

&lt;p&gt;Each new technology brings new bugs and problems to your codebase. TypeScript is not exception to that. While developers on social media preach the benefits of static types - your experience may differ.&lt;/p&gt;

&lt;p&gt;Especially at first, TypeScript makes you go slower and you don't see immediate value from it. It's hard to justify the decrease in development speed.&lt;/p&gt;

&lt;p&gt;You need to explicitly check variables for missing values and the aesthetics level of your code drops.&lt;/p&gt;

&lt;p&gt;You find yourself trying to write the correct generic for a &lt;strong&gt;reduce&lt;/strong&gt; call for an hour and you get frustrated. Instead of doing &lt;strong&gt;actual&lt;/strong&gt; work - you end up writing types for trivial problems.&lt;/p&gt;

&lt;p&gt;For people like me who are not used to working in a strictly typed language it will feel like trying to run in knee-deep water. You are doing your best but the environment around you is not letting you go faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Also it looks awkward.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the moment that some developers are put off by TypeScript. I like to call it the tipping point. You rename your files back to &lt;strong&gt;.js&lt;/strong&gt; and delete any interface in sight.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give it Some Time
&lt;/h2&gt;

&lt;p&gt;Writing TypeScript should be looked at as a long term investment. You can only feel the benefits as time goes.&lt;/p&gt;

&lt;p&gt;At first you will spend some extra time on writing down interfaces and extra checks. It's not the most pleasant activity in software development. Especially for a JavaScript purist.&lt;/p&gt;

&lt;p&gt;Checks are not &lt;strong&gt;stylish&lt;/strong&gt;. Generics feel &lt;strong&gt;awkward&lt;/strong&gt;. Error messages could be more &lt;strong&gt;descriptive&lt;/strong&gt;. If you are looking for quick wins and productivity - yes, TypeScript may not be the best choice for you.&lt;/p&gt;

&lt;p&gt;But if you are planning to work on the same codebase for more than a few months - that invested time will start paying off when you are returning to that code.&lt;/p&gt;

&lt;p&gt;It's hard to remember project-specific utility functions and data structures. You won't need to remember them with TS because your editor's intellisense will remind you.&lt;/p&gt;

&lt;p&gt;As you are going through the first hurdles you need to remember that you are actually writing in a different programming language. Even if it's a superset of JavaScript. Every language has its specifics and takes time to get used to.&lt;/p&gt;

&lt;p&gt;You are usually not starting from scratch either. You decided to add TS to a project and now you've got errors to fix for weeks.&lt;/p&gt;

&lt;p&gt;Figuring out types and interfaces while working in a React codebase is a different game. &lt;strong&gt;Don't beat yourself&lt;/strong&gt; if you are moving slower than expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Does TypeScript Shine?
&lt;/h2&gt;

&lt;p&gt;With that said, let's examine the long term benefits of TypeScript.&lt;/p&gt;

&lt;p&gt;There are countless articles on the benefits of TypeScript and types in general. Safer development, better intellisense and more descriptive code are only scratching the surface. To summarise - &lt;strong&gt;less things to remember&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you are working on a solo project or a module you understand your codebase well. You know the intentions and thought process that lead to the particular state of the codebase.&lt;/p&gt;

&lt;p&gt;But to other people on your team &lt;strong&gt;understand&lt;/strong&gt; those points as well? Are you &lt;strong&gt;sure&lt;/strong&gt; you will remember it if you have to step away for a few months?&lt;/p&gt;

&lt;p&gt;It’s hard to remember the structure of an object which is specific to the domain you are working in. You know what an “Order” looks like. If you create an interface for that entity - every developer that inherits that codebase will know as well.&lt;/p&gt;

&lt;p&gt;Will you be able to recall the structure of the Redux store maintained by the other team? Having intellisense in the editor makes things much easier than using the developer tools in the browser.&lt;/p&gt;

&lt;p&gt;It’s much easier for new team members to understand the codebase, the business and the flow of data.&lt;/p&gt;

&lt;p&gt;Larger projects that consist of many modules or completely separate services are often owned by different teams. If something happens and you need to hop on another team to help, how quickly can you get to speed with what is going on?&lt;/p&gt;

&lt;p&gt;You will step on some gardening equipment as you are finding your way around TS. But after the initial hurdle you will find working with it quite pleasant. Once it becomes a part of your normal flow when writing code it’s hard to deny the benefits it brings.&lt;/p&gt;

&lt;p&gt;But to reap those benefits it’s important to not cut corners. Unless necessary avoid using the “any” keyword. Write down interfaces in the most descriptive possible manner.&lt;/p&gt;

&lt;p&gt;Do not be afraid that your codebase will become more like Java than JavaScript. TS still manages to infer types when possible so you are not required to write them down for every variable and function.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Not to Use TypeScript?
&lt;/h2&gt;

&lt;p&gt;You are probably seeing a pattern in everything that I’ve written down so far. I’m praising TypeScript in terms of project longevity and scalability.&lt;/p&gt;

&lt;p&gt;The benefits and strong sides shine the brightest in larger codebases or long-term projects. Apps that need to be worked on by many different teams gain the most from a readable codebase.&lt;/p&gt;

&lt;p&gt;We need to look at the other side of the coin, though. It’s important to note “again” that TypeScript slows down development a bit. Of course, you need to write slightly more code to achieve the same end result - this is undeniable.&lt;/p&gt;

&lt;p&gt;There is a saying in software development that everything is a trade-off. When using TypeScript we trade a bit of our speed to make sure that the project will be easier to scale and extend in the future.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When development speed is the critical factor, we can sacrifice sustainability to achieve it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I believe that there are situations in which leaving TS on the bench (at least at the beginning) is the correct choice. If the answer to any of the following is yes, then you should probably stick to pure JavaScript for the time being.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the scope/complexity of your project small?&lt;/li&gt;
&lt;li&gt;Is this a one-off project that will not me maintained in the future?&lt;/li&gt;
&lt;li&gt;Are you working on a proof of concept?&lt;/li&gt;
&lt;li&gt;Are you in a startup that aims to go to market as soon as possible?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For those cases, gaining speed in exchange for sustainability is a good trade-off (at least in my eyes). There is no need to spend extra time on something that will be long forgotten in a few months.&lt;/p&gt;

&lt;p&gt;Yet, if the situation changes and you need to do further work on that project - look into TypeScript. Adding it now will be much easier than convincing the stakeholders to give you more time in the future.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For Lambda functions whose nature is to be small, stateless and self-contained - I use good old JavaScript.&lt;/li&gt;
&lt;li&gt;For React applications that use Redux and have complex components - I resort to TypeScript.&lt;/li&gt;
&lt;li&gt;For Express services I would still pick TypeScript because I feel confident in that choice. I could see the argument for JS if the scope is small, though.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All things said, as you gain experience with TypeScript it may become an irreplaceable part of your toolset. If you and your team members are confident with it you may end up using it everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maturity
&lt;/h2&gt;

&lt;p&gt;The first time I tried TypeScript was in late 2016 when the community around it was not that large. The adoption wasn't that high and integrating it with tools different than Angular was quite the hassle.&lt;/p&gt;

&lt;p&gt;At the time I felt that working with TS was a zero-sum game - benefits and time costs canceled each other out.&lt;/p&gt;

&lt;p&gt;At the time of this writing you could say that the TypeScript ecosystem is mature. Libraries now ship with types. Integration with tools is quite easy. The community is larger, so you can find learning resources or help when you encounter a problem.&lt;/p&gt;

&lt;p&gt;There are frameworks entirely based on TypeScript and others that come with first class support for it. Upgrading to TS with some tools is a simple as renaming the file.&lt;/p&gt;

&lt;p&gt;The team is pushing many releases per month and if Twitter is a reliable source - adoption of TypeScript across organisations is high!&lt;/p&gt;

&lt;h2&gt;
  
  
  One Advice to Get Started
&lt;/h2&gt;

&lt;p&gt;Never use &lt;strong&gt;any&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you are not familiar with TypeScript - &lt;strong&gt;any&lt;/strong&gt; is the master keyword to bypass any restriction that the language opposes on you. You should avoid using it at all cost.&lt;/p&gt;

&lt;p&gt;Using this keyword is an escape mechanism whenever you don't feel like writing a generic or tracing a type. You can jam it anywhere where &lt;strong&gt;tslint&lt;/strong&gt; is having a problem with you and you're good to go.&lt;/p&gt;

&lt;p&gt;This beats the purpose of using TypeScript in the first place. You bypass TS and you get no benefit from the type system. So the only thing you did was writing a few extra symbols and clutter our code.&lt;/p&gt;

&lt;p&gt;In some situations it's necessary - maybe a library hasn't updated its types. But unless that is the case, avoid using it at all cost.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;TypeScript is a good long term investment.&lt;/li&gt;
&lt;li&gt;You will take a productivity hit at first - that's OK.&lt;/li&gt;
&lt;li&gt;If you are working on a large project it's worth to take an initial productivity hit. You'll gain advantage in scalability and sustainability.&lt;/li&gt;
&lt;li&gt;For smaller apps - unless you and your team members are confident with your TS skills, you may be better of sticking to JS.&lt;/li&gt;
&lt;li&gt;The community around TypeScript is quite strong and growing.&lt;/li&gt;
&lt;li&gt;Don't use &lt;strong&gt;any&lt;/strong&gt; , unless absolutely necessary. You put in extra characters and get no benefit from TypeScript in return.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>How to Structure Express Applications</title>
      <dc:creator>Alex Kondov</dc:creator>
      <pubDate>Mon, 06 May 2019 00:00:00 +0000</pubDate>
      <link>https://forem.com/alexkondov/how-to-structure-express-applications-3o8j</link>
      <guid>https://forem.com/alexkondov/how-to-structure-express-applications-3o8j</guid>
      <description>&lt;p&gt;When I started my first job I worked with PHP. We built WordPress projects - sites, ecommerce and the occasional plugin. After I did that for some time I had the chance to jump on a Laravel project and the difference in architecture, structure and conventions fascinated me.&lt;/p&gt;

&lt;p&gt;Frameworks like Laravel can get you spoiled, because they do a lot of things under the hood for you. Pre-built mechanisms implement most of the things you'd need in an application so you can focus on the business logic. Such opinionated frameworks make your life easier by "holding your hand".&lt;/p&gt;

&lt;p&gt;And then I got to work on an Express project. For those that don't know, Express is a minimalistic Node.js web application framework. My first encounter with it after working with Laravel left me culture shocked.&lt;/p&gt;

&lt;p&gt;Some frameworks come with a pre-designed folder structure and guides to understand them better. Express on the other hand comes with 6 lines in an empty JavaScript file. The tool gives you the freedom to include only what you want in your project.&lt;/p&gt;

&lt;p&gt;There are many libraries that you can piece up together to suit your needs. Github hosts countless Express scaffolding projects that come pre-configured. However, the question about The Right Way™ to structure an app was still bothering me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure by Technical Role
&lt;/h2&gt;

&lt;p&gt;Since Express is a minimalistic tool it doesn't come batteries included. Many examples take the MVC approach and structure apps by technical role. This means separating controllers, models, views, tests and other utilities in separate folders.&lt;/p&gt;

&lt;p&gt;Especially for smaller applications this is an excellent approach. It makes it easy to find to find your way around a project. For example, if you need to debug a certain route handler you know that you need to look in the controllers.&lt;/p&gt;

&lt;p&gt;Where this grows short is when you are dealing with a larger app. A project with more complex business logic also imposes a challenge. Sticking to the traditional architecture makes it hard to understand the domain that it represents.&lt;/p&gt;

&lt;p&gt;Folders get bloated, the count of models rises and proper encapsulation becomes harder. A newcomer to the project would find it hard to change code since he won't be sure what parts of the app it can affect. People working on different features may have to modify the same utility functions.&lt;/p&gt;

&lt;p&gt;At one point, the sensible thing to do is to further split folders by domain. We can move all controllers that contain product specific logic in a subfolder. Then we can do the same for models, views and other utilities. Afterwards, we need to make sure that these new "modules" do not depend tightly on each other.&lt;/p&gt;

&lt;p&gt;This will slowly evolve into the structure that we will discuss bellow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure by Components
&lt;/h2&gt;

&lt;p&gt;There are at least two ways to structure any application. One is by grouping files by their technical role. The other is by splitting them depending on the part of the &lt;strong&gt;domain&lt;/strong&gt; that they serve.&lt;/p&gt;

&lt;p&gt;An application's domain is the area of expertise in which it works. Put in simpler words - the real-life problem that it solves. If you are building an accounting app articles probably won't be a part of your domain. Invoices on the other hand will.&lt;/p&gt;

&lt;p&gt;I'm becoming more and more fond of domain-centric application structure. We will no longer need top level folders for controllers, models and views. Instead of that we will group them by domain - users, comments, products. Each of those folders will contain all controllers, models and utilities for that &lt;strong&gt;particular part&lt;/strong&gt; of the app.&lt;/p&gt;

&lt;p&gt;Most of the time we won't be working on many parts of an application at once. Modularizing a project in components makes it easy to work in isolation. This structure gives us confidence that everything related to a part of the domain is in the same place.&lt;/p&gt;

&lt;p&gt;Personally, I'm fond of this structure because it gives a good bird's eye view of the project. You can easily tell what it is about and what components it consists of.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Does Your Architecture Scream?
&lt;/h2&gt;

&lt;p&gt;Earlier this year I finally decided to read &lt;a href="https://www.goodreads.com/book/show/18043011-clean-architecture"&gt;Clean Architecture&lt;/a&gt;. I wanted to get a better understanding of the core principles behind designing applications. A particular quote from the book stood out to me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So what does the architecture of your application scream? When you look at the top level directory structure, and the source files in the highest level package; do they scream: &lt;strong&gt;Health Care System&lt;/strong&gt; , or &lt;strong&gt;Accounting System&lt;/strong&gt; , or &lt;strong&gt;Inventory Management System&lt;/strong&gt;? Or do they scream: &lt;strong&gt;Rails&lt;/strong&gt; , or &lt;strong&gt;Spring/Hibernate&lt;/strong&gt; , or &lt;strong&gt;ASP&lt;/strong&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The idea of grouping code by business logic is covered in the book &lt;a href="https://www.goodreads.com/book/show/179133.Domain_Driven_Design?ac=1&amp;amp;from_search=true"&gt;Domain-Driven Design&lt;/a&gt;. It emphasizes on the idea that applications used in different domains should not be designed the same.&lt;/p&gt;

&lt;p&gt;An app that operates in the financial industry and one that operates in the medical one should be structured differently. The differences in how their domains operate should be visible in the codebase.&lt;/p&gt;

&lt;p&gt;We need to structure depending on the real-world problems that our software solves. Every business domain faces different challenges, thus we shouldn't design applications the same.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://www.goodreads.com/book/show/22512931-building-microservices?ac=1&amp;amp;from_search=true"&gt;Building Microservices&lt;/a&gt; we can find similar ideas. The author talks about finding the boundaries (seams) in our application. The places where we can split our project in smaller modules.&lt;/p&gt;

&lt;p&gt;Structuring our project early makes it easy to split it in microservices in the future if we have to.&lt;/p&gt;

&lt;p&gt;I've been using the same approach in React applications as well. Instead of grouping all components together I place them in modules. Each module contains all components, state management and utilities that relate to it.&lt;/p&gt;

&lt;p&gt;When you are looking in a module you should be confident that everything you need is there.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Express apps give us the liberty to chose our own app structure. Thiscan be overwhelming for beginners or people that have worked on an MVC framework.&lt;/li&gt;
&lt;li&gt;Splitting the app in technological related parts is the most intuitive approach. While there is nothing wrong with that, it can be hard to manage, grow and modify if the app grows or it's of higher complexity.&lt;/li&gt;
&lt;li&gt;Structuring the app in component related to the part of the domain is a better approach. We encapsulate the different pieces of the app making it easier to build services in the future.&lt;/li&gt;
&lt;li&gt;The component architecture helps the developers get a better grasp of how the app works and the building blocks of which it consists.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>express</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
