JAVA/Adapter Pattern


アダプタモードはStructure Patternの1つであり、関連しないインタフェースを一緒に使用することができます。


構造モードとは?


構造モードとは,小クラスを継承し合成してより大きなクラスを生成する方法を提供するモードである.このモードでは、互いに独立して開発されたクラスライブラリを全体として使用できます.また,複数のインタフェースを合成することにより,異なるインタフェースの統一抽象を提供する.
構造モードの重要な特徴は,複合インタフェースや実装ではなく,オブジェクトを合成する方法を提供することである.これは、コンパイルフェーズではなく実行フェーズで複合メソッドまたはターゲットを変更できるため柔軟性があります.

アダプタモードの概念とサンプルコード


アダプターの日常生活での使い道を考えると、InputとOutputは違います.
同様に、アダプタモードは、クラスのインタフェースをユーザが望むインタフェース形式に変換するモードである.アダプタモードでは、不一致インタフェースを持つクラスを一緒に動作させます.
前述したように、ボルトコンバータの概念を用いてサンプルコードを見てみましょう.
Voltクラスはvolt値を持つPOJOクラスにすぎない.

socketクラスは、値120ボルトのボルトオブジェクトを生成するクラスです.

120ボルトだけでなく、3ボルトと12ボルトも生成できるアダプタを見て、各ボルトオブジェクトを作成するためのインタフェースを定義します.

アダプタモードを実現するには、ClassAdapterとObjectAdapterの2つの方法があります.
どんな方法で実現しても、結果は同じです.
  • ClassAdapter
    Java継承の使用方法
  • ObjectAdapter
    Java合成(Composite)を使用する方法
  • SocketクラスとVoltクラスを使用して、SocketAdapterインタフェースで定義されている方法に合わせます.
    サンプルコードをClassAdapterとObjectAdapterでそれぞれ表示します.

    クラスアダプティブメソッド

    //Using inheritance for adapter pattern
    public class SocketClassAdapterImpl extends Socket implements SocketAdapter{
     
        @Override
        public Volt get120Volt() {
            return getVolt();
        }
     
        @Override
        public Volt get12Volt() {
            Volt v= getVolt();
            return convertVolt(v,10);
        }
     
        @Override
        public Volt get3Volt() {
            Volt v= getVolt();
            return convertVolt(v,40);
        }
    	
        private Volt convertVolt(Volt v, int i) {
            return new Volt(v.getVolts()/i);
        }
     
    }

    オブジェクトアダプティブ

    public class SocketObjectAdapterImpl implements SocketAdapter{
     
        //Using Composition for adapter pattern
        private Socket sock = new Socket();
    	
        @Override
        public Volt get120Volt() {
            return sock.getVolt();
        }
     
        @Override
        public Volt get12Volt() {
            Volt v= sock.getVolt();
            return convertVolt(v,10);
        }
     
        @Override
        public Volt get3Volt() {
            Volt v= sock.getVolt();
            return convertVolt(v,40);
        }
    	
        private Volt convertVolt(Volt v, int i) {
            return new Volt(v.getVolts()/i);
        }
    }
    注目すべきは、両方の方法でsocketAdapterインタフェースが実現されていることです.
    このアダプタインタフェースは抽象クラスとして使用できます.
    次に、このアダプタインタフェースを使用してテストコードを作成します.
    public class AdapterPatternTest {
     
        public static void main(String[] args) {
    		
            testClassAdapter();
            testObjectAdapter();
        }
     
        private static void testObjectAdapter() {
            SocketAdapter sockAdapter = new SocketObjectAdapterImpl();
            Volt v3 = getVolt(sockAdapter,3);
            Volt v12 = getVolt(sockAdapter,12);
            Volt v120 = getVolt(sockAdapter,120);
            System.out.println("v3 volts using Object Adapter="+v3.getVolts());
            System.out.println("v12 volts using Object Adapter="+v12.getVolts());
            System.out.println("v120 volts using Object Adapter="+v120.getVolts());
        }
     
        private static void testClassAdapter() {
            SocketAdapter sockAdapter = new SocketClassAdapterImpl();
            Volt v3 = getVolt(sockAdapter,3);
            Volt v12 = getVolt(sockAdapter,12);
            Volt v120 = getVolt(sockAdapter,120);
            System.out.println("v3 volts using Class Adapter="+v3.getVolts());
            System.out.println("v12 volts using Class Adapter="+v12.getVolts());
            System.out.println("v120 volts using Class Adapter="+v120.getVolts());
        }
    	
        private static Volt getVolt(SocketAdapter sockAdapter, int i) {
            switch (i){
            case 3: return sockAdapter.get3Volt();
            case 12: return sockAdapter.get12Volt();
            case 120: return sockAdapter.get120Volt();
            default: return sockAdapter.get120Volt();
            }
        }
    }
    v3 volts using Class Adapter=3
    v12 volts using Class Adapter=12
    v120 volts using Class Adapter=120
    v3 volts using Object Adapter=3
    v12 volts using Object Adapter=12
    v120 volts using Object Adapter=120
    これまでアダプタモードについて理解してきました.
    このアダプタモードはJavaのJDKでArraysです.asList()または
    InputStreamReader(InputStream),
    OutputStreamWriterなどに使用します.
    リファレンスソース