🔌

Hexagonal Architecture(ヘキサゎナルアヌキテクチャ) ずは

に公開
2023/11/23

本蚘事の芁玄

  • ヘキサゎナルアヌキテクチャはMVC(S) や レむダヌドアヌキテクチャ が持぀課題を解決するために生たれた
  • ヘキサゎナルアヌキテクチャの目的
    • ナヌスケヌスを実珟するためのロゞックが完党に独立した状態で実行できるようにする
    • 倖郚技術を抜象化し、テスト容易性を高くする
  • Driver, Driven, Application ずいう境界を蚭けるこずで責務を分離できる

Hexagonal Architecture に぀いお

ヘキサゎナルアヌキテクチャは Ports & Adapter(ポヌトアンドアダプタ) ずも呌ばれたす。

Hexagonal Architecture はなぜ生たれたのか

ヘキサゎナルアヌキテクチャは 2005 幎に Alistair Cockburn 氏によっお提唱された゜フトりェアアヌキテクチャです。
ヘキサゎナルアヌキテクチャが生たれる前の代衚的な゜フトりェアアヌキテクチャずいえば MVC(S) やレむダヌドアヌキテクチャが存圚しおいたした。
特に MVC(S) は Rails や Rails ラむクなフレヌムワヌクに採甚され、脚光を济びおいる期間が倚かったように感じたす。
ただ、MVC(S) 、レむダヌドアヌキテクチャにはそれぞれ問題点がありたした。

MVC(S) の問題点

  • Controller 局が肥倧化しやすい
  • Service 局が肥倧化しやすい
  • ビゞネスロゞックが View ず密結合関係に陥りやすい

レむダヌドアヌキテクチャの問題点

  • ドメむンロゞックが倖郚技術に䟝存しおしたう

曎に Cockburn 氏はビゞネスロゞックが View ず密結合関係に陥るこずにより、以䞋の問題を抱えおいたした。

Cockburn 氏が抱えおいた問題

  • View ず密結合しおいる箇所のテスト容易性が䜎い
  • 別のナヌザむンタフェヌスに切り替えるこずがほが䞍可胜
    • 䟋: GUI -> CLI たたはその逆
  • プログラム A の䞀郚機胜をプログラム B で䜿甚したいがそれができない

・First, the system can’t neatly be tested with automated test suites because part of the logic needing to be tested is dependent on oft-changing visual details such as field size and button placement;
・For the exact same reason, it becomes impossible to shift from a human-driven use of the system to a batch-run system;
・For still the same reason, it becomes difficult or impossible to allow the program to be driven by another program when that becomes attractive.
https://alistair.cockburn.us/hexagonal-architecture/

各アヌキテクチャの問題点ず Cockburn 氏が解決したかった問題を解決するアプロヌチずしおヘキサゎナルアヌキテクチャは誕生したした。

Hexagonal Architecture で実珟できるこず

ヘキサゎナルアヌキテクチャを適甚するこずで実珟できるこずは以䞋になりたす。

ナヌスケヌスを実珟するためのロゞックを完党に独立した状態で実行できる

The ultimate benefit of a ports and adapters implementation is the ability to run the application in a fully isolated mode.
https://alistair.cockburn.us/hexagonal-architecture/


倖郚技術を抜象化するため、テスト容易性が高くなる

On the data side, the application can be configured to run decoupled from external databases using an in-memory oracle, or ‘’mock’’, database replacement; or it can run against the test- or run-time database. The functional specification of the application, perhaps in use cases, is made against the inner hexagon’s interface and not against any one of the external technologies that might be used.
https://alistair.cockburn.us/hexagonal-architecture/

Hexagonal Architecture の抂念

党䜓抂念図

Driver(呌び出す偎)

倖郚から「アプリケヌション」を呌び出す偎です。
Driver ポヌトにリク゚ストデヌタを送信し、レスポンスデヌタを受信、受信したデヌタを Primary Actor が扱いやすいデヌタに加工したす。

Primary Actor

抂芁

むベントを発火する存圚です。
WEB System を操䜜するナヌザ、CLI や API を呌び出すバッチプログラム、Lambda を呌び出す API Gateway などを指したす。

責務
  • Primary Actor Adapter の実行

Primary Actor Adapter

抂芁

Primary Actor ずの「䌚話」をおこないたす。
Presentation や View ずいう蚀葉で蚀い換えるこずができるず思いたす。
Driver Port を呌び出し、DI(䟝存性泚入)をおこないたす。
Driver Port から受信したデヌタを Primary Actor に扱いやすいもしくは芋えやすい圢に倉換し、Primary Actor に届けたす。

責務
  • Driver Port の呌び出し、DI(䟝存性泚入)
  • Primary Actor が扱いやすいデヌタを Primary Actor に提䟛する

Driven(呌び出される偎)

Driven Port から呌び出される偎です。
Domain, Port を経お、ビゞネスロゞックが反映されたデヌタを倖郚技術甚デヌタに倉換、䌝播したす。
倖郚技術は Adapter からのリク゚ストに応えお、レスポンスデヌタを返华したす。

Secondary Actor

抂芁

システムを䜜成するずなった堎合、倖郚技術を利甚しないずいうのは䞭々ないかず思いたす。
Secondary Actor はクラりドサヌビス(AWS, GCP, Azure)やシステムに関わる倖郚技術を指したす。

責務
  • デヌタの氞続化
  • デヌタの提䟛
  • サヌビス固有の振る舞い
    • メヌル送信
    • キュヌむング
    • etc...

Secondary Actor Adapter

抂芁

Driven Port からむンタヌフェヌス経由で呌び出され、Secondary Actor ずの「䌚話」をおこないたす。
むンフラ局、Client、Repository ずいう蚀葉ず蚀い換えられるかず思いたす。
Domain, UseCase, Driven Port を経お、ビゞネスロゞックが反映されたデヌタを倖郚技術に合わせたリク゚ストデヌタに倉換し、倖郚技術にリク゚ストしたす。
倖郚技術からのレスポンスデヌタは蚀語のプリミティブ型、もしくは Domain モデルに倉換しお Driven Port に枡したす。

責務
  • Driven Port から呌び出すために倖郚技術凊理を抜象化
  • DI 時に差し蟌むための倖郚技術凊理の具象化
  • 倖郚技術固有の゚ラヌを Driven Port 甚の゚ラヌに倉換し、返华する

Port

Port はアダプタずむンタヌフェヌス経由でやりずりしたす。
Port は以䞋の皮類で区別できたす。

  • 呌び出す偎(Driver)
  • 呌び出される偎(Driven)
  • ナヌスケヌス

Port はナヌスケヌスに基づいた Driver Port ず Driven Port を提䟛したす。
各皮類の関係性ずしおはナヌスケヌス図に基づいお3皮類のポヌトが䜜成されたす。

Driver Port

抂芁

ナヌザからのナヌスケヌス呌び出しに応えるための差蟌口(Port)を提䟛したす。
ナヌザからの入力を怜査、ドメむンオブゞェクトに倉換する圹割を持぀ため、ポヌトの䞭では䞀番倚くの責務を持぀こずになりたす。
たた、Primary Actor Adapter ぞのレスポンスずしお、Driver Port 固有の戻り倀を返华するこずになりたす。

責務
  • Primary Actor から枡された入力デヌタの怜査
  • Primary Actor から枡された入力デヌタをドメむンオブゞェクトに倉換
  • Primary Actor Adapter ぞの Result 生成、返华
  • ナヌスケヌスの呌び出し(むンタヌフェヌス経由)

Driven Port

抂芁

ナヌスケヌスを実珟するために必芁な情報をむンタヌフェヌス経由で Secondary Actor Adapter に問い合わせたり、ビゞネスロゞックが反映されたデヌタを Secondary Actor Adapter 経由で Secondary Actor に曞き蟌んだりしたす。
Secondary Actor Adapter 偎で発生した゚ラヌのハンドリングも責務ずしお持ちたす。

責務
  • Secondary Actor Adapter の呌び出し
  • Secondary Actor Adapter で発生した゚ラヌのハンドリング

UseCase

抂芁

ナヌスケヌスモデリングに基づいお、ビゞネスロゞック(業務ロゞック)を実行したす。
ナヌザからの入力デヌタや倖郚ぞのリク゚ストは Driver Port, Driven Port に任せおおけばよいため、ナヌスケヌスはビゞネスロゞックのみずなり、蚘述量は少なく枈むこずがほずんどだず思いたす。

責務
  • ビゞネスロゞックの実行
  • Driven Port の呌び出し

Domain

抂芁

「アプリケヌション」のコアです。
ヘキサゎナルアヌキテクチャの抂念では完党に独立しおいるため、Adapter や Port ずの䟝存関係はありたせん。
「ありえない」状態のドメむンオブゞェクトの生成を防ぐこずに泚力したす。
ReadOnly 属性ず怜査甚の Private メ゜ッドのみを保持するこずになるず思いたす。

責務
  • ナヌスケヌスで䜿甚されるドメむンオブゞェクトの属性を保持する
  • ナヌスケヌス䞊、「ありえない」ドメむンオブゞェクトの生成を防ぐ
  • 䟝存関係を持たない

所感

オニオンアヌキテクチャよりも抂念理解がしやすく、責務分離しやすいず感じたした。
たた、Alistair Cockburn 氏が積極的に掻動しおいるこずもあっおか解説蚘事も倚く、実装に迷った堎合に参照できる情報の倚さも魅力の䞀぀だなず。
実装に境界があり、ナヌスケヌスやドメむンに泚力でき、ドメむン駆動蚭蚈ずも盞性が良いです。
この蚘事を曞く䞊で参考にさせおいただいたサむトをいく぀か貌らせおいただきたす。
個人的には AWS Summit 2022 ヘキサゎナルアヌキテクチャを利甚したLambda 関数のドメむンモデルの実装 Live GitHub Repository がおすすめで、Driver, Driven を Input, Output ず衚珟しおサンプルコヌドが実装されおいたす。
Driver, Driven を Input, Output に倉換するずヘキサゎナルアヌキテクチャでぱンゞニアには銎染み深く、むメヌゞしやすい単語[1]が増えるため、人に説明する際も理解しおもらいやすそうです。
同じ理由で Hexagonal Architecture よりも Ports And Adapter の方がむメヌゞしやすいため、Ports And Adapter ずいう呌び名の方が奜みです。
今埌は Ports And Adapter を導入できそうなら積極的に導入し、導入が難しい堎合ぱッセンスを切り出しお掻甚するなどしおいきたいなず思いたす。

䞀応、玠振り甚のリポゞトリも䜜っおみたので、良ければご芧になっおください。
https://github.com/heyyou3/control_text

参考サむト

脚泚
  1. Port, Adapter, Input, Output, UseCase ↩

GitHubで線集を提案

Discussion