---
title: "Introduce Null Object"
type: "refactoring-technique"
slug: "introduce-null-object"
url: "http://localhost:3000/en/introduce-null-object.md"
category: "Simplifying Conditional Expressions"
description: "Problem: Since some methods return null instead of real objects, you have many checks for null in your code. Solution: Instead of null, return a null object that exhibits the default behavior."
languages: ["java", "csharp", "php", "python", "typescript"]
---
# Introduce Null Object

> Problem: Since some methods return null instead of real objects, you have many checks for null in your code. Solution: Instead of null, return a null object that exhibits the default behavior.

## Problem

Since some methods return `null` instead of real objects, you have many checks for `null` in your code.

## Solution

Instead of `null`, return a null object that exhibits the default behavior.

## Why Refactor

Dozens of checks for `null` make your code longer and uglier.

## How to Refactor

1. From the class in question, create a subclass that will perform the role of null object.
2. In both classes, create the method `isNull()`, which will return `true` for a null object and `false` for a real class.
3. Find all places where the code may return `null` instead of a real object. Change the code so that it returns a null object.
4. Find all places where the variables of the real class are compared with `null`. Replace these checks with a call for `isNull()`.
5. * If methods of the original class are run in these conditionals when a value doesn’t equal `null`, redefine these methods in the null class and insert the code from the `else` part of the condition there. Then you can delete the entire conditional and differing behavior will be implemented via polymorphism.
  * If things aren’t so simple and the methods can’t be redefined, see if you can simply extract the operators that were supposed to be performed in the case of a `null` value to new methods of the null object. Call these methods instead of the old code in `else` as the operations by default.
## Relations

**Similar techniques**

- [Replace Conditional with Polymorphism](/en/replace-conditional-with-polymorphism.md)

**Eliminates smells**

- [Switch Statements](/en/smells/switch-statements.md)
- [Temporary Field](/en/smells/temporary-field.md)

## Code Examples

### java

```java
// Before
if (customer == null) {
  plan = BillingPlan.basic();
}
else {
  plan = customer.getPlan();
}

// After
class NullCustomer extends Customer {
  boolean isNull() {
    return true;
  }
  Plan getPlan() {
    return new NullPlan();
  }
  // Some other NULL functionality.
}

// Replace null values with Null-object.
customer = (order.customer != null) ?
  order.customer : new NullCustomer();

// Use Null-object as if it's normal subclass.
plan = customer.getPlan();
```

### csharp

```csharp
// Before
if (customer == null) 
{
  plan = BillingPlan.Basic();
}
else 
{
  plan = customer.GetPlan();
}

// After
public sealed class NullCustomer: Customer 
{
  public override bool IsNull 
  {
    get { return true; }
  }
  
  public override Plan GetPlan() 
  {
    return new NullPlan();
  }
  // Some other NULL functionality.
}

// Replace null values with Null-object.
customer = order.customer ?? new NullCustomer();

// Use Null-object as if it's normal subclass.
plan = customer.GetPlan();
```

### php

```php
// Before
if ($customer === null) {
  $plan = BillingPlan::basic();
} else {
  $plan = $customer->getPlan();
}

// After
class NullCustomer extends Customer {
  public function isNull() {
    return true;
  }
  public function getPlan() {
    return new NullPlan();
  }
  // Some other NULL functionality.
}

// Replace null values with Null-object.
$customer = ($order->customer !== null) ?
  $order->customer :
  new NullCustomer;

// Use Null-object as if it's normal subclass.
$plan = $customer->getPlan();
```

### python

```python
// Before
if customer is None:
    plan = BillingPlan.basic()
else:
    plan = customer.getPlan()

// After
class NullCustomer(Customer):

    def isNull(self):
        return True

    def getPlan(self):
        return self.NullPlan()

    # Some other NULL functionality.

# Replace null values with Null-object.
customer = order.customer or NullCustomer()

# Use Null-object as if it's normal subclass.
plan = customer.getPlan()
```

### typescript

```typescript
// Before
if (customer == null) {
  plan = BillingPlan.basic();
}
else {
  plan = customer.getPlan();
}

// After
class NullCustomer extends Customer {
  isNull(): boolean {
    return true;
  }
  getPlan(): Plan {
    return new NullPlan();
  }
  // Some other NULL functionality.
}

// Replace null values with Null-object.
let customer = (order.customer != null) ?
  order.customer : new NullCustomer();

// Use Null-object as if it's normal subclass.
plan = customer.getPlan();
```

