クラス図の継承/インターフェース実装における矢印の向きついて、SOLID原則(のO)からなんとなく理解した
結論、疎結合で書けばクラス図がスッキリするため。
「継承する/実装する」という語感から、より上位にあるものを受け継ぐというイメージがあり、「下される」ことの図示であれば親クラス(インターフェース)>子クラス(実装)の向きの方が直感的ではないかとずっと疑問だった。
継承/インターフェース実装により、子のインスタンスや実際のオブジェクトを直接参照・検知する必要なく、基部から処理を実行できるようになる。
クラス図でその図示を行う際、呼び出し側から何本も線を引いて実体と結びつける(密結合)よりも、「概念的に同じタイプの処理をしている」ことを示す親1個だけに線を引くほうがスッキリしてわかりやすい(疎結合)。
呼び出す側からの矢印の向きはプロジェクトのメイン部分であり、内部の処理に関わってしまう結合になりがちなため、そこが多くなると流れが複雑になって良くないのだと思う。
独自の処理ではあれど概念的に同じグループとして、派生するのではなく属する/集約することを示すルールとして、メインの処理である呼び出す側に合わせた都合の良い書き方なのだろうという結論になった。
具体例
SOLID原則でのOは”Open-Closed”の頭文字で、「機能の拡張において、修正の必要がないようなコーディングを心がけよ」ということ。
unityで、例えばタッチしたオブジェクトのタグを判別し、その後の処理を分岐させるという処理があったとする。
これをifなりswitchなりでタグを網羅して分岐させた場合、新たなタグを追加(機能拡張)する際にコードの追加修正が伴うし、当然コードの量が多くなるため、Open-Closedに則って言えば良くない形と言える。
呼び出す側が子の内容を知る必要はないので、具体的な処理は個別のオブジェクトに詳述させたいのだが、実体が大量にある場合などでそれらを参照するのも密結合となり、修正の際に網羅するのも手間である。
そこで考えるべきなのが、それらの実体は「タッチしたオブジェクトのタグを判別し、その後の処理を分岐させる」という処理の基部では概念的に同じであるということである。
つまり「タッチ可能なオブジェクト」としてひとまとめにできるグループであり、共通のインターフェース(IInteractableとかとして)を実装させることができる。
よって、「タッチしてタグを判断される」という基部が同じオブジェクトに上記インターフェースを実装すれば、タッチする側=呼び出す側での処理をつぶさに書く必要もなく、実装した側(より末端の、より下流に影響の少ない方)での詳細なコーディングが可能となる。
unityではGetComponentでインターフェースを取得できるので(これ知らなかった)、呼び出す側でifやswitchでゴリ押しコーディングしていた場所が、
obj.gameObject.GetComponent<IInteractable>().Hoge();
とかの記述だけで済むようになる。
加えて、以降なにかバグった際、その原因はより下流の実体側での処理にあるだろうと切り分けられるため、こちらに手を加える必要もない。
っていうようなことを図示するために、継承/インターフェースの矢印が直感に反する向きになっていたのではないか、と結論付けたわけでした。
この記事が気に入ったらサポートをしてみませんか?