Skip to main content

Command Palette

Search for a command to run...

Code Smell 122 - Primitive Obsession

Objects are there for the picking. Even the smallest ones.

Published
2 min read
Code Smell 122 - Primitive Obsession
M

I’m a senior software engineer loving clean code, and declarative designs. S.O.L.I.D. and agile methodologies fan.

TL;DR: Use small objects instead of primitive ones.

Problems

  • Code Duplication

  • Small Objects Missing

  • Fail Fast principle violation.

  • Bijection Fault

  • Subset violations: Emails are a subset of strings, Valid Ages are a subset of Real, Ports are a subset of Integers, etc.

  • We spread Logic and Behavior in many places.

  • Premature Optimization.

Solutions

  1. Create Small Objects

  2. Build missing abstractions using MAPPER

  3. Use Value-Objects.

Context

We are very lazy to create small objects.

We are also lazy to separate What and How

We like very much to understand the internals of how things work.

We need to start thinking in a whitebox way and looking at the protocol and behavior of small components.

Sample Code

Wrong

//Samples borrowed with permission from 
//https://towardsdev.com/why-a-host-is-not-a-string-and-a-port-is-not-an-integer-595c182d817c

var port = 8080;

var in = open("example.org", port);
var uri = urifromPort("example.org", port);
var address = addressFromPort("example.org", port);
var path = pathFromPort("example.org", port);

Right

//Samples borrowed with permission from 
//https://towardsdev.com/why-a-host-is-not-a-string-and-a-port-is-not-an-integer-595c182d817c

const server = Port.parse(this, "www.kivakit.org:8080");
//Port is a smallobject with responsibilities and protocol

let in = port.open(this);
const uri = port.asUri(this);
const address = port.asInetSocketAddress();
const path = port.path(this, "/index.html");

Detection

[X] Manual

We can automate checks on constructors for small objects missing opportunities.

Tags

  • Primitive Obsession

Conclusion

We need to transform our strings, numbers, and arrays into small objects

Relations

More Info

Credits

Photo by K. Mitch Hodge on Unsplash


Iteration allows us to progressively approach some goal. We can discard the steps that take us further away and prefer the steps that move us nearer. This is in essence how evolution works. It is also at the heart of how modern machine learning (ML) works.

Dave Farley


This article is part of the CodeSmell Series.

M

Great writing again Maxi. 👏

I have to admit I am obsessed with primitives. 😊

But I can answer why.

I am not an OOP purist.

Creating objects for the tiniest variables has its price.

You need to put a lot of extra effort to implement them.

And there is also one more advantage:

During the last decades developers were obsessed with primitives.

But it has also a benefit.

We can easily read and write such code.

Just my 2 cents. 😊

M

I agree with you. Code is easier to read. But primitive code fails too late and it is very difficult to find the exact place where we broke the contract.

10
M

Thanks for sharing your thoughts Maxi Contieri.

Code Smells

Part 1 of 50

In this series, we will see several symptoms and situations that make us doubt the quality of our developments. We will present possible solutions. Most are just clues. They are no hard rules.