【Java】デザインパターンをやってみた 〜 Adapter編 ~

◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
【5/21開催】Azure OpenAI ServiceによるRAG実装ガイドを公開しました
生成AIを活用したユースケースで最も一番熱いと言われているRAGの実装ガイドを公開しました。そのガイドの紹介をおこなうイベントです!!
https://tech-lab.connpass.com/event/315703/

こんにちは。サイオステクノロジーの川田です。

今回はAdapterパターンについて調べてみました。
参考☞「増補改訂版Java言語で学ぶデザインパターン入門

Adapterとは

「Adapt」とは適応させるという意味です。
適応させると言葉で言われてもパッとしません。

よく例に出てくるのがACアダプタです。簡単に言うとズバリ仲介人です。

ACアダプタはコンセントからくる電気をパソコンで使える電気に変換する役割をしてくれます。

クラス図で考える

先ほどはACアダプタを使って例えてみました。
ではプログラミングではどのように考えるのかクラス図で見てみます。

役割分担
Client :Targetメソッドを使って処理を行う
Target :必要とされるメソッド
Adapter:Adapteeのメソッドを使ってTargetの役割を満たすためのクラス
Adaptee:すでに用意されているメソッドを持っているクラス

AdapterとなるPrintHumanクラスはHumanクラスを継承(extends)し、Printインターフェースを実装(implements)しています。

実装してみる

Adapteeの部分です。

  • Human.java
public class Human {
    private String name;
    private int birthday;

    public Human(String name, int birthday){
        this.name = name;
        this.birthday = birthday;
    }
    public void showName(){
        System.out.println(name);
    }
    public void showBirthday(){
        System.out.println(birthday);
    }
}

Targetで必要とされているメソッドを定めています。

  • Print.java
public interface Print {
    public abstract void printName();
    public abstract void printAge();
}

本日の主役、Adapterの役割です。
HumanクラスをextendsしてshowNameとshowBirthdayメソッドを継承しています。
Printインターフェースをimplementsし、printNameとprintBirthdayを実装しています。

  • PrintHuman.java
public class PrintHuman extends Human implements Print{
    public PrintHuman(String name, int birthday){
        super(name, birthday);
    }
    public void printName(){
        showName();
    }
    public void printBirthday(){
        showBirthday();
    }
}

これらのクラスやインターフェースを利用するmainメソッドは以下の通りです。

  • Main.java
public class Main {
    public static void main(String[] agrs){
        Print p = new PrintHuman("taro", 19990101);
        p.printName();
        p.printBirthday();
    }
}

実行結果はこちらです。

taro
19990101

MainクラスはPrintインターフェースのprintNameとprintBirthdayメソッドを使っています。
Adapterがどんな実装になっているかなんてMainクラスは知らないのです!
既に提供されているもの、それがHumanクラスだとします。
PrintHumanクラスはHumanクラスの実装を利用できるように変換する役割を担ってくれました。

委譲

先ほどのは継承を使ったAdapterパターンでした。
実はもう一つ、委譲を使ったAdapterパターンもあります。

委譲とは他にゆだね、ゆずるという意味になります。
今回の委譲の表現は「あるメソッドの処理を他のクラスのインスタンスにお任せする」という考えになります。

クラス図(委譲)

右上は先ほど出てきた「継承を使った」クラス図です。
比べてみると赤丸の部分が変わっていることがわかりますね。

実装で確認してみましょう!

実装してみる

Print.javaとPrintHuman.javaを修正します。

  • Print.java
public abstract class Print {
    public abstract void printName();
    public abstract void printBirthday();
}

Printはインターフェースではなく、クラスに修正します。

  • PrintHuman.java
public class PrintHuman extends Print{
    private Human human;
    public PrintHuman(String name, int age){
        human = new Human(name, age);
    }
    public void printName(){
        human.showName();
    }
    public void printAge(){
        human.showBirthday();
    }
}

1行目ではPrintをextendsしています。
そして2行目でHumanクラスのインスタンスを保持しています。
showNameとshowBirthdayの呼び出し方がhumanフィールドを経由して呼び出していることがわかりますね!

printNameやprintBirthdayメソッドが呼ばれたらHumanクラスのインスタンスにお任せしているということです。
実行結果は変わりません。

taro
19990101

まとめ

今回はAdapterパターンの継承と委譲について学びました。
既存のソースをいじらずに修正ができればテストの手間も省けますね!

アバター画像
About kawada 25 Articles
Webアプリケーション開発を行っており、プログラミング初心者向けの記事や動画編集に関する内容を中心とした記事を執筆しています。
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる