DEV Community

Cover image for Refactoring 012 - Reify Associative Arrays
Maxi Contieri
Maxi Contieri

Posted on • Originally published at maximilianocontieri.com

2

Refactoring 012 - Reify Associative Arrays

Converting your anemic dictionaries is easy

TL;DR: Convert your key/value into full behavioral objects

Problems Addressed

Related Code Smells

Context

You have anemic associative arrays that hold unstructured data and you want to have richer objects with stricter controls (possibly including type checking in static typed languages)

Steps

  1. Find the references to the object or associative array

  2. Reify it

  3. Replace generic calls with setters and getters for every key (You also will be able to debug them better)

  4. Add parameter and return type hinting to interfaces (if your language supports it)

  5. Add stronger assertions on the setters between different keys.

(if you are using TCR, you can do baby refactoring steps)

Sample Code

Before

<?

class AuthenticationHelper extends Singleton {

  private $data = [];

  function setParameter(string $key, ?$value) {
    // no type checking
    // value as the name is too generic
    // Since SOME parameters might be null
    // You cannot check a single parameter for not null

    $this->data[$key] = value;
  }

  function getParameter(string $key) {
    // no return type hinting
    return $this->data[$key] ?? null;
  }

}

// Usages

AuthenticationHelper::getInstance->setParameter('oauth2_token', []);
// type error not caught

AuthenticationHelper::getInstance->setParameter('scopes', null);
// We need to enforce this not to be NULL

AuthenticationHelper::getInstance->setParameter('user', 'Elon');
// This should not mutate
// No validation with business rules

$credential = AuthenticationHelper::getInstance->getParameter('oauth2token');
// Typo not detected

// You can not easily find references to methods setting the oauth2_token
Enter fullscreen mode Exit fullscreen mode

After

<?

class AuthenticationCredentials {

  private $user;
  private $oauth2_token;

  function __construct(User $user) {
    $this->validateUser($user);
    // Specific validation rules

    $this->user = $user;
    // Cannot mutate 
  }

  function oauth2_token(string $token): void {
    // You can add specific validations
    $this->oauth2_token = $token;
  }

  function oauth2_token(): string {    
    // Return type hinting
    return $this->oauth2_token;
  }

}

// Usages

$credentials = new AuthenticationCredentials(new User('Elon'));
// Valid since creation

$credentials->oauth2_token([]);
// type errors are caught

$credentials->oauth2_token(null);
// cannot be null. Fail fast

$credentials->scope();
// Typo detected
Enter fullscreen mode Exit fullscreen mode

Now, you have an anemic data class or DTO. It is time to give it behavior and (possibly) remove some getters and setters.

Type

[X] Semi-Automatic

You can perform this refactor with the aid of an IDE.

Safety

This is not an automatic refactoring but small steps are safe if you have good coverage.

Why is code better?

Your new object fails fast and is more declarative.

You can debug it easily and find the referencing methods.

Limitations

In dynamically typed languages you cannot enforce type or domain restrictions for the values

Tags

  • Anemic

Related Refactorings

See also

Credits

Image from MustangJoe en Pixabay


This article is part of the Refactoring Series.

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

👋 Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

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

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay