Skip to main content

Designing for Likely Change Without Over-engineering

August 17, 2026 Highland Software

One of the most important skills a software developer can develop isn’t writing code.

It’s analysis.

Before writing a single line of code, we should be asking questions.

  • What do the current requirements cover?
  • What don’t they cover?
  • What are the edge cases?
  • What happens if the user enters unexpected data?
  • What happens if someone deliberately tries to break the application?
  • Most importantly… what requirements are likely to change?

Software is constantly evolving.

Today’s “final requirement” often becomes tomorrow’s change request.

Planning Without Over-Engineering

Years ago, I was working on a project when a product manager submitted a ticket for a relatively straightforward enhancement.

As I read through the requirements, I noticed another scenario that wasn’t part of the request but seemed like a logical extension of the feature.

I asked the product manager:

“If this option is ever required in the future, I can build the flexibility into the solution now. It will add about one extra day to this ticket, but it’ll make future changes much easier.”

The response was immediate.

“We have no intention of ever implementing that.”

Fair enough.

I completed the ticket exactly as requested, closed it before the end of the day, and moved on.

Less than three business days later, a new ticket arrived.

The requested feature?

The exact scenario I had raised the previous week.

Unfortunately, because the original implementation had been intentionally simplified, it couldn’t simply be extended. The underlying design didn’t support the new requirement.

Instead of adding a small enhancement, I had to remove part of the previous implementation and rewrite it to support the new behaviour.

The one-day enhancement had become a two-day rewrite.

That experience taught me an important lesson.

Sometimes doing a little more than the minimum today saves a great deal of work tomorrow.

Don’t Build for Every Possibility

This doesn’t mean every application should be engineered to support every imaginable future requirement.

That’s called over-engineering.

Good software balances today’s requirements with reasonable expectations about tomorrow.

The goal isn’t to predict every future feature.

The goal is to avoid painting yourself into a corner.

Avoid Hardcoded Values

One of the simplest ways to make software easier to maintain is to avoid hardcoded values whenever possible.

For example, I recently wrote software that included a seven-day trial period.

Rather than scattering the number throughout the codebase, I defined it once:

const TRIAL_DAYS = 7;

During testing, the business decided that a fourteen-day trial would provide a better user experience.

Because the value existed in one location, changing the trial period was trivial.

I updated a single constant.

If I had hardcoded the value throughout the application, I would have been searching for and updating it in fifteen or more locations.

Not only would that have taken longer, but it would have increased the risk of missing one and introducing inconsistent behaviour.

Design for Change

Software requirements change.

Business priorities change.

Product managers change their minds.

Customers discover new use cases.

Regulations evolve.

None of those things should surprise us.

Our job isn’t to predict the future perfectly.

Our job is to build software that’s flexible enough to accommodate reasonable change without requiring a complete rewrite every time a requirement evolves.

Final Thoughts

Don’t hardcode values that belong in configuration.

Don’t tightly couple components that may evolve independently.

Don’t assume today’s requirements will be tomorrow’s requirements.

Build software that solves today’s problem while remaining flexible enough to handle tomorrow’s.

Because the best software isn’t just correct today.

It’s adaptable tomorrow.

Write code for today’s requirements, but design it so tomorrow’s requirements don’t require tomorrow’s rewrite.

Highland Principle #8: Don’t Hardcode Tomorrow’s Requirements

More From Highland Software