🐹

ソフトウェアアーキテクチャをかじって得られたミニマルなメンタルモデル

2024/12/18に公開

はじめに

最近、改めてソフトウェアアーキテクチャを学び始め、その中でソフトウェアアーキテクチャに関するミニマルなメンタルモデルが自分の中にあることに気づいたので、共有いたします。
最初に断っておきます、ミニマルなメンタルモデルは実世界では役に立たないとよく言いますが、私が今回紹介するものもその類ですのでご承知おきください。
これから、学びたいという人には簡単な型としてご理解いただくと、今後、ソフトウェアアーキテクチャについて学んだ時に理解が進みやすくなるかと思います。

想定読者

  • ソフトウェアアーキテクチャについてこれから学び始めたいという方
  • クリーンアーキテクチャとかドメイン駆動設計とか名前だけしか知らないよって方
  • 知らない単語は自分で調べるよって方(すみません、短時間で書き上げたので補足が色々足らないです。。。)

ソフトウェアアーキテクチャ

代表的なソフトウェアアーキテクチャのご紹介

とりあえず、名前だけ並べておくので、興味がわいたら自分で調べてみてください。ドメイン駆動設計は厳密にはソフトウェアアーキテクチャではない認識なので割愛しています。

  • クリーンアーキテクチャ
  • オニオンアーキテクチャ
  • ヘキサゴナルアーキテクチャ(ポート&アダプター)
  • レイヤードアーキテクチャ

私の理解と学んで感じたアーキテクチャのよく見る点

ソフトウェアアーキテクチャはトレードオフの見極めが重要

ソフトウェアアーキテクチャについては、銀の弾丸はなく、実装したいものの複雑性や特性にそってアーキテクチャを決めることが重要です。
オライリーのドメイン駆動設計をはじめようを訳された増田さんも発表の中で、以下のようにアプリ特性に沿って実装方法を判断するという話をしています。

引用元:ドメイン駆動設計の実践(speakerdeck

とはいえ、複数のソフトウェアアーキテクチャを使いこなすのはコストが高いので、私としては簡略化した戦術DDDあたりをメインにしながら、ミニマルなメンタルモデルを使って他のアーキテクチャについても理解をするというスタンスを取ろうと思っています。

コアロジックは最も中核に置いて他の層に依存させない

ビジネスで一番大事なコアロジックは、最も中核な部分に置いて他の層に依存させないというルールがあります。これにより、アーキテクチャの中で最も価値が高いコア(ビジネス)ロジックを変化に耐えられるようにしています。コアロジックは、DDDでいうところのドメイン層になります。
クリーンアーキテクチャ、オニオンアーキテクチャがわかりやすい例ですが、以下のクリーンアーキテクチャの図を見ると以下のようにコアロジック(Entities/Enterprise Business Rules)が中心に来ています。図の中の矢印は依存の方向性を表しており、円の中心にあるコアロジックは他の層に依存しないようになっています。
依存ってなぁに?って人はとりあえず、とあるモジュールに依存しているというのは、とあるモジュールをインポートしてるとでも思っておいてください。依存すると、依存しているコードに変更があった場合に、影響が及ぶ可能性を考慮しなければなりません。

引用元:The Clean Code Blog

外部とのやりとりにはリポジトリパターンで抽象化する

従来のレイヤードアーキテクチャでは、素直に実装するとドメイン層(コアロジック)がデータのやり取りのために、インフラストラクチャ層(RDB操作等のデータ永続化のための層)に依存してしまいます。現代のソフトウェアアーキテクチャでは、依存関係逆転の原則に従うために、インターフェースリポジトリパターンを用いて、ドメイン層ではインターフェースを定義し、インフラストラクチャ層では、インターフェースに基づいてリポジトリを実装いたします。こうすることで、コアロジックにインフラストラクチャを依存させない、疎結合な設計が実現できます。

コアロジックを実現するドメインモデルは、高凝集・低結合を目指す

高凝集というのは、関連性の高い責務・機能が一箇所にまとめられている状態を指します。
ドメインモデル固有のロジックやルール、振る舞いを自らのモデルの中に完結的に持ち、外部に分散させないことが求められます。
これにより、関連ロジックが一箇所にまとまった状態になり、変更容易性の向上や、ドメインモデル自体のロジック・ルール等の理解のしやすさの向上にもつながります。
個人的には、クラス内に関連メソッドがまとまった状態は、IDEの補助が効くので大変好ましいです。
実際には、ドメインモデル間を横断するような処理があった場合、どちらに実装すべきか等の悩みが出てきます。マークザッカーバーグさんの「Done is better than perfect.」の言葉を胸に頑張りましょう。
低結合というのは、ドメインモデル間が必要最低限のやり取りで済むようにし、互いに強く依存し合わない状態を指します。
低結合を維持することで、ドメインモデルに変更があっても他のモデルへの影響を最小限に抑えられ、保守性が向上します。

ミニマルなメンタルモデル

想定読者の方が、上記の内容を読んでもほとんど理解がすすまなかったのではないでしょうか。
そこで、下記のユースケース層とドメイン層の私の理解だけ覚えていただけたらと思います。ユースケース層というのは、アプリのユースケースに該当します。アプリがECサイトだとすると、商品一覧を見る、商品を購入する等です。ドメイン層にはたくさんの部品がありますが、こちらは、DDDで用いるような値オブジェクトやエンティティやドメインサービスを想定しています。

このような作りにすることで、以下のようなメリットがあります。

  • 部品単位で動作するように設計しているため、拡張性やモビリティが高い
  • 部品はユニットテストが容易で品質を高やすい
  • 値オブジェクト等は、自身の状態を検証するので部品が不正な状態でないことを担保できる

上記さえ、覚えておけば、後は、リポジトリパターンでインフラとやりとりするということと、ユースケースをプレゼンテーション層から呼び出すだけですので、とりあえずの実装はできるようになるかと思います。

最後に

ソフトウェアアーキテクチャの話をしていると、設計にどこまで時間をかけるべきかという議論がでますが、その話をしている時、私はよくファーストチェス理論が頭をよぎります。
ファーストチェス理論とは、チェスの名人が「5秒で考えた打ち手」と「30分考えた打ち手」を比べると86%は同じになる、という理論のことです。 つまり、判断する場面に出会った時、あれこれ迷っても、多くの場合、結局結論は変わらない、という意味で使われることが多く、下手な考え休むに似たりやビジネスマンの即断即決が重要という流れで引用されます。
私の視点は少し違って、プロであれば短時間でも8割正答に辿り着くというところを重要視しています。例えば、周りにプログラムなんて動けばいいよ(綺麗に書いてもしゃーないんだから)って言いながら、綺麗なコードを書く方はいらっしゃいませんでしょうか。もしかすると、彼らは綺麗に書いているつもりはなく、最初に思いついたコードが綺麗だっただけなのかなと思いを馳せると、早く自分もプロになりたいものだと思ってしまいます。

Nishika Tech Blog

Discussion