# Refactoring 018 - Replace Singleton

> TL;DR: Refactor singletons to reduce coupling

# Problems Addressed

- High [coupling](https://maximilianocontieri.com/coupling-the-one-and-only-software-design-problem)
- Difficult testability
- Multi-threading issues
- Garbage accumulation
- [15 problems more...](https://maximilianocontieri.com/singleton-the-root-of-all-evil)

# Related Code Smells

%[https://maximilianocontieri.com/code-smell-32-singletons]

%[https://maximilianocontieri.com/code-smell-22-helpers]

%[https://maximilianocontieri.com/code-smell-25-pattern-abusers]

# Steps

1. Identify the singleton 
2. Locate all references to *its getInstance()* method
3. Refactor the singleton to a standard class
4. Inject it as a dependency

# Sample Code

## Before

[Gist Url]: # (https://gist.github.com/mcsee/43f6accd32cfcfef4e1daf5d159c1394)

```java
public class DatabaseConnection {
    private static DatabaseConnection instance;

    private DatabaseConnection() {}

    public static DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }

    public void connect() { 
    }
}

public class Service {
    public void performTask() {
        DatabaseConnection connection = DatabaseConnection.getInstance();
        connection.connect(); 
    }
}
```

## After

[Gist Url]: # (https://gist.github.com/mcsee/d52dafea0e452a5343045d47a4524510)

```java
public class DatabaseConnection {  
    // 1. Identify the singleton 
    public void connect() { 
    }
}

public class Service {
    // 2. Locate all references to its getInstance() method.
    private DatabaseConnection connection;

    // 3. Refactor the singleton to a standard class. 
    public Service(DatabaseConnection connection) {
        // 4. Inject it as a dependency.
        this.connection = connection;
    }

    public void performTask() {
        connection.connect(); 
    }
}

DatabaseConnection connection = new DatabaseConnection();
// You can also mock the connection in your tests

Service service = new Service(connection);
service.performTask();
```

# Type

[X] Semi-Automatic

# Safety

This refactoring is safe when you update all references to the singleton and handle its dependencies correctly. 

Testing each step ensures that no references to the singleton are missed.

# Why is code better?

Refactoring away from a singleton makes the code more modular, testable, and less prone to issues caused by the global state. 

Injecting dependencies allows you to easily replace the former singleton with a mock or different implementation in testing and other contexts.
 
# Tags

- Coupling

# Related Refactorings

%[https://maximilianocontieri.com/refactoring-007-extract-class]

# See also

%[https://maximilianocontieri.com/singleton-the-root-of-all-evil]

%[https://maximilianocontieri.com/coupling-the-one-and-only-software-design-problem]

# Credits

Image by [PublicDomainPictures](https://pixabay.com/users/publicdomainpictures-14/) from [Pixabay](https://pixabay.com/)

* * * 

This article is part of the Refactoring Series.

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