Taking “service” out of service – thoughts on the most used misnomer in ASP.NET Core and Angular

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 GetCurrentUser() and 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

Circa 2009 Helper-classes were the laughing-stock in the local dev circuit and nobody wanted to be caught dead writing one. Professionals wrote Helper Utility classes.

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

Circa 2012 Helper Utility-classes were the laughing-stock in the local dev circuit and nobody wanted to be caught dead writing one. Professionals wrote Helper Utility Manager classes.

Why bother determining whether it’s a builder, singleton or command? You don’t need to know fancy programming patterns to write working software!

Today…

The Age of Services

It’s 2016: Helper Utility Manager-classes are the laughing-stock in the local dev circuit and nobody wants to be caught dead writing one. Professionals write Helper Utility Manager 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.

noooooo

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.
E.g. the 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 UserService?
What shouldn’t?
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 UserHelper or UserPotato instead?

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.

2 thoughts on “Taking “service” out of service – thoughts on the most used misnomer in ASP.NET Core and Angular

  1. Good post on an eternal software development problem.
    Just to clarify: The concept Service comes from Domain Driven Design where it is defined as a stateless class which handles an operation not naturally belonging to a entity. The newfound love for services probably comes from the stateless point (which we all love coz static is just soo simple to deal with).
    But what’s equally more important to remember is that a service handles one operation – and that the ubiquitous language is respected. This is why UserService is horrible: what does it do? ‘user()’? This bad naming lends itself to not having a single responsibility (which we all know is bad, right?). Now an ‘IAuthenticateUserService’ wouldn’t be as bad, right?

    • Hi Thomas!

      Thanks for clarifying the origin of the service-pattern, I hadn’t realized (or rather forgotten) that there’s an accurate definition of the term in DDD – I’ve updated the post accordingly.

      My grievance is (as you’ve already hinted) that the “service” implementations I’ve come across either perform a variety of operations which should be split into aptly named subparts, or perform operations for which the term “service” is simply inappropriate as other design patterns already lay claim to said operations; a classic seems to be services doing the work of repositories, particularly in Angular applications (e.g. the HeroService in the current Angular 2 tutorial).

      As stated earlier, my guess as to why this is happening in Angular and ASP.NET Core in particular is that there are built-in “service nomenclatures” in both of these frameworks, i.e. as a quasi base class and as part of the DI terminology.

      I hadn’t considered that it might be a reaction to “statics are bad” as you mention, since JavaScript doesn’t have the concept of statics and I failed to look at the symptoms in isolation per language.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s