Skip to content
Home » Introduce Local Extension

Introduce Local Extension

Refactoring is a crucial aspect of writing and maintaining clean, efficient code. One of the techniques used in refactoring is the ‘Introduce Local Extension’ method. This article will delve into what this technique is, when it’s used, and provide practical examples in Java.

What is ‘Introduce Local Extension’ Refactoring?

‘Introduce Local Extension’ is a refactoring technique used when you need to add more functionality to a class, but you don’t have the ability to modify it. This could be because the class is part of a library or it’s in a part of your codebase that you don’t want to change.

In such cases, you can create a new class that contains the additional methods and inherits from the original class or wraps the original class. This new class is referred to as a ‘Local Extension’.

Criteria for Application

This refactoring technique is used when:

  1. You need to add new methods or fields to a class, but you can’t modify the original class.
  2. You want to simplify complex calls to methods in a class by introducing simpler methods in the local extension.

Examples in Java

Let’s consider a scenario where we have a Date class from a library, and we want to add a method to check if a date is a holiday. We can’t modify the Date class directly, so we introduce a local extension.

Extension Type

Here’s the original Date class:

import java.util.Date;

public class OriginalDate {
    private Date date;

    public OriginalDate(Date date) {
        this.date = date;
    }

    // Other methods...
}
Java

We introduce a local extension, ExtendedDate, which inherits from OriginalDate:

public class ExtendedDate extends OriginalDate {
    public ExtendedDate(Date date) {
        super(date);
    }

    public boolean isHoliday() {
        // Check if the date is a holiday
        // This is a placeholder implementation
        return false;
    }
}
Java

In the ExtendedDate class, we’ve added the isHoliday() method, which isn’t present in the original Date class.

Wrapper Type

Alternatively, you can use the wrapper type for local extension. In this case, instead of inheriting from the original class, you wrap the original class in a new class and add the new functionality:

public class DateWrapper {
    private OriginalDate originalDate;

    public DateWrapper(OriginalDate originalDate) {
        this.originalDate = originalDate;
    }

    public boolean isHoliday() {
        // Check if the date is a holiday
        // This is a placeholder implementation
        return false;
    }

    // Delegate other methods to the originalDate...
}
Java

In the DateWrapper class, we’ve added the isHoliday() method, which isn’t present in the original Date class. Other methods of OriginalDate can be accessed by delegating them to the originalDate instance.

Support in Programming Languages

Kotlin’s extension functions are a perfect example of the ‘Introduce Local Extension’ refactoring technique. In Kotlin, you can add new functions to an existing class without inheriting from the class or using any type of design pattern. These new functions, called extension functions, can be called on objects of the original class just like regular methods. This allows you to extend the functionality of classes even if you don’t have access to their source code.

fun String.hasSpaces(): Boolean {
    return this.contains(" ")
}

fun main() {
    println("Hello, World!".hasSpaces()) // prints: true
}
Kotlin

In the above Kotlin code, we’ve added a hasSpaces function to the String class. This function checks if a string contains spaces.

Other languages also have features that facilitate ‘Introduce Local Extension’ refactoring. For instance, C# has a similar feature to Kotlin’s extension functions. In Swift, you can use extensions to add new functionality to an existing class, structure, enumeration, or protocol type. This includes the ability to extend types for which you do not have access to the original source code (known as retroactive modeling). Python, on the other hand, doesn’t have built-in support for extension methods, but you can achieve similar results using its dynamic nature and monkey patching. However, monkey patching should be used with caution as it can lead to less predictable and harder-to-maintain code.