デザインパターンの一つ、BridgeパターンをQtとC++を使って勉強してみました。
実際にアプリを作ってみることで、パターンの使い方を学びたいと思います。

橋渡しをするパターン
Bridgeパターンとは
実装部分と機能部分を分割して、その間を橋(Bridge)でつなげるようなパターンとなります。
こうすることによって、クラスを複数方向に拡張することが可能となります。
Wikipediaに参考になる利用例がありましたので、具体例がほしい人は確認してみると良いと思います。
Wikipediaには、Bridgeパターンを使う良い例として、
(1)クラスの追加が困難である場合
(2)コードの複製が出てきちゃうような場合
とあります。
クラス図

AbstractionクラスとImplementorクラスの間にある線がBridgeとなります。
そして橋の左側にあるのが、Abstractionクラスの機能系のクラス。
右側にあるのが、Implementorクラスの実装系のクラスです。
なので、例えば新規機能を追加したければ左側だけを更新すればよくなります。(実装系であれば右)
作成したアプリ
猫と犬の鳴き声と、大阪出身の猫と犬の鳴き声を表示するアプリを作成しました。
犬と猫はImplementorクラス、鳴き声と大阪弁の鳴き声はAbstractionクラスで実装しました。

ただ、「〜やねん」を語尾につけただけのほんとしょうもないアプリです・・
コードと実行結果

ボタンを押すことで、猫と犬のそれぞれの鳴き声を表示する非常にシンプルなものとなっています。
コードを分解
では、各クラスの説明をしていきます。
mainwindow.h / mainwindow.cpp
ここでは、UI部分の実装やロジックを入れています。
animal-super.h / animal-super.cpp
クラス図でいうImplementorクラスになります。このAnimalSuperクラスからCat, Dogクラスを継承します。
cat-sub.h / cat-sub.cpp / dog-sub.h / dog-sub.cpp
クラス図でいうConcreteImplementorクラスになります。
Cat, Dogともに同じ関数を書いているのでまとめて紹介しますが、
猫、犬それぞれ鳴き声と画像のパスをメンバ変数として保持し、Getter関数も実装します。
behavior.h / behavior.cpp
クラス図でいうAbstractionクラスになります。
コンストラクタで、Implementorインスタンスを受け取り、playSound関数でインスタンスから鳴き声関数を呼んでいます。
osaka-behavior.h / osaka-behavior.cpp
クラス図でいうRefinedAbstractionクラスになります。
大阪弁バージョンという機能追加をしたかったので、Behaviorクラスを継承し、新たにplaySoundWithDialect関数を追加しました。
どういう時に使うのか?
うーん・・・
継承するクラスが多くなって複雑になりそうな場合や、
実装部分と機能部分を分けておいたほうがいい場合に有用なんですかね?
でも、そんなの実装してみてからじゃないとわからないよな・・・
実装してみてから気づくものなのかしら?

ロジックはわかるけど、いざどういうときに使用するかがやっぱりまだ難しい
まとめ
Bridgeパターンのアプリを作成してまとめてみました。
実装と機能を別々に分けてアーキテクチャを組む場合に使えるパターンですね。
他のデザインパターンについてはこちらをご覧ください。
参考サイト

にほんブログ村に参加しております!よろしければクリックお願いします 🙂
にほんブログ村



コメント