Hexagonal Architecture(ãããµãŽãã«ã¢ãŒããã¯ãã£) ãšã¯
æ¬èšäºã®èŠçŽ
- ãããµãŽãã«ã¢ãŒããã¯ãã£ã¯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 ãå°å
¥ã§ããããªãç©æ¥µçã«å°å
¥ããå°å
¥ãé£ããå Žåã¯ãšãã»ã³ã¹ãåãåºããŠæŽ»çšãããªã©ããŠãããããªãšæããŸãã
äžå¿ãçŽ æ¯ãçšã®ãªããžããªãäœã£ãŠã¿ãã®ã§ãè¯ããã°ã芧ã«ãªã£ãŠãã ããã
åèãµã€ã
- ãããµãŽãã«ã¢ãŒããã¯ãã£æå±èšäº
- ãããµãŽãã«ã¢ãŒããã¯ãã£æå±èšäº(æ¥æ¬èªç)
- cockburn æ°ããããã®ãããµãŽãã«ã¢ãŒããã¯ãã£åŠç¿ãµã€ã
- Netflixã§ã®å®è£ äºäŸ
- AWS Summit 2022 ãããµãŽãã«ã¢ãŒããã¯ãã£ãå©çšããLambda 颿°ã®ãã¡ã€ã³ã¢ãã«ã®å®è£ Live è³æ
- AWS Summit 2022 ãããµãŽãã«ã¢ãŒããã¯ãã£ãå©çšããLambda 颿°ã®ãã¡ã€ã³ã¢ãã«ã®å®è£ Live GitHub Repository
-
Port, Adapter, Input, Output, UseCase â©ïž
Discussion