ケーススタディ:設計モードとコードの構造特性-アダプタモード

13582 ワード

アダプタモードの定義
アダプタモードは、1つのクラスのインタフェースをクライアントが望む別のインタフェースに変換し、インタフェースが一致しないために一緒に動作できない2つのクラスを一緒に動作させる.アダプタモードでは、クラスのアダプタモードとオブジェクトのアダプタモードの2つの異なるモード構造があります.
宣言:javaは多重継承をサポートしておらず、1つのクラスに1つの親しか存在しません.本明細書で示したアダプタモードのクラス図は、クラスアダプタのクラス図ではなく、GOF著作に従ってオブジェクトアダプタモードに属するクラス図に分類されます.
シーンでの適用
洗濯機が3つの穴のプラグを使っていると仮定し、テレビが2つの穴のプラグを使っていると仮定します.
1、Target(ターゲット抽象クラス):ターゲット抽象クラスは顧客に必要なインタフェースを定義し、抽象クラスまたはインタフェースであってもよいし、特定のクラスであってもよい.
2、Adaptee(アダプタークラス):アダプターはすでに存在するインタフェースを定義し、このインタフェースはアダプターが必要であり、アダプタークラスは一般的に具体的なクラスであり、お客様が使用したいビジネス方法を含む.
3、Adapter(アダプタ類):適切なオブジェクトを包装することで、元のインタフェースをターゲットインタフェースに変換します.
キーコード
package com.AdapterPattern;
 
public abstract interface ThreeElectricOutlet {
 
    public abstract void connectElectricCurrent();
    
}
package com.AdapterPattern;
 
public abstract interface TwoElectricOutlet {
 
    public abstract void connectElectricCurrent();
 
}
package com.AdapterPattern;
 
public class ThreeElectricAdapter implements ThreeElectricOutlet {
 
    private TwoElectricOutlet twoElectricOutlet;
    
    public ThreeElectricAdapter(TwoElectricOutlet twoElectricOutlet) {
        super();
        this.twoElectricOutlet = twoElectricOutlet;
    }
 
    public void connectElectricCurrent() {
        twoElectricOutlet.connectElectricCurrent();
    }
 
}
package com.AdapterPattern;
 
public class Application {
    public static void main(String[] args) {
        ThreeElectricOutlet outlet;   //    (    )
        Wash wash=new Wash();         //   
        outlet=wash;                  //          
        System.out.println("          :");
        outlet.connectElectricCurrent();     //
        
        TV tv=new TV();                   //   
        ThreeElectricAdapter adapter=new ThreeElectricAdapter(tv);   //          
        outlet=adapter;             //          
        System.out.println("          :");
        outlet.connectElectricCurrent();   //
        
    }
}
class Wash implements ThreeElectricOutlet{  //         
    String name;
    public Wash() {
        name="     ";
    }
    public Wash(String name) {
        this.name = name;
    }
    public void connectElectricCurrent() {
        turnOn();
    }
    public void turnOn() {
        System.out.println(name+"     。");
    }
 
}
 
class TV implements TwoElectricOutlet { //         
    String name;
    public TV() {
        name="     ";
    }
    public TV(String name) {
        this.name = name;
    }
    public void connectElectricCurrent() {
        turnOn();
    }
    public void turnOn() {
        System.out.println(name+"      。");
    }
 
}

にほうこうアダプタ
オブジェクトアダプタモードでは、Adapterロールがターゲットインタフェースとアダプタインタフェースを同時に実装し、ターゲットとアダプターの参照を含む場合、アダプタは双方向アダプタです.双方向アダプタを使用すると、ユーザーは新しいインタフェースも既存のインタフェースも使用できます.
例えば、ユーザーが新しい三相コンセントで洗濯機とテレビに電流を接続したい場合、古い二相コンセントで洗濯機に電流を接続したい場合は、双方向アダプタを使用する必要があります.
 
双方向アダプタのコードは次のとおりです.
package com.AdapterPattern;
 
public class ThreeAndTwoElectricAdapter implements ThreeElectricOutlet,TwoElectricOutlet{
    TwoElectricOutlet twoElectricOutlet;
    ThreeElectricOutlet threeElectricOutlet;
    public ThreeAndTwoElectricAdapter(TwoElectricOutlet twoElectricOutlet, ThreeElectricOutlet threeElectricOutlet) {
        super();
        this.twoElectricOutlet = twoElectricOutlet;
        this.threeElectricOutlet = threeElectricOutlet;
    }
    public ThreeAndTwoElectricAdapter(ThreeElectricOutlet threeElectricOutlet,TwoElectricOutlet twoElectricOutlet ) {
        super();
        this.twoElectricOutlet = twoElectricOutlet;
        this.threeElectricOutlet = threeElectricOutlet;
    }
    public void connectElectricCurrent() {
        if(this instanceof ThreeElectricOutlet)
            twoElectricOutlet.connectElectricCurrent();      //TwoElectricOutlet      
        if(this instanceof TwoElectricOutlet)
            threeElectricOutlet.connectElectricCurrent();    //threeElectricOutlet      
    }
    
}

 
 
アダプタモードのメリット
ターゲットクラスとアダプタークラスをデカップリングし、アダプタクラスを導入することで既存のアダプタークラスを再利用し、既存の構造を変更する必要はありません.
クラスの透明性と多重性を向上させ、特定のビジネス実装プロセスをアダプタークラスにカプセル化し、クライアントクラスにとって透明であり、アダプターの多重性を向上させ、同じアダプタークラスを複数の異なるシステムで多重化することができる.
柔軟性と拡張性に優れ、プロファイルを使用することでアダプタの交換が容易になります.また、既存のコードを変更せずに新しいアダプタクラスを追加することもでき、「開閉の原則」に完全に合致します.
マルチステート
2つの電気器具は1つは2つの穴のコンセントを使って、1つは3つの穴のコンセントを使って、それぞれインタフェースの多態を使っています:ThreeElectricOutletとTwoElectricOutlet
パッヶージ
コード内のすべての方法はpublic(すべてのクラスが表示されます)であり、電気器具のname変数はデフォルトであり、本パッケージにアクセスできます.パッケージは実装されていません.洗濯機を例に、以下の方法でパッケージすることができます.
class Wash implements ThreeElectricOutlet{  //         
    private String name;
    public String getname(){
        return name;
    }
    public Wash() {
        name="     ";
    }
    public Wash(String name) {
        this.name = name;
    }
    public void connectElectricCurrent() {
        turnOn();
    }
    public void turnOn() {
        System.out.println(name+"     。");
    }
 
}    

これにより、変数の保護が実現されます.プログラムコードのセキュリティを強化しました.
結合度と凝集度
このコードは主にアダプタモードの意味を理解するのに役立つため、簡単です.
凝集度にとって、コードは比較的簡単で、2つの電気製品もある機能を実現するために一緒に働いているわけではないので、特に明らかではありません.
結合度については,まずインタフェースを用いて結合度を低下させた.
次に,アダプタの導入により,ターゲットクラスとアダプタ間の結合度が低下した.つまりモジュール間のつながりが簡単になります.アダプターが変更された場合、アダプタを変更しても、ターゲットクラスに影響はありません.
導入された操作手順
テストコード
package com.AdapterPattern;
 
public class BiApplication {
 
    public static void main(String[] args) {
        ThreeElectricOutlet threeElectricOutlet;   //ThreeElectricOutlet  (    
        TwoElectricOutlet twoElectricOutlet;       //TwoElectricOutlet  (    )
        Wash wash=new Wash();      //   
        TV tv=new TV();           //   
        ThreeAndTwoElectricAdapter adapter=new ThreeAndTwoElectricAdapter(wash, tv);  //     
        threeElectricOutlet=adapter;        //          
        System.out.println("          :");
        threeElectricOutlet.connectElectricCurrent();
        twoElectricOutlet=adapter;          //          
        System.out.println("          ");  
        twoElectricOutlet.connectElectricCurrent();
    }
 
}

ソースアドレス:
https://github.com/androidwolf/designpattern--adapter