I would argue the major purpose of design is to reduce the cost of change. Generally developers do not get given a full perfect picture of the product up front, yet they are expected to build it. As the picture becomes clearer to the client over time the developer is going to have to make changes during development and after release. By having a good design this process of constant change becomes easier, but that is easier said than done.

There are always trade offs and often by using design patterns to reduce cost of change you can land up increasing complexity to the point that you increase the cost of change. I find there is a certain level of complexity which is easy enough for developers to work with but them moment you step passed that point and start making the application too complex it hurts the cost of change unintentionally.

"The ultimate goal(of architecture) is to minimize the lifetime cost of the system and to maximize programmer productivity."

-Robert C. Martin

Don't cut corners

What really costs the most in the dev process? (keep in mind "time is money")

  • Writing code
  • Reading code
  • Planning and design

Non-developers would say writing code takes the longest but this is simply not true. Most of a developers time usually goes toward planning and reading code. If you cut down on the design and planning time, sure you save some time when you start but you usually waste that extra time in writing because you dont really know what to do. Then you get hit with increased time spent trying to read the poorly designed code.

Assume Change

Often we think we know exactly how the product should be and that this is the final form of the code, but code does not have a final form and will always need new features and bug fixes. Always ask yourself, "What will need to be done to change this code?". Sometimes you find that a very simple change to your design may make the code far more flexible without any draw backs. You do not need to be a fortune teller to be able to do this, you only need to be well schooled in design principles and patterns, to see when something is off.

What might need to change?

  • Database
  • Communication eg AMQP, REST, SOAP, GRPC, etc.
  • Programming language
  • Third party providers eg emailing service, credit card integration, etc.
  • Business logic
  • Packages eg Hibernate, EntityFramework, Log4Net/Log4j, Bootstrap, etc.
  • Framework eg ASP.Net, Spring, React, Rails, Django, Laravel
  • Infrastructure eg On Prem servers, AWS, Azure, VMs
  • Deployment pipeline eg GitLab, circle Ci, Code Fresh, Jenkins, Octopus, etc.

While you may not be able to be prepared for all of these, it is worth being prepared for the most expected changes.

Make the change ASAP

Consider which phase would be cheaper to make changes?

  • No code - Design and planning
  • Some code - MVP has been released
  • Massive amounts of code - Fully featured application with full integration

Clearly it is easier to make changes when there is less code, therefore the earlier you detect issues the cheaper the change will be. By spending more time in the design and planning phase you are able to pick more issues earlier where the cost of change is lower.

Build simple products and test early to detect any issues you missed during planning. By deferring the major decisions for later and keeping the code as slim as possible you can wait until you know more before making the major decisions. For example, you do not have to actually write to any database but instead your repository can work with an in-memory list, so that you can decide on the db later.

When a system has complex business logic as well as poor design, then it can become very difficult to make any simple changes. Poor design impacts the whole company on an ongoing basis because new features take ten times longer to implement. We can fix a poorly designed system by rewriting it or slowly fixing it piece by piece. If poor design is clearly a problem why does it never get fixed?

  • Developers without enough design knowledge won't make an effort to correct the design.
  • Rewriting the whole system means no new features for awhile, which may hurt the business.
  • When developers are chasing to hit dead lines of new features they often don't get to improve the design and land up just adding to the problem.
  • Broken windows theory: Visible signs of crime, encourages further crime. This leads to mindsets similar to "If the existing code is bad then writing more bad code won't matter".

To get the full picture you need to cover the following topics:

But here is a quick broad summary of some solutions:

Check out these links for more info:

My design and architecture repo