Design patterns Adapter Adapter (Java)


Example

Lets assume that in your current codebase, there exists MyLogger interface like so:

interface MyLogger {
    void logMessage(String message);
    void logException(Throwable exception);
}

Lets say that you've created a few concrete implementations of these, such as MyFileLogger and MyConsoleLogger.

You have decided that you want to use a framework for controlling your application's Bluetooth connectivity. This framework contains a BluetoothManager with the following constructor:

class BluetoothManager {
    private FrameworkLogger logger;

    public BluetoothManager(FrameworkLogger logger) {
        this.logger = logger;
    }
}

The BluetoothManager also accepts a logger, which is great! However it expects a logger of which the interface was defined by the framework and they have used method overloading instead of naming their functions differently:

interface FrameworkLogger {
    void log(String message);
    void log(Throwable exception);
}

You already have a bunch of MyLogger implementations that you would like to reuse, but they do not fit the interface of the FrameworkLogger. This is where the adapter design-pattern comes in:

class FrameworkLoggerAdapter implements FrameworkLogger {
    private MyLogger logger;

    public FrameworkLoggerAdapter(MyLogger logger) {
        this.logger = logger;
    }

    @Override
    public void log(String message) {
        this.logger.logMessage(message);
    }

    @Override
    public void log(Throwable exception) {
        this.logger.logException(exception);
    }
}

By defining an adapter class that implements the FrameworkLogger interface and accepts a MyLogger implementation the functionality can be mapped between the different interfaces. Now it is possible to use the BluetoothManager with all of the MyLogger implementations like so:

FrameworkLogger fileLogger = new FrameworkLoggerAdapter(new MyFileLogger());
BluetoothManager manager = new BluetoothManager(fileLogger);

FrameworkLogger consoleLogger = new FrameworkLoggerAdapter(new MyConsoleLogger());
BluetoothManager manager2 = new BluetoothManager(consoleLogger);