DEV Community

Cover image for Refactoring 017 - Convert Attributes to Sets
Maxi Contieri
Maxi Contieri

Posted on

3 1

Refactoring 017 - Convert Attributes to Sets

Favor immutability by converting attributes to sets

TL;DR: Using sets for attributes simplifies your code and makes state management easier

Problems Addressed

  • Mutability
  • Complexity
  • Attributes become polluted
  • Setters

Related Code Smells

Steps

  1. Identify attributes representing states
  2. Replace the attributes with sets: one for each state
  3. Adjust methods to move items between sets instead of mutating attributes

Sample Code

Before

class Bill {
  amount: number;
  paid: boolean;

  constructor(amount: number) {
    this.amount = amount;
    this.paid = false;
  }

  pay() {
    if (!this.paid) {
      this.paid = true;
    }
  }
}

const bill = new Bill(100);
console.log(bill.paid); // false
bill.pay();
console.log(bill.paid); // true
Enter fullscreen mode Exit fullscreen mode

After

// 1. Identify attributes representing states

class Accountant {  
   // 2. Replace the attributes with sets: one for each state
  unpaidBills: Set<Bill>;
  paidBills: Set<Bill>;

  constructor() {
    this.unpaidBills = new Set();
    this.paidBills = new Set();
  }

  addBill(bill: Bill) {
    this.unpaidBills.add(bill);
  }

  payBill(bill: Bill) {    
    // 3. Adjust methods to move items
    // between sets instead of mutating attributes
    if (this.unpaidBills.has(bill)) {
      this.unpaidBills.delete(bill);
      this.paidBills.add(bill);
    }
  }
}

class Bill {
  amount: number;

  constructor(amount: number) {
    this.amount = amount;
  }
}

const bill = new Bill(100);
const accountant = new Accountant();
accountant.addBill(bill);
console.log(accountant.unpaidBills.has(bill)); // true
accountant.payBill(bill);
console.log(accountant.paidBills.has(bill)); // true
Enter fullscreen mode Exit fullscreen mode

Type

[X] Semi-Automatic

Safety

This refactoring is safe when your attributes don't rely on specific indexing behavior.

Since sets don't maintain element order, check if your logic depends on order.

Why is the code better?

Entities are immutable in the essence.

Using sets ensures uniqueness and simplifies logic.

You no longer need to check for duplicates before adding elements.

Operations like union, intersection, and difference become straightforward, making your code more maintainable and flexible.

Limitations

Sets don't preserve element order.

If your logic depends on sequence, converting to a set may not be appropriate and you should use an Ordered Collection or Array

AI Refactoring

You can prompt your AI assistants to make this refactoring for you.

Try Them!

Without Proper Instructions With Specific Instructions
ChatGPT ChatGPT
Claude Claude
Perplexity Perplexity
Copilot Copilot
Gemini Gemini

Tags

  • Mutability

Related Refactorings

https://dev.to/mcsee/refactoring-001-remove-setters-26cg

See also

Credits

Image by Angelo Giordano in Pixabay


This article is part of the Refactoring Series.

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay