【Outsystems】モジュール・アーキテクチャ設計について

## はじめに
Outsystemsを使用した開発を進める際、システムの要件をどのようにモジュールやアプリケーションに分化させ構造を設計するのか参考サイトを見ながら自分が読み取れた内容をまとめる。

間違っていたらご助言を...

## システムの構成
Outsystemsは1つ以上の「モジュール」で構成される「アプリケーション」という単位で管理される。(LifeTime管理)

Service Studio画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/ec49aafe-4366-7825-0f66-a6a3169507d8.png)
システムの構造を大きく分割すると上記のModuleとそれを束ねるApplicationで構成される。

## Architecture Canvas
OutsystemsではModule/Applicationの機能を3つのレイヤーに分けて整理する方法を推奨している。
このアーキテクチャーフレームワークの名前がArchitecture Canvas

参考：
[[OutSystems]Architecture Canvasを使った設計の骨格](https://qiita.com/jyunji_watanabe/items/147980fd974774e2fc39)
[アーキテクチャフレームワークを使用したアプリ設計](https://www.outsystems.com/ja-jp/training/courses/193/designing-apps-using-an-architecture-framework/)
[OutSystemsアプリケーションのサービス指向アーキテクチャ](https://success.outsystems.com/documentation/best_practices/architecture/designing_the_architecture_of_your_outsystems_applications/service_oriented_architectures_for_outsystems_applications/)

- システムの構造を3つのレイヤーに分類する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/8e01cfda-e7bd-d33f-a24a-f63439d92750.png)

### End User：エンドユーザー
再利用しない要素を置く。ユーザーの要求を直接実現する要素を配置する(UI/UX)
Reactive Web Appを配置する
ex：画面UI、再利用しない業務ロジック、Processなど

### Core：コアレイヤー
再利用可能な部品で、業務要求に関連するものを配置する。
ビジネスロジック
Serviceモジュールを配置する
ex：Expose API (REST/SOAP)、業務要求に関わるWidget、業務ロジック

### Foundation：基盤レイヤー
再利用可能な部品で、業務要求に直接関わらないものを配置する。
Librariesモジュールを配置する
ex：Extension、UI Pattern (OutSystems UI Widget、再利用するUI、Theme)

[アーキテクチャから開発へ](https://success.outsystems.com/ja-jp/documentation/best_practices/architecture/from_architecture_to_development/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/b2d293f5-ad6c-3de6-5ab7-9fdb514cb27e.png)


## Moduleの種類
 Applicationは1つ以上のModuleで構成されるが、アーキテクチャのレイヤーに従いModuleが持つべき機能が決まる。
またModuleが持つ事のできる機能はモジュールタイプによって決まる。

参考
[モジュールタイプ(module type)の違いについて調べる[Outsystems]](https://mikan-tech.info/module-type)
[【メモ】OutSystemsのアクション差異](https://qiita.com/yos777/items/46e23d8fffbec58357b4)

以下はモジュールの情報について読み取れたものを表記

### Reactive Web Appモジュール
特に機能的な制限がない？
UI 関連の要素を実装するには、リアクティブ Web、モバイル、または従来の Web モジュールを使用する必要がある

End User レイヤーに配置されるモジュール

### Serviceモジュール
参考：[サービスを使用して機能を公開する](https://success.outsystems.com/documentation/11/developing_an_application/reuse_and_refactor/use_services_to_expose_functionality/)

Serviceモジュールタイプはアーキテクチャ構成におけるEnd Userに属さないモジュールに使用される。

関心事を分離し(DDD？)、カプセル化が必要なCoreレイヤーに適応される。

UI関連の以下の要素を使用することができない。
- UI アセットのモジュール プロパティ (JavaScript、グローバル エラー ハンドラーなど)
- クライアント側ロジック
- ローカルストレージエンティティ
- セッション変数

### Librariesモジュール
参考：[ライブラリー](https://success.outsystems.com/ja-jp/documentation/11/developing_an_application/reuse_and_refactor/libraries/)

以下引用
>ライブラリモジュールタイプは、以下の原則を念頭に置いて設計されました。

>ライブラリは、ステートレスです。**データベースに情報を保存することやエンティティに直接アクセスすることはできません。
**ライブラリの要素は、コンシューマアプリケーションのコンテキストでのみデプロイされます。**スタンドアロンのアプリケーションとしてデプロイされることはないため、Platform Serverのアプリケーションサーバーの負荷が低減されます。
ライブラリは、それらを参照しているアプリケーションがデプロイされているデータベースに依存しません。

データベースに接続しない画面部品、テンプレートやコンポーネントの考え方に近い。
APIの外部連携機能は使えるので、外部連携部品を作るのに適している。

以下の要素を使用することができない。
- Data(EntitiesやStructureなど）
- InterfaceのScreen要素（Block要素は使用可能）
- Logic内のServer Actionでデータベース操作系の機能（AggregateとSQL)


## モジュール間の依存関係のルール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/cc532cd9-b6ca-67ac-d093-96bcb3a483c3.png)
1.上方参照をしない(全レイヤー)
2.側方参照しない(エンドユーザーレイヤー)
3.循環参照しない(全レイヤー)


1.上方参照の問題点
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/c338faa7-cb0c-b4c5-30d8-359b95545cfb.png)
EがAに依存すると、Dの依存に循環が発生する
その結果、Dに依存するBが全モジュールに依存し、認識されていないモジュールで行われた変更による影響を絶えず受ける

2.エンドユーザー間の参照の問題点
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/50c3a6eb-2f7c-aaea-e491-ed4125179844.png)
最上位のモジュール同士が結合すると、下位レイヤーからの膨大な量の間接的依存をもたらす傾向がある
エンドユーザーが他のモジュールに参照される事はない

3.コア、ライブラリ間で循環しないの例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/c353e858-d53a-7269-c4f3-3ae7f53d4a44.png)
循環は予期しない影響や管理しにくいコードを伴うため、どのような場合でも望ましくありません。とのこと。

参考：[アプリケーションアーキテクチャを検証する](https://success.outsystems.com/ja-jp/documentation/best_practices/architecture/designing_the_architecture_of_your_outsystems_applications/validating_your_application_architecture/)

実装されたモジュールがこれらのアーキテクチャルールに従っているかどうかは、[Discovery](https://www.outsystems.com/forge/component-overview/409/discovery)ツールを使用して自動的に確認できます。とのこと。

## モジュールの「密結合」「疎結合」

参考：[強い依存関係と弱い依存関係について理解する](https://success.outsystems.com/ja-jp/documentation/11/developing_an_application/reuse_and_refactor/understand_strong_and_weak_dependencies/?_gl=1*fx22oj*_ga*MTc4NTMxMjI2MS4xNjg0MDQ1NjE0*_ga_ZD4DTMHWR2*MTY4NTU0MTYyMC4xMi4wLjE2ODU1NDE2MjAuNjAuMC4w)

モジュール間の依存関係の中で何の機能を使用するかにより、結合の強さが決まる

### 強い依存関係：密結合

以下の要素を再利用した場合、コンシューマのプロデューサに対する依存関係は強い依存関係になります。

サーバーアクション
クライアントアクション
ブロック
画像
リソース
スクリプト
テーマ
ロール
プロセス
プロセスアクティビティ

### 弱い依存関係：疎結合

以下の要素を再利用した場合、コンシューマのプロデューサに対する依存関係は弱い依存関係になります。

画面
サービスアクション
データベースエンティティ
ローカルストレージ
静的エンティティ
ストラクチャ

依存関係を持つモジュールの更新に関わるらしい。(AをPublishするとBが影響を受ける。など)
実際作成しないとよくわからない

## まとめ
やってみないと分からないと思ったので、次回はアーキテクチャーのトレーニング動画で例として設計されている診療予約アプリを、実際にPublishするところまでやってみる。

参考：[アーキテクチャフレームワークを使用したアプリ設計](https://www.outsystems.com/ja-jp/training/Learn_Lesson_View.aspx?LessonId=2305&LessonName=designing-an-architecture-an-example&)