Code Smell 192 - Optional Attributes

Maxi Contieri - Jan 17 '23 - - Dev Community

You need to model something optional. Have you tried collections?

TL;DR: Collections are fantastic. And Polymorphic.

Problems

Solutions

  1. Change the optional attribute to a collection.

Context

If you need to model something that might be missing, some fancy languages will provide optional, nullable, and many other wrong solutions dealing with The Billion Dollar Mistake.

Empty collections and non-empty collections are polymorphic.

Sample Code

Wrong

class Person {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }

  email() {
    return this.email;
    // might be null    
  }

}

// We cannot use safely person.email()
// We need to check for null explicitly
Enter fullscreen mode Exit fullscreen mode

Right

class Person {
  constructor(name, emails) {
    this.name = name;
    this.emails = emails;
    // emails should allways be a collection. 
    // even an empty one
    // We can check it here
  }

  emails() {
    return this.emails;
  }

  // We can mutate the emails since they are not essential

  addEmail(email) {
    this.emails.push(email);
  }

  removeEmail(email) {
    const index = this.emails.indexOf(email);
    if (index !== -1) {
      this.emails.splice(index, 1);
    }
  }
}

// we can iterate the person.emails() 
// in a loop without checking for null 
Enter fullscreen mode Exit fullscreen mode

Detection

[X] Semi-Automatic

You can detect nullable attributes and change them when necessary.

Tags

  • Null

Conclusion

This is a generalization of the null object pattern.

Relations

More Info

Disclaimer

Code Smells are just my opinion.

Credits

Photo by Levi Jones on Unsplash


To iterate is human, to recurse divine

Peter Deutsch


This article is part of the CodeSmell Series.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .