7

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.

  • 1
    Three downvotes and no comments explaining why... I'm sorry if I insulted you guys? – KeizerHarm Mar 6 at 11:49
  • 1
    I'm a fan of camelCasing or PascalCasing abbreviations in identifiers. In your case, I would name it SdreRepository. sdreRepository = new ...;. I find it easier to read than a bunch of capital letters mashed together. As to whether or not this is good - I think it comes down to whether you and your team can agree on the convention and also the definition of "SDRE." – neilsimp1 Mar 6 at 12:46
  • @neilsimp1 Thanks for the feedback. – KeizerHarm Mar 6 at 14:51
  • The problem with abbreviations usually isn't in recognizing what they're an abbreviation for. It's in remembering how someone abbreviated something. What the heck was that column name? InvNum? InvcNum? InvNo? It's especially bad when it's abbreviated different ways in the same application. – StackOverthrow Mar 6 at 22:45
  • @user560822, I agree. With abbreviations, it's crucial to be consistent in one context, and in general to follow sensible standards or conventions if possible - most words have already been abbreviated in the past. A person should maintain a dictionary of abbreviations. Longhand names are not necessarily solution - an "Invoice Number" could still end up being called an "Invoice Reference", "Invoice Serial", or just "Invoice", and there is only less variability in the spelling because English dictionaries are maintained. – Steve Mar 7 at 10:45
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.

| improve this answer | |
  • "allow var provided the type is on the right side of the statement" Except for silly examples, of course, such as var x = (T)null; (instead of T x = null;), which I saw in production code a few weeks ago. Ideally we should give the type once, but on the left if it's achievable without casting or by implicit casting, whereas it has to be on the right to explicitly cast as in var x = (string)0;. – J.G. May 1 at 16:47
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.

| improve this answer | |
  • Thanks for the feedback. The StatemachineDefinitionRelevantEvents is however basically an import of an externally defined data scheme. You can read the whole name as one word; I'm not doing anything with just statemachines in this particular context. I don't think it lends itself to namespace division well. – KeizerHarm Mar 10 at 15:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.