Yomiage
メニュー

Java実践講座 06:インターフェースと合成で変更に備える

更新 2026/9/27 6:22:11 公開

投稿者: しゅりりん

到達点は、実装を取り替えられる境界を作ることです。前提は第05回です。

呼ぶ側が必要とする約束

通知処理で必要なのは「メッセージを送れること」です。画面表示かメールかという実装の詳細まで、業務処理が知る必要はありません。インターフェースに操作の約束を置き、実装を外から渡します。これを依存性の注入と呼びます。大きなフレームワークは不要です。

public class Main {
    interface Notifier {
        void send(String message);
    }

    static final class ConsoleNotifier implements Notifier {
        public void send(String message) {
            System.out.println("通知: " + message);
        }
    }

    static final class StudyService {
        private final Notifier notifier;

        StudyService(Notifier notifier) {
            this.notifier = java.util.Objects.requireNonNull(notifier);
        }

        void complete(String lesson) {
            notifier.send(lesson + "を完了しました");
        }
    }

    public static void main(String[] args) {
        StudyService service = new StudyService(new ConsoleNotifier());
        service.complete("クラスの学習");
        new StudyService(message -> System.out.println("テスト記録: " + message))
            .complete("設計の学習");
    }
}

Main.javaで実行すると通常の通知とテスト記録が一つずつ表示されます。StudyServiceはNotifierを「持つ」関係です。これが合成です。実装が異なっても同じ約束で呼び出せる性質を、多態性と呼びます。

継承を選ぶ基準

継承は単なるコードの使い回し機能として乱用しないようにします。親型として使う利用者の期待を、子型も守れるかを考えます。例えば「必ず保存できる保存先」を継承して「常に保存禁止の保存先」を作ると、期待を壊す可能性があります。

変えたい部分を小さな部品として持つ方が、影響範囲を小さくできる場合があります。ただし、すべてのクラスに機械的にインターフェースを作る必要もありません。外部通信、保存先、時計など、変更やテスト差し替えの理由がある境界から始めます。

練習と解答

練習:画面に出さず、通知をリストへ記録する実装を作ります。何を検証すべきでしょうか。

解答例:List<String> messages = new ArrayList<>(); を用意し、new StudyService(messages::add) として注入します。完了後の要素数が1で、内容が期待した文章であることを確認します。privateな内部処理ではなく、通知という外部から見える結果を確かめます。

公式資料

インターフェースを参照できます。


Java全20回の目次 | 前の回 | 次の回

このブラウザでは Web Speech API が利用できません。

1 / 15 · 停止中