# Refactoring 012 - Reify Associative Arrays

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

# Problems Addressed

* [Associative arrays](https://maximilianocontieri.com/code-smell-27-associative-arrays)
    
* Fail Fast principle violation
    
* [Bijection](https://maximilianocontieri.com/the-one-and-only-software-design-principle) Fault
    
* Hard to find method references
    
# Related Code Smells

%[https://maximilianocontieri.com/code-smell-27-associative-arrays] 

# 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](https://maximilianocontieri.com/code-smell-28-setters) and [getters](https://maximilianocontieri.com/code-smell-68-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

[Gist Url]: # (https://gist.github.com/mcsee/ca8de4d5b62f43e87002b6424de11d60)
```php
<?

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
``` 

## After

[Gist Url]: # (https://gist.github.com/mcsee/d8c3cb918572138803015c91a0274d9d)
```php
<?

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 validations
    $this->oauth2_token = $token;
  }

  function oauth2_token(): string {    
    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
``` 

Now, you have an anemic data class or [DTO](https://maximilianocontieri.com/code-smell-40-dtos). 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

%[https://maximilianocontieri.com/refactoring-002-extract-method] 

# See also

%[https://maximilianocontieri.com/code-smell-27-associative-arrays] 

# Credits

Image from [MustangJoe](https://pixabay.com/en/users/mustangjoe-2162920/) en [Pixabay](https://pixabay.com/)

---

This article is part of the Refactoring Series.

%[https://maximilianocontieri.com/how-to-improve-your-code-with-easy-refactorings]
