DDDのパターンをOutSystemsの要素にマッピングする

DDDを実践するに当たり、

- ドメインを「モデリング」する
- 「パターンの力を借りて」モデルを実装に落とす

があるらしく、概ね前者に該当する部分を
[OutSystemsのDDD情報まとめ](https://qiita.com/jyunji_watanabe/items/357470b3b632c232ce76)
にまとめた。これは、OutSystemsの公式ドキュメントに基づいている。
（ただ、このやり方は「モデリング」に完全に対応しているのか？　公式の手法に修正は必要ないのか？　という疑問はある。それについては別の機会に検討する）

この記事では、「ドメイン駆動設計入門 ボトムアップでわかる！ドメイン駆動設計の基本」という本を読んで、DDDのパターンをOutSystemsの要素にマッピングしてみる。

# OutSystemsはオブジェクト指向ではない
DDDはオブジェクト指向でなければできない、というようなものではないらしい。
しかし、オブジェクト指向開発の現場で発展してきたことから、既存のパターンやアーキテクチャはオブジェクト指向言語を前提としていると思われる部分がある。
## カプセル化
クラスがないので、クラスにデータ＋操作のカプセル化することができない。
代わりにCore Entity Patternを使って、データ（Entity）とその操作（Public Action）を特定のモジュールに封じ込める。
→[Entityの更新を1箇所に限定するパターン](https://qiita.com/jyunji_watanabe/items/2858f386cdb8cbe5258f)
このパターンそのものは、Entityのためのものだが、Structureに対しても同様のことはできる。

注意点として、

- モジュール内の他要素はそのEntityに自由に触れる
- Public=YesにしたEntityはExpose Read Only=Yesに設定しても、AggregateやSQLによる検索は可能
- EntityやStructureに値を設定することそのものはConsumerから自由にできる（操作するためのActionを提供できるだけ）。Entityなら永続化のときにロジックを強制することはパターンで可能

## Interface
オブジェクト指向でいうinterfaceに対応するものがない。
ので、依存関係逆転の原則に基づく実装ができず、レイヤー上位のモジュールから下位のモジュールへの一方通行の参照関係になる。

# 各パターンのArchitecture Canvasイメージ
矢印：参照関係
（）で囲まれたテキスト：OutSystemsの要素・概念
平文：DDDのパターン名
必ずしも四角形の単位でモジュールになるとは限らない。例えば仕様とドメインサービスは必ずしも分割しなくてもいいかもしれない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/5a97c604-ae32-e20c-753e-158bfb4c76cf.png)

ドメインモデルと対応させて変更していくのは、主にCore Business Layerに配置した要素（一番右はAPI用なので除外）。

# マッピング
DDDを実践してみたら、マッピング先は変わるかもしれない。以下のマッピングは2022/2/5時点の印象に基づく。

| パターン/概念[^1] | レイヤー[^2] | 要素 | 補足 |
|:-|:-|:-|:-|
| 値オブジェクト | Core Business | Structure + Public Action  | Core Entity Patternと同じ形式  |
| エンティティ | Core Business | Entity + Public Action  | Core Entity Pattern。データ永続化を行う先が外部DBや外部サービスならデータに直接アクセスする部分はFoundationになる。外部DBならExtension、外部サービスなら[Integration Pattern](https://success.outsystems.com/ja-jp/Support/Enterprise_Customers/Maintenance_and_Operations/Designing_the_Architecture_of_Your_OutSystems_Applications/05_Integration_Patterns_for_Core_Services_Abstraction)  |
| ドメインサービス  | Core Business | Server Action / Service Action / Expose REST API | 使い分けは、サービス提供先がドメイン内→Server、ドメイン外のOutSystems→Service、OutSystems外→REST  |
| リポジトリ | Core Business/Foundation  | Entity  | 外部DBや外部サービスならFoundationレイヤー |
| アプリケーションサービス  | End User  | Server Action  | DDDのアーキテクチャにおけるプレゼンテーション層の要素とは同じモジュールでもいい気がするが、DDDのアーキテクチャを重視するなら、別モジュールにするかも |
| 依存関係逆転の原則  | 該当なし  | 該当なし  | Interfaceがないので、実現方法は思いつかない。OutSystemsのArchitecture Canvasは上位レイヤーから下位レイヤーへの一方通行の参照だし無視して良い気がしている |
| 集約  | Core Business  | モジュール or モジュール内の1フォルダ  | 一連のEntityに対する更新単位で集約を作るので、Core Entity Patternを作るモジュールに配置するのが良い。集約のルートに当たるものがPublicなActionになる。モジュール内の1フォルダにするとモジュール数は節約できるが、同じモジュール内の他集約の要素から操作できてしまう |
| 仕様  | Core Business  | Server Action  |  |
| アーキテクチャ  | 該当なし   | Architecture Canvas利用  | DDDで出てくるアーキテクチャ（LayerdとかHexagonalとか）のエッセンスを取り入れることは可能。依存関係逆転の原則が使えないので、完全に踏襲するのは無理だと思うが |

[^1]: DDDにおけるパターン名（一部パターンじゃないものもあるが）。OutSystems用語と紛らわしいので日本語訳を採用
[^2]: そのパターンをOutSystemsにマッピングした要素を格納するモジュールが、Architecture Canvasにおけるどのレイヤーに配置されるか

# 参考
各パターンの意味とマッピングの理由については、本を読みながら作ったメモを参照。
[読書メモ：ドメイン駆動設計入門 ボトムアップでわかる！ドメイン駆動設計の基本 1](https://blog.house-soft.info/archives/1859)
[読書メモ：ドメイン駆動設計入門 ボトムアップでわかる！ドメイン駆動設計の基本 2](https://blog.house-soft.info/archives/1869)
[読書メモ：ドメイン駆動設計入門 ボトムアップでわかる！ドメイン駆動設計の基本 3](https://blog.house-soft.info/archives/1875)
[読書メモ：ドメイン駆動設計入門 ボトムアップでわかる！ドメイン駆動設計の基本 4](https://blog.house-soft.info/archives/1877)