8

Oh, abbreviations in code, the bane of every developer.

Consensus seems to be against them, because readability might be affected. But the examples given are often extreme: like "repr" for "represent". I call that extreme, because it is shortening a word not in need of shortening, into something that has a very ambiguous meaning.

Please consider my example as a possible example of when abbreviations may be justified. I've got a project that uses a number of projections, which are basically views on a Mongo-database. To name a projection descriptively, you have to describe the perspective, which takes a few words. And each projection has a number of classes to make it work, each of which have names of their own, suffixed to the projection name.

So, because I have a projection named StatemachineDefinitionRelevantEvents (take my word for it that this is the shortest way to describe the projection), I also have classes named StatemachineDefinitionRelevantEventsAggregrateProjection, StatemachineDefinitionRelevantEventsReadModel, StatemachineDefinitionRelevantEventsRepository. Those are around 50 characters long.

Because vars are also disallowed (company policy), you get code like this:

StatemachineDefinitionRelevantEventsAggregrateProjection statemachineDefinitionRelevantEventsAggregrateProjection = new StatemachineDefinitionRelevantEventsAggregrateProjection(<bunch of parameters with similarly lengthy names>);

Repeated over and over if I need to create several of these classes in a row.

I decided to just replace every instance of StatemachineDefinitionRelevantEvents with SDRE. I'm also clearly noting in my ubiquitous language and documentation that SDRE stands for StatemachineDefinitionRelevantEvents, with an explanation of the projection's definition and purpose. Lo and behold, my initialisations suddenly fit on a single line! And the suffix always remains unabbreviated, so even if you don't know what SDRE means, the function of a SDRERepository, SDREReadModel and SDREAggregrateProjection should be interpretable from the name alone.

Is this an example of justified and 'good' use of abbreviations, or is it still wrong? I want to get a second opinion before I propose it to the team.

2 Answers2

3

First off, the naming of the classes seems odd. Generally, convention is to go from most specific word to least. E.g. AggregateException and FileNotFoundException. In your case they would be (assuming these are the correct order):

AggregrateProjectionStatemachineDefinitionRelevantEvents
ReadModelStatemachineDefinitionRelevantEvents
RepositoryStatemachineDefinitionRelevantEvents

Generally it is recommended to avoid abbreviations. However, this does seem like a particularly extreme case. I'd abbreviate the variable name statemachineDefinitionRelevantEventsAggregrateProjection before the class (not obvious from your question if that's what you're proposing).

It then follows that the shorter name for these could be:

aggregrateProjectionSdre
readModelSdre
repositorySdre

(note: Sdre not SDRE, the same as you may find HtmlContext rather than HTMLContext)

Because vars are also disallowed (company policy), you get code like this:

Blanket banning of a language feature is strange, exactly for reasons like this. You harm the overall readability of the code for the sake of redundant names. Perhaps it would be a better (halfway house) rule to allow var provided the type is on the right side of the statement.

Combining this (and taking care to keep a sensible line length) you'd end up with:

var aggregrateProjectionSdre = 
    new AggregrateProjectionStatemachineDefinitionRelevantEvents(
        <bunch of parameters with similarly lengthy names>,
        <bunch of parameters with similarly lengthy names>,
        ...);

(or sdreAggregrateProjection if I've made a wrong assumption)

You may even get away with omitting Sdre depending on how obvious it is from context.

2

This is the sort of situation where namespaces come in handy. I don't know the C# syntax, but something like:

Statemachine::Definition::RelevantEvents::AggregrateProjection 
Statemachine::Definition::RelevantEvents::ReadModel
Statemachine::Definition::RelevantEvents::Repository

That allows you to have the full context where it's necessary but be less verbose where the context is clear. You could do:

import Statemachine::Definition::RelevantEvents as SDRE
...
SDRE::AggregrateProjection 
SDRE::ReadModel
SDRE::Repository

Or even:

using namespace Statemachine::Definition::RelevantEvents
...
AggregrateProjection 
ReadModel
Repository

People often balk at using statements or aliased imports, because they are bad in a header file that imposes the abbreviation on people in different scopes who may not be familiar with the context, but within a limited scope where it is clear everything in here is working with Statemachine::Definition::RelevantEvents, they remove a lot of the clutter and add a lot of readability.

Karl Bielefeldt
  • 148,830