Architecture Made Easy: 4 Simple Ways you can Perfect your Code Design

Bar Zach
Tech at Trax
Published in
5 min readApr 23, 2020
Image by StockSnap from Pixabay

For many years I’ve been working as a software engineer in various roles and companies. Whether I was working on new projects or editing existing ones, a few questions have always come back to mind.
Am I designing the right project architecture? How much time will it take someone to read/refactor my code in the future?
Most senior developers, hopefully, consider the way they architect a code and what they’re going to write about. But because there is no “correct” architecture for a program, many developers aren’t sure how their design will handle future changes.

In this article I’m going to talk about a few simple steps I’ve learnt to create a design that scales over time.

Ask the Right Questions

Taking the time to organise a project before starting, significantly helps us get things done easier. These are my favourite “4-Whats” questions when starting to form a solution:

● What entities do you have?

● What part of the code is breakable over time?

● What are your project’s external dependencies and I/O?

● Last but not least — What could change?

To show the power of these questions, I’ll take a simple coding task of creating an ordering system for restaurants. Meaning, managing the order data from end-to-end.

1. Planning your Entities

Have you seen an entire code written inside “main”? Probably not often. Although this is an obvious ‘code smell’, it doesn’t mean that all other code is considered perfect.

First thought of dividing our implementation into different entities

Using the “high cohesion, low in coupling” concept, we would like to make loose connections between entities. Clients place orders with restaurants. Restaurants have menus, with their own menu items and chefs making them. Each order is packed and sent as a delivery, which the client receives.

2. Finding Breakable Code

Every developer knows that testing is a must, because without it the code may react differently than we expect. But what if we could try and use the test approach while designing? That way we could make a cleaner design by “playing” with our entities before we code.

How do you test a design to find breakable code? I usually try and imagine possible flows of deployment and see what problems I get. One might call it “debugging on paper”.

There are a few issues with this flow, but let’s focus on only one for this example.

Business Flow: “Clients choose menu items and make orders. These orders are placed in a restaurant and passed to the chefs. The chefs make the orders, and when they’re ready they are delivered to the client.”

  • Chefs — Which kind of chefs should receive the order? Could chefs work in different restaurants on the same day?

For that I might introduce two new entities — a “Shift” and an “Employee”

New connections between entities that might otherwise break the code in future
  • Employee (base class) — Having a Chef inherit Employee would help us expand different roles (Pastry Chef, Waiter, etc) as needed. That way we can add chef-specific functionalities.
  • Shift — Chefs might only work part time. This object would match a list of chefs with specific times and restaurants, providing a dynamic way to control the number of chefs needed in each restaurant at a specific time.

3. Packaging External Dependencies and Making APIs

Even though our newer design seems cleaner, we can make tremendous progress by diving into its external parts. I usually ask myself — do I have any particular code that can benefit other projects of mine? Something using any external I/O? Using the example from above, we can try and create packages out of it. There are many examples of packaging and “API-ing” our code, but I’ll focus on these two:

  • Orders — Most of the order information is quite generic to any type of orders. For example — clothes, art, etc. You might create an Order package and use an inherited class to implement the unique data — menu items.
  • Menu items and prices — The data these classes use is placed in a DB, so you can obviously “guard” it from direct queries using some kind of API. That way future changes to the DB are easy, because the data in the DB isn’t coupled with the code itself. Thus, you only need to update the API.
Phase three, creating packages and making APIs

4. What could change?

This last question might seem like a small one at first, but actually it is of the utmost importance to ask. So how can you adopt a futuristic mindset? My favourite strategy is to look down at my program’s UML diagram, and start exploring. In the example I presented above, I’d take each entity in turn and try to rethink it. For example –

Shifts — I implemented it as a list of chefs and a time range, such as “chefs #1, #2 at 14:00 to 16:00”. But what would you do if you needed to split shifts? For example, “chef #1 from 13:00 to 16:00, chef #2 from 14:00 to 15:30 and chef #3 from 15:00 to 17:00”? The employer might not care when the chefs come and go as long as there are X chefs at every time of the day.

For that, we might change the Shift entity to be chef-specific, and add a new class called “Capacity” to handle the number of chefs per hour.

More changes may include:

  • Different prices on menu-items (in different restaurants)
  • Deliveries as external service with API
  • Restaurant service by client location
  • and more

Future Thoughts

The topics we discussed in this post can be considered highly relevant in creating a new service. It seems that similar skills are required in refactoring an existing code that has already been deployed. As services get bigger without the appropriate design, it tends to be harder to maintain over time and make changes. It’s often possible to refactor such code appropriately (a topic that should get its own post), but smartly adapting a futuristic mindset and techniques would save much time and energy.

--

--

Bar Zach
Tech at Trax

Software Engineer @ Trax | Languages, skiing, software craftsmanship enthusiastic- “Quality isn’t expensive, it’s priceless”.