Wait until the last responsible moment to add structure to your Blazor UI

A few years ago I worked for a company with a code base which had "evolved" over many years.

I never quite got to the bottom of how it had happened but the code had deteriorated over time, gradually becoming more and more complicated, and less and less consistent.

By the time I came to work on it the dev team was stuck in a vicious cycle.

The code was so verbose, and poorly structured, that even "small" changes required hours of stepping through various layers of the application to figure out how to make the change.

By the time the dev had found where to make the change, they were so worn down by the process that they'd often just make their small change and get the hell back out of there!

As the sticking plasters piled up, the app got ever harder to maintain, and lead times grew longer and longer.

Software needs structure. Without structure application code deteriorates into a tangled, unmaintainable mess over time.

But structure isn't a silver bullet.

The challenge of structure, layers, and abstractions lies in how it separates you from the reality of the feature you're building.

Once you're thinking about layers, database tables, or building out services, you're thinking in terms of abstractions.

This means you have to understand what you're building and also how that relates to the technical abstractions you've created along the way.

The problem comes when the requirements change, or you realise you didn't have all the information you needed in the first place (or you misunderstood a fundamental piece of the puzzle).

Suddenly you find yourself trying to do two things at once:

  • Understand the change being requested
  • Map that to the technical abstractions which exist in the code (and/or changing those abstractions if they no longer work)

Alas, the human brain doesn't cope very well when faced with multiple, different problems like this.

If we're talking about building a feature, UI and all, our freedom to iterate, tweak and extend the feature is hampered by the need to map it to the (often arbitrary) structure created around this feature.

What's more, building the 'wrong' structure can stop you in your tracks.

In this case, technical decisions by developers who had long since left the company remained in the form of multi-layer behemoths, huge classes, full of mostly procedural code, with arbitrary and inconsistent names.

So how can we avoid this fate and build simpler web applications?

The alternative is to defer building those technical abstractions until the last responsible moment.

No-one can tell you exactly when that moment is, but it's probably later than you think!

Apply it to your own application

The trick is to keep your application malleable, so you can evolve and iterate it without wading through layers of technical abstraction to make "small changes".

For me this is why I tend to start with by building a rudimentary part of the UI...

Sketch out the UI for your app

It's not just about writing some HTML and CSS, but rather a a way to better understand the feature in front of you, to really figure out what you're working with, the feature's purpose, and how it feels to work with in the browser.

I would try to avoid the temptation to break the UI down into separate components too soon.

It's tempting, as parts of the markup start to become duplicated (think multiple cards in a Kanban board for example) to try and remove that duplication.

But early on in the design phase this duplication is entirely manageable, and having all the markup in one place makes it much easier to iterate, and tweak your UI.

One way to think of this is in terms of collecting enough data to inform your decisions about how to structure the code.

Data comes from building the simplest version of your feature, and spotting the patterns that emerge.

Once you have something concrete you can tread lightly and add just enough structure where it feels like i will help to keep your code maintainable, and/or separate concerns if you feel your component is doing too much.

But remember, for every new abstraction you add (repositories, services, managers, helpers) you're adding another layer for future you (or someone else) to understand, evolve, and maintain.

In many cases, less is more.

Practical Blazor Components

New Course - Coming Soon

Get these 'writing in progress' articles delivered straight to your inbox, plus be first to know when the course is available.

I respect your email privacy. Unsubscribe with one click.