ソフトウェアエンジニアの日常の雑記

日々思ったことをまとめます

デザインパターン:Adapterパターン

Adapterパターン

 Adapter パターンを用いると、既存のクラスに対して修正を加えることなく、インタフェースを変更することができる。 [Wikipedia]

ということらしい。Adapterパターンには、継承を使ったパターンと委譲を使ったパターンがあるとか。

継承を使ったAdapterパターン

public class Main {
    public static void main(String[] args) {
        Print p = new PrintBanner("Hello");
        p.printWeak();
        p.printStrong();
    }
}

interface Print {
    public abstract void printWeak();
    public abstract void printStrong();
}

class Banner {
    private String string;
    public Banner(String string){
        this.string = string;
    }
    public void showWithParen(){
        System.out.println("("+string+")");
    }
    public void showWithAster(){
        System.out.println("*"+string+"*");
    }
}

class PrintBanner extends Banner implements Print{

    public PrintBanner(String string) {
        super(string);
    }

    @Override
    public void printWeak() {
        showWithParen();
    }

    @Override
    public void printStrong() {
        showWithAster();
    }
    
}

これが継承を使ったパターン。継承されたBannerクラスやshowWithParen()メソッドをmainメソッドは知らないが、インターフェースを介して呼び出せている。

委譲を使ったAdapterパターン

package jp.co.adapter;

public class Main2 {
    public static void main(String[] args) {
        Print2 p = new PrintBanner2("Hello");
        p.printWeak();
        p.printStrong();
    }
}

abstract class Print2 {
    public abstract void printWeak();
    public abstract void printStrong();
}

class Banner2 {
    private String string;
    public Banner2(String string){
        this.string = string;
    }
    public void showWithParen(){
        System.out.println("("+string+")");
    }
    public void showWithAster(){
        System.out.println("*"+string+"*");
    }
}

class PrintBanner2 extends Print2{
    Banner2 banner;
    public PrintBanner2(String string) {
        this.banner = new Banner2(string);
    }

    @Override
    public void printWeak() {
        banner.showWithParen();
    }

    @Override
    public void printStrong() {
        banner.showWithAster();
    }
    
}

Print2クラスを抽象クラスにして、PrintBanner2クラスに継承させる。PrintBanner2クラスの中で、PrintBanner2クラスのコンストラクタの中で、Banner2クラスをインスタンス化する。Mainクラスからはそのことはわからない。そうすると疎結合になるので、変更による影響が少なくなる。