アプリケーションの外側と内側

# はじめに

ソフトウェアアーキテクチャの話をするときに内側と外側という言葉を聞いたことがあるかもしれません。私はよく言葉にします。なにかの説明なしに伝わる人もいれば、十分な説明をしてやっと伝わることもあります。説明なしに伝わる人が優秀というわけではありませんが、少なくとも内側と外側という考えを持っている人と持っていない人がいるのは事実なようです。そこで、ソフトウェアアーキテクチャにおける内側と外側とは一体何を指しているのかを[多層アーキテクチャ](https://ja.wikipedia.org/wiki/%E5%A4%9A%E5%B1%A4%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3)と[ヘキサゴナルアーキテクチャ](https://blog.tai2.net/hexagonal_architexture.html)を比較して言葉にしたいと思います。

# 多層アーキテクチャ

多層アーキテクチャとは「アプリケーションを複数の"層"に分け、それらを独立したモジュールとして開発・保守する」ソフトウェアアーキテクチャパターンの一つです。[^1]代表的な多層アーキテクチャといえば、３層アーキテクチャでしょう。３層アーキテクチャは以下の３つの層にアプリケーションを分割します。

* プレゼンテーション層 ... アプリケーションの表示方法やその入力方法に関する関心事を持つ。
* アプリケーション層 ... アプリケーションのビジネスロジックに関する関心事を持つ。
* データベースアクセス層 ... アプリケーションの永続化に関する関心事を持つ。

![3層アーキテクチャ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115251/0320846b-db46-8336-ce53-2c4ae0a09744.jpeg)

多層アーキテクチャでは各層がそれよりも下位の層を隠蔽し、上位の層へサービス（機能）を提供します。[^2]３層アーキテクチャではプレゼンテーション層、アプリケーション層、データベースアクセス層へと依存が発生しており、アプリケーション層はビジネスロジックや永続化に関する関心事をプレゼンテーション層から隠蔽します。データベースアクセス層は永続化に関する関心事をプレゼンテーション層、アプリケーション層から隠蔽します。

この隠蔽の仕組みによって、上位の層では下位の層がどのように処理を行っているのか意識する必要がなくなります。

## 多層アーキテクチャの懸念点

アプリケーションの関心事を大きく分類すると方針と詳細に分けることができます。[^3]

* 方針 ... システムがやりたいこと。例えば、条件判定（１００万円以上は送金できない）や処理の順番（入金が確定してから商品を配達する）
* 詳細 ... システムがやりたいことを実現する技術要素。例えば、情報を表示するためにHTMLを使用する、やデータを永続化するためにリレーショナルデータベースを使用する、といった事

多層アーキテクチャではアプリケーションが **"何をするのか"** という方針に当たるビジネスロジックが、 **"どのようにするのか"** という詳細に依存することになります。方針が詳細に依存する場合、詳細の変更が方針に影響を与えます。3層アーキテクチャではアプリケーション層がデータベースアクセス層に依存しています。データベースをリレーショナルデータベースからNoSQLへ変更する場合、アプリケーション層が影響を受け、再構築を余儀なくされます。

方針が詳細に依存することにより、アプリケーションを一度構築したあとで技術要素を容易に変更することができなくなります。これは次の2つの状況を作り出します。

* 使用する技術要素を開発の途中で変更することが困難になる。
* リリース後、技術要素を変更することが困難になる。

特定の技術要素はすぐに時代遅れになります。新しい通信プロトコルや、新しい永続化技術など、常に新しいものが出てきています。**アーキテクチャはこのような詳細の変化から方針を保護出来る（変更の影響を受けない）構造を持たなくてはなりません。**

# ヘキサゴナルアーキテクチャ

ヘキサゴナルアーキテクチャでは方針と詳細をアプリケーション層とアダプタ層に分け、詳細が方針に依存する構造を持ちます。

* アプリケーション層 ... アプリケーションの方針（ビジネスロジック）関する関心事を持つ。
* アダプタ層 ... アプリケーション層の入力・出力を変換することで具体的な技術要素を使用できるようにする。

![ヘキサゴナルアーキテクチャ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115251/103daaf7-21c8-954e-f76a-34813eb71bd0.jpeg)

これは、PCをイメージするとわかりやすいかもしれません。PCは通常、複数の入力・出力をサポートしていますが具体的に何がつながっているかは気に留めません。ディスプレイが4Kであろうが8Kであろうが、マウスがトラックパッドであろうがレーザーマウスであろうが、それぞれが標準化された規格のとおりに信号を送受信すれば適切に機能します。

ヘキサゴナルアーキテクチャもこれと同じです。アプリケーション層は入力が何であるか（HTTP通信によるものなのか、それともテストランナーによるものなのか）、出力が何であるか（リレーショナルデータベースかNoSQLか）には関心を持ちません。それぞれの技術要素が、アプリケーション層で定義しているインターフェイスを守ってやりとりをすれば適切に動作します。

アプリケーション層で定義したインターフェイスと技術要素間のやり取りはアダプタ層が担当します。アダプタ層はアプリケーション層で定義されている入力形式（メソッドの引数）に合わせて技術要素の入力を変換し、アプリケーション層で定義されている出力形式を変換して技術要素に合わせて出力を行います。ヘキサゴナルアーキテクチャはこのように、 **方針が詳細を知らなくて済むようにして、詳細の変更の影響を方針に与えないようにします。**

![アダプタ層の例.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115251/da5e8c2f-c086-d63d-5f5e-2d9421d87f1c.jpeg)

ヘキサゴナルアーキテクチャを適用することで、以下の効果が期待できるようになります。

* 使用する技術要素を開発の途中で変更することが容易であり、技術要素の選定を先延ばしにできる。
* リリース後、技術要素を変更することが変更することが容易であり、アプリケーションの寿命を伸ばすことができる。

つまり、アプリケーションの内側と外側というのは上記の図でも分かる通り、アプリケーション層（内側）とアダプタ層（外側）に当たります。アプリケーションをこの２つの視点で捉えることで、より変更に強く、より長く使用できるアプリケーションを構築できるようになります。

# おわりに

この記事ではアプリケーションの外側と内側が何を指すのかを、多層アーキテクチャとヘキサゴナルアーキテクチャを元に説明しました。もしヘキサゴナルアーキテクチャに興味を持ったら以下のサイトを一読すると良いと思います。

* [ヘキサゴナルアーキテクチャ | 翻訳](https://blog.tai2.net/hexagonal_architexture.html)

また、ヘキサゴナルアーキテクチャを具体的にどう実装するのかについては以下の記事で現場適用の事例が公開されています。

* [ヘキサゴナルアーキテクチャ導入事例 | Fintan](https://fintan.jp/?p=1375)

[^1]: https://ja.wikipedia.org/wiki/%E5%A4%9A%E5%B1%A4%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3
[^2]: Patterns of Enterprise Application Architecture, p17
[^3]: Clean Architecture 達人に学ぶソフトウェアの構造と設計