A long time ago in an IDE far, far away…
The Age of Helpers
When I started out in the software industry circa 2006, the misnomer of the time was “helper” in the local dev circuit. If you didn’t know where to put a particular piece of code, you would simply add another static method to a
Helper class and be done with it.
These classes had the tendency to grow into maintenance nightmares, sometimes spanning thousands of SLOC. If you were lucky the code was related in some way, but finding both
CalcWorkWeeks() in a class called
DataHelper wasn’t unusual.
Why bother determining whether it’s a strategy, facade or gateway? You don’t need to know fancy programming patterns to write working software!
The Age of Utilities
Helper-classes were the laughing-stock in the local dev circuit and nobody wanted to be caught dead writing one. Professionals wrote
Why bother determining whether it’s a mapper, repository or adapter? You don’t need to know fancy programming patterns to write working software!
The Age of Managers
Utility-classes were the laughing-stock in the local dev circuit and nobody wanted to be caught dead writing one. Professionals wrote
Why bother determining whether it’s a builder, singleton or command? You don’t need to know fancy programming patterns to write working software!
The Age of Services
Manager-classes are the laughing-stock in the local dev circuit and nobody wants to be caught dead writing one. Professionals write
Service-classes. Disambiguation: These are not to be confused with actual DDD services.
Why bother determining whether it’s a factory, decorator, or visitor? You don’t need to know fancy programming patterns to write working software!
Naming things in ASP.NET Core and Angular 1.5.X
About a year ago I switched jobs and started writing SPA’s using ASP.NET Core and Angular 1.5.X.
To my horror I found that most of the code showcased by early ASP.NET Core-adopters and samples of both ASP.NET Core and Angular on e.g. Stack Overflow and Pluralsight was being placed in code elements suffixed with the term “service”, regardless of the underlying code’s responsibilities.
Neither the ASP.NET Core documentation nor the codebase suffer from this fallacy or otherwise promote it, even their code samples use proper naming and software design patterns.
Angular’s stance on the other hand is a bit unclear to me, as they promote proper naming but not necessarily naming based on well-known OOD patterns.
HeroService in the current Angular 2 tutorial is actually a
HeroRepository – it’s an in-memory representation of our domain entities which we use for queries, using HTTP to connect to an underlying data store.
My best guess is that this anti-pattern simply arose because the ASP.NET Core and Angular dependency injection containers often use the term “service” to denote an injectable code element, and don’t make enough of a point about the fact that this doesn’t mean you should suffix every piece of code injected via DI with said term (or any piece of code at all, for that matter).
Why is a “one-size-fits-all” suffix bad?
The mandatory naming things is hard-discussion aside:
Every part of the name should express something about the underlying code element.
Using non-specific names for code elements let’s them bloat, rot and become unmaintanable quicker than you can say “this shit is unmaintanable”. The suffix du jour is simply too broad and carries no well-known meaning in OOP, regardless of whether it’s “utility”, “manager”, “helper” or “service”.
Other devs will end up sticking all sorts of inappropriate things into what might have started out as a virtuous single responsibility class — and you can’t blame them for doing so, as the suffix conveys no meaning.
What logic should be allowed in a class called
Is it okay to place creational logic in it?
What about encapsulating queries or wrapping a complex third-party API?
Would the name lose informational value if you called it
I’ve seen both inexperienced and seasoned developers alike fall into the “utilities pit”. This is somewhat understandable for the inexperienced devs, while there’s no real explanation aside from inaptitude or laziness for the seasoned devs who hop from one “catch-all” suffix to the next every X years and don’t realize (or care?) that they’re writing the same unmaintanable code over and over, simply with a slightly different pronunciation and possibly in a slightly different framework.
What’s a better alternative?
If you find yourself creating or extending classes called “helper”, “service” or whatever the misnomer of the season might be, ask for help: ask a colleague, ask your dev forum of choice or simply take a break to ponder whether there’s a more appropriate name or place for the code you’re about to write.
And, as always, spend time talking, reading, listening, watching and practicing software craftsmanship and software design patterns. It will help your customers, your colleagues and your career.
As the saying goes there’s a time and place for everything, and this is true even for “helpers” — but if half of your business logic is tied up in “XyzHelper/Service/Manager/Utility”, it’s either a failure at exercising OOD, a failure at naming, or both.