モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

工作HardwareHub ロゴ画像 (Laptop端末利用時)
工作HardwareHub ロゴ画像 (Mobile端末利用時)

Java Bridge デザインパターン

モーダルを閉じる

ステッカーを選択してください

モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

作成日作成日
2013/08/13
最終更新最終更新
2015/12/17
記事区分記事区分
一般公開

目次

    アカウント プロフィール画像 (サイドバー)

    Javaちょっとできるプログラマ。教育業界のエンジニアです。

    0
    ステッカーを贈るとは?

    クラスの継承関係 (extends) を大別すると以下の二つがあります。

    • 親クラスがabstractで要請した機能を子クラスが実装する関係
    • 親クラスで不足していた機能 (メソッドなど) を子クラスで追加するための関係

    それら継承関係を混在させて実装すると意図が不明瞭になってしまいます。そこでBridgeパターンでは二つの独立した継承関係を用意し、それぞれの継承関係のトップ同士を委譲によってつなぐ (Bridge) ことで継承を複数方向に行うことを可能にします。新たに継承が必要になったときには、どちらのツリーを拡張しようとしているのかを明確に意識できます。

    サンプルコード

    sample.java

    class Sample {
        public static void main(String args[]) {
            int val=1;
            int arr[]={1};
    
            // プロジェクトのある時点まではAdderが有する機能で満足していた
            Adder intAdder = new Adder(new IntAdderImpl(val)); //abstractで要請された機能の実装方法を
            Adder arrAdder = new Adder(new ArrAdderImpl(arr)); //切り換えるためにはこの引数を差し替える
            intAdder.add(val);
            intAdder.print();
            arrAdder.add(arr);
            arrAdder.print();
    
            // 仕様変更か何かで機能が不足したため、Adderを継承したMultiAdderを用意し追加分を実装
            MultiAdder intMultiAdder = new MultiAdder(new IntAdderImpl(val));
            MultiAdder arrMultiAdder = new MultiAdder(new ArrAdderImpl(arr));
            intMultiAdder.add(val);
            intMultiAdder.multiAdd(val,8);
            intMultiAdder.print();
            arrMultiAdder.add(arr);
            arrMultiAdder.multiAdd(arr,8);
            arrMultiAdder.print();
    
            // 参考: Adder型変数にMultiAdderを代入することは可能
            Adder intAdder2 = new MultiAdder(new IntAdderImpl(val));
            intAdder2.add(val);
            // intAdder2.multiAdd(val,8); //ただしこれはエラー
            intAdder2.print();
        }
    }
    

    Adder.java

    class Adder {
        private AdderImpl impl;
        public Adder(AdderImpl impl) {this.impl=impl;}
        public void add(Object val) {impl.rawAdd(val);}
        public void print() {impl.rawPrint();}
    }
    

    MultiAdder.java

    class MultiAdder extends Adder {
        public MultiAdder(AdderImpl impl) {super(impl);}
        public void multiAdd(Object val, int times) {
            for(int i=0; i<times; ++i) add(val);
        }
    }
    

    AdderImpl.java

    abstract class AdderImpl {
        public abstract void rawAdd(Object val);
        public abstract void rawPrint();
    }
    

    IntAdderImpl.java

    class IntAdderImpl extends AdderImpl {
        private int val;
        public IntAdderImpl(int val) {this.val=val;}
        public void rawAdd(Object val) {this.val += (Integer)val;}
        public void rawPrint() {System.out.println(val);}
    }
    

    ArrAdderImpl.java

    class ArrAdderImpl extends AdderImpl {
        private int arr[];
        public ArrAdderImpl(int arr[]) {
            this.arr = new int[arr.length];
            for(int i=0; i<arr.length; ++i) this.arr[i]=arr[i];
        }
        public void rawAdd(Object val) {
            int tmp[] = arr; //参照をコピー
            arr = new int[arr.length + ((int[])val).length]; //キャスト (型変換)
            for(int i=0; i<tmp.length; ++i) arr[i]=tmp[i];
            for(int i=0; i<((int[])val).length; ++i) arr[i+tmp.length]=((int[])val)[i];
        }
        public void rawPrint() {
            for(int i=0; i<arr.length; ++i) System.out.print(arr[i] + " ");
            System.out.println("");
        }
    }
    

    実行例

    $ javac Adder.java  AdderImpl.java  ArrAdderImpl.java  IntAdderImpl.java  MultiAdder.java  sample.java && java Sample
    2
    1 1 
    10
    1 1 1 1 1 1 1 1 1 1 
    2
    
    0
    詳細設定を開く/閉じる
    アカウント プロフィール画像 (本文下)

    Javaちょっとできるプログラマ。教育業界のエンジニアです。

    記事の執筆者にステッカーを贈る

    有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

    さらに詳しく →
    ステッカーを贈る コンセプト画像

    Feedbacks

    Feedbacks コンセプト画像

      ログインするとコメントを投稿できます。

      関連記事

      • Spring Security フォームログインのサンプルコード
        Spring フレームワークによる Web アプリケーション開発で、ログイン処理を実装する際は Spring Security が便利です。ここでは特に Spring Boot で Web アプリケーションを開発する場合を対象とし、フォームによる ID/Password ログインを行うためのサンプルコードをまとめます。 公式ドキュメント [Spring Security チュートリアル](http...
        えびちゃんえびちゃん12/4/2019に更新
        いいねアイコン画像0
      • Java配列の宣言方法 (C/C++との違い)
        Javaの配列 Javaの配列宣言方法はC/C++と似ているようで若干異なる。 初期化しない場合 C/C++の int array[10]; はJavaでは int array[] = new int[10]; となる。同様にC/C++の int array[3][3]; はJavaでは int array[][] = new int[3][3]; となる。 初期化
        てんとうむしてんとうむし5/13/2018に更新
        いいねアイコン画像0
      • PlantUML による UML 図の描き方
        サムネイル画像-c788fffde5
        PlantUML はテキスト形式で表現されたシーケンス図やクラス図といった UML (Unified Modeling Language) 図の情報から画像を生成するためのツールです。簡単な使い方をまとめます。 インストール方法の選択 Atom や Eclipse のプラグインをインストールしてエディタから利用する方法、JAR をダウンロードして Java コマンドで実行する方法、Redmine ...
        kentakenta1/21/2020に更新
        いいねアイコン画像0
      • Akka HTTP サンプルコード (Scala)
        サムネイル画像-a98142497c
        Akka アクターを用いて実装された汎用 HTTP フレームワークです。Spray の後継です。コアモジュールである akka-http-core は 2016/2/17 に experimental が外れました。akka-http などのいくつかのサブモジュールは 2016/3/1 現在 experimental のままですが、基本的な
        雄太雄太10/7/2021に更新
        いいねアイコン画像0
      • Kestrel の使用例
        Kestrel は Message Queue (MQ) の実装のひとつです。一般に MQ はアプリケーション間やプロセス間、スレッド間で非同期に通信するために用いられます。メッセージの送信側は MQ に書き込めば受信側の応答を待たずに次の処理に非同期に進むことができます。Kestrel はわずか 2500 行程の Scala で実装されており JVM で動作します。MQ 自体はメモリ上に存在する...
        したくんしたくん10/12/2017に更新
        いいねアイコン画像0