HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Is this an acceptable implementation of the Adapter pattern?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thistheadapterimplementationacceptablepattern

Problem

I've used the UK Plug -> US Socket and US Plug -> UK Socket analogy. I've also made it possible for UK plug to use a UK socket and a US plug to use a US socket. The output of the SSCCE below is

UKPlug -> UKSocket
USPlug -> USSocket
UKPlug -> UKUSAdapter -> USSocket
USPlug -> USUKAdapter -> UKSocket


And the code

```
package com.structural.adapter.adapter2;

interface IAdapter {
public void plugin();
}

class UKUSAdapter implements IAdapter {
UKPlug plug;
USSocket socket;
public UKUSAdapter(UKPlug plug, USSocket socket) {
this.plug = plug;
this.socket = socket;
}

@Override
public void plugin() {
System.out.print("UKUSAdapter -> ");
socket.accept_2pin_plug(plug.pin1, plug.pin2);
}
}

class USUKAdapter implements IAdapter {
USPlug plug;
UKSocket socket;
public USUKAdapter(USPlug plug, UKSocket socket) {
this.plug = plug;
this.socket = socket;
}

@Override
public void plugin() {
System.out.print("USUKAdapter -> ");
socket.accept_3pin_plug(plug.pin1, plug.pin2, 1);
}

}

class USSocket {
USPlug plug;
public USSocket(USPlug plug) {
this.plug = plug;
}

public void accept_2pin_plug(int pin1, int pin2) {
System.out.print("USSocket");
}
}

class UKSocket {
UKPlug plug;
public UKSocket(UKPlug plug) {
this.plug = plug;
}
public void accept_3pin_plug(int pin1, int pin2, int pin3) {
System.out.print("UKSocket");
}
}

class UKPlug {
int pin1;
int pin2;
int pin3;

IAdapter adapter;
UKSocket socket;

public UKPlug(int pin1, int pin2, int pin3) {
this.pin1 = pin1;
this.pin2 = pin2;
this.pin3 = pin3;
}

public void plug_into_3pin() {
System.out.print("UKPlug -> ");
if(this.socket == null) {
adapter.plugin();
} else {
socket.accept_3pin_plug(pin1, pin2, pin3);
}
}

public void setAdapter(IAdapter adapter) {
this.adapter = adapter;
this.socket = null;
}

public void setSocket(UKSocket socket) {

Solution

This is not an implementation of the Adapter pattern.

What is the Adapter pattern trying to solve?

Lets' say I have :

public interface UKPlug {

    int getPin1();

    int getPin2();

    int getPin3();
}

public class UKSocketImpl {

    public void plugin(UKPlug plug) {

        if (plug.getPin1() == -plug.getPin2() && plug.getPin3() == 0) {
            System.out.println(plug.toString() + " -> UKSocket");
        }

    }
}


A UK socket, that accepts UKPlugs. The socket is the client in this scenario, which makes use of an interface (UKPlug)

Now I want to plug in my device, but it has a USPlug :

import java.math.BigInteger;

public class USPlugImpl {

    public BigInteger getPin1() {
        return BigInteger.TEN;
    }

    public BigInteger getPin2() {
        return BigInteger.TEN.negate();
    }

    @Override
    public String toString() {
        return "USPlug";
    }
}


This is where we can write an Adapter class to adapt our Adaptee (USPlugImpl) :

package adapter.improved;

public class USUKAdapter implements UKPlug {

    private final USPlugImpl plug;

    public USUKAdapter(USPlugImpl plug) {
        this.plug = plug;
    }

    @Override
    public int getPin1() {
        return plug.getPin1().intValue();
    }

    @Override
    public int getPin2() {
        return plug.getPin2().intValue();
    }

    @Override
    public int getPin3() {
        return 0;
    }

    @Override
    public String toString() {
        return plug.toString() + " adapted to UKPlug";
    }
}


This is what the Adapter class does :

  • it implements the needed interface



  • it does so by delegating to methods of the Adaptee instance (the USPlug), or by supplying some default behaviour.



  • Both the USPlug as the UKSocket are unaware of the use of an Adapter.



example use :

private void plugIn(UKSocketImpl ukSocket, USPlugImpl usPlug) {
    ukSocket.plugin(new USUKAdapter(usPlug));
}


How do your Adapter classes differ?

  • They implement an interface, but not one that is used by the Client



  • The UKPlug and USPlug classes have a reference to an adapter. What if these were classes from a 3rd party library, and you couldn't add members to them? That's what the Adapter pattern solves.



Final style note : don't use '_' in method names.

Code Snippets

public interface UKPlug {

    int getPin1();

    int getPin2();

    int getPin3();
}

public class UKSocketImpl {

    public void plugin(UKPlug plug) {

        if (plug.getPin1() == -plug.getPin2() && plug.getPin3() == 0) {
            System.out.println(plug.toString() + " -> UKSocket");
        }

    }
}
import java.math.BigInteger;

public class USPlugImpl {

    public BigInteger getPin1() {
        return BigInteger.TEN;
    }

    public BigInteger getPin2() {
        return BigInteger.TEN.negate();
    }

    @Override
    public String toString() {
        return "USPlug";
    }
}
package adapter.improved;

public class USUKAdapter implements UKPlug {

    private final USPlugImpl plug;

    public USUKAdapter(USPlugImpl plug) {
        this.plug = plug;
    }

    @Override
    public int getPin1() {
        return plug.getPin1().intValue();
    }

    @Override
    public int getPin2() {
        return plug.getPin2().intValue();
    }

    @Override
    public int getPin3() {
        return 0;
    }

    @Override
    public String toString() {
        return plug.toString() + " adapted to UKPlug";
    }
}
private void plugIn(UKSocketImpl ukSocket, USPlugImpl usPlug) {
    ukSocket.plugin(new USUKAdapter(usPlug));
}

Context

StackExchange Code Review Q#51135, answer score: 5

Revisions (0)

No revisions yet.