DEV Community

Cover image for Deconstructing popular developer dogmas #1
daniel-octomind
daniel-octomind

Posted on • Originally published at octomind.dev

Deconstructing popular developer dogmas #1

dogmatism

noun, dog·​ma·​tismˈdȯg-mə-ˌti-zəm
1: the expression of an opinion or belief as if it were a fact: positiveness in assertion of opinion especially when unwarranted or arrogant
2: a viewpoint or system of ideas based on insufficiently examined premises

~ Merriam Webster

Just like everywhere in today’s society, it seems that opinions and debates in software engineering have gotten more extreme and absolute lately. The adoption of the term ‘opinionated’ into marketing lingo when describing dev tools is telling.

Take the example of the frankly ridiculous but hilarious fight between DHH's ’hate’ for typescript and the community’s and Theo’s backlash. Or the neverending row between unit test absolutists vs. unit test deniers. The singleton shamers! While I think everyone here has a point, I also think that nuances in software engineering often get overlooked.

I want to share some examples from my own experience to refocus our overton window a little. Let’s go back to building the right solutions for the right problems instead of bashing our heads over what design pattern is the absolute truth.

Let’s start with a popular one.

Singletons are always 100% bad

To say singleton patterns in software development are controversial is a bit of an understatement. Diving into the topic you’ll learn that singletons suck and they are the root of all evil. But are they?

Consider the following controllers in a node.js typescript application:

class SomeControllerA {
 private logger: Logger;


 constructor(logger: Logger) {
   this.logger = logger
 }


 public doSomething(): void {
   this.logger.info("doing something");
 }
}


class SomeControllerB {
 private logger: Logger;


 constructor(logger: Logger) {
   this.logger = logger
 }


 public doSomethingElse(): void {
   this.logger.info("doing something else");
 }
}
Enter fullscreen mode Exit fullscreen mode

This clearly looks like dependency injection, often touted as 'best practice'. However, 90% of us would agree that there’s not much point to using it here. The code would be equally good and comprehensible if we used a singleton logger.

import { logger } from './logger';


class SomeControllerA {
 public doSomething(): void {
   logger.info("doing something");
 }
}


class SomeControllerB {
 public doSomethingElse(): void {
   logger.info("doing something else");
 }
}
Enter fullscreen mode Exit fullscreen mode

Naturally, this changes if for some reason the logging was actually different for each controller, maybe they are deployed in different environments or the like. But in my 8 years of developing software I haven’t come across such a case. And you can always change it once you need it.

Singletons are obviously not a pattern in current_year anymore. My point isn’t that you should replace your nice dependency injection with singletons, but that there IS nuance to anything in software.

Granted, logging might be the only valid use case for using the singleton pattern, but that’s maybe worth a blog post on its own ;)

StackOverflow screenshot - singletons

source: StackOverflow

Don’t be dogmatic

When discussing coding best practices, we often forget that they are just that — best practices, not absolutes. There are many variables and business requirements that influence how a particular piece of code or software should be constructed. We shouldn’t dish out absolutes like ‘singletons are always 100% bad’ or ‘typescript is making the code worse to read and write’. I’ll address more of these dogmas in upcoming articles. I’d appreciate your nuanced take on them.

Daniel Draper
Lead Engineer at Octomind

Top comments (0)