DEV Community

Cover image for Code Smell 50 - Object Keys
Maxi Contieri
Maxi Contieri

Posted on • Edited on • Originally published at maximilianocontieri.com

4 2

Code Smell 50 - Object Keys

Primary keys, IDs, references. The first attribute we add to our objects. They don't exist in the real world.

Problems

Solutions

  1. Reference object to objects.

  2. Build a MAPPER.

  3. Only use keys if you need to provide an external (accidental) reference. Databases, APIs, Serializations.

  4. Use dark keys or GUIDs when possible.

  5. If you are afraid of getting a big relation graph use proxies or lazy loading.

  6. Don't use DTOs.

Sample Code

Wrong

class Teacher {
static getByID(id) {
// This is coupled to the database
// Thus violating separation of concerns
}
constructor(id, fullName) {
this.id = id;
this.fullName = fullName;
}
}
class School {
static getByID(id) {
// go to the coupled database
}
constructor(id, address) {
this.id = id;
this.address = address;
}
}
class Student {
constructor(firstName, lastName, id, teacherId, schoolId) {
this.firstName = firstName;
this.lastName = lastName;
this.id = id;
this.teacherId = teacherId;
this.schoolId = schoolId;
}
school() {
return School.getById(this.schoolId);
}
teacher() {
return Teacher.getById(this.teacherId);
}
}
view raw student.js hosted with ❤ by GitHub

Right

class Teacher {
constructor(fullName) {
this.fullName = fullName;
}
}
class School {
constructor(address) {
this.address = address;
}
}
class Student {
constructor(firstName, lastName, teacher, school) {
this.firstName = firstName;
this.lastName = lastName;
this.teacher = teacher;
this.school = school;
}
}
// The ids are no longer needed
// since they don’t exist in the real world.
// If you need to expose a School to an external API or a database,
// another object (not school)
// will keep the mapping externalId<->school and so on
view raw noids.js hosted with ❤ by GitHub

Detection

This is a design policy.

We can enforce business objects to warn us if we define an attribute or function including the sequence id.

Tags

  • Accidental

Conclusion

Ids are not necessary for OOP. You reference objects (essential) and never ids (accidental).

In case you need to provide a reference out of your system's scope (APIs, interfaces, Serializations) use dark and meaningless IDs (GUIDs).

Relations

More info

Credits

Photo by Maurice Williams on Unsplash


All problems in computer science can be solved by another level of indirection.

David Wheeler

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (2)

Collapse
 
frankfont profile image
Frank Font

Simple answers don't always fit complex problems.
Semantic keys are not always a code smell in the wild.
I've found the lack of them when needed for performance and scale resilience can be a problem. They are the first thing I sniff for in a relational database and some shared object structures.

Collapse
 
mcsee profile image
Maxi Contieri

Of course. But then we are talking about data and performance(accidental) In my article I was focusing solely on behaviour (essential)

👋 Kindness is contagious

Explore this insightful piece, celebrated by the caring DEV Community. Programmers from all walks of life are invited to contribute and expand our shared wisdom.

A simple "thank you" can make someone’s day—leave your kudos in the comments below!

On DEV, spreading knowledge paves the way and fortifies our camaraderie. Found this helpful? A brief note of appreciation to the author truly matters.

Let’s Go!