[OutSystems]Mobile Developer Specializationのサンプル問題について解説 1/2(#1-#4)

各問題を確認し、回答に必要な資料への解説をまとめます。
これまでに試験のサンプル問題を解説した記事では、英語の試験問題を使ってきましたが、今回はダウンロードした時点で日本語版試験があるため、そちらを使います。

全部で8問で、この記事では1問目-4問目が対象。

試験問題は、
https://www.outsystems.com/learn/certifications/
の、「Mobile Developer Specialist (OutSystems 11)」項目のリンク「Exam Details (.pdf)」でダウンロードできる資料から。解凍したら、Japaneseフォルダにあるファイルを開いてください。

# 1 Local StorageとDatabaseでのEntityの違い
モバイルアプリケーションにはLocal Storageというものがあり、各端末（iOSとAndroid）内にデータが保存されるEntityを作ることができます。このLocal Storage内のEntityと、WebアプリケーションにもあるDatabase内に作るEntityの違いに関する問題。

Service Studio上での、基本的な性質はDatabase内のEntityと同じです。DatabaseのEntityと同じく主キーは1つのみ。
以下はLocal StorageのEntityのMore...で開くダイアログ。Identifierとして選べるのは1つのみですね。これはDatabaseのEntityと同じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/0db30816-cae5-0102-510f-bc539a4bf556.png)
よって選択肢B「データベースエンティティは複合主キーをサポートするが、ローカルストレージはサポートしない。」は誤り。データベースエンティティも複合主キーをサポートしません。

Local StorageのEntityを作る方法は2つあります。
1. DatabaseのEntityと同じようにEntityを作成し、その中にAttributeを作っていく方法
2. DatabaseのEntityを元に、必要なAttributeだけを選択して作成する方法
（Service Studio上でLocal Storageを右クリックし、Add Entity from Databse...を選択）
よって選択肢C「ローカルストレージエンティティは既存のデータベースエンティティをマッピングする必要がある。」は誤り。1.に書いたようにデータベースエンティティと無関係に定義することもできるため。

Local StorageのEntityも、他のEntityのId属性の型の属性を持つことで参照を持てます。
この参照属性も、データベースエンティティと同じようにDelete Ruleプロパティを持っていますが、Ignore（参照先のレコード削除が行われようとしても、それを防いだり、連動して削除したりしない）に固定です。つまり参照整合性の保証は行われないため、選択肢Aは誤り。

最後の選択肢D「データベースストレージでは静的エンティティを作成できるが、ローカルストレージでは作成できない。」は正しい。Local StorageにはStatic Entityがありません。

# 2 Local Storageに対するAggregateのデータ取得タイミング
Local Storageからデータを取得するAggregateには、3つの実行タイミングがあります。

1. （Action Flow中にAggregateが配置されている場合）そのAggregateに差し掛かったとき
2. （画面にAggregateを定義した場合、かつFetchプロパティがAt Start）画面の初期化タイミング
3. （画面にAggregateを定義した場合）Action Flow中でRefresh Dataを指定したとき

問題は、「...画面を初期化するときに『必ず』Aggregateがトリガーされる」から『必ず』の部分が間違いです。上の3.の場合があるため。

3.に示したとおり、選択肢C「この文は正しくない。画面にあるローカルストレージのAggregateはオンデマンドでトリガーすることもできる。」が正解ですね。

# 3 同期パターン（Read/Write Last Write Wins）
同期というのは、DatabaseとLocal Storageに、同じ概念を表すEntityがあるときに、双方（あるいは一方向）でデータを一致させるための処理のことです。

Read Only（更新はDatabase側で行われ、Database→Local Storageの一方向の動機のみが行われる）パターンとRead/Write（更新が端末側でも発生し、Local Storage→Database方向の同期も行われる）パターンがあります。

この問題に示されたAction Flowはその中でも「Read/Write Last Write Wins」パターンのものです。このパターンでは、Local Storageに、端末内で変更されたレコードであるかどうかを示す属性「IsFromServer, IsModified, IsActive」があります。
1. 同期の最初でこの属性を使って端末内で変更されたデータを取得
2. サーバーに同期するActionのパラメータに渡す
3. サーバー側で端末から来た変更をそのまま反映する
4. サーバー側で最新データを取得して端末側に返し、Local Storage内のデータを洗替する
という流れ。3. のために、同じデータ（同じレコード）に複数の端末で同じタイミングに変更が発生すると後勝ちになってしまい、変更が失われる可能性があります。

よって、選択肢A「このパターンは、アプリがオフラインの間に複数のエンドユーザーが同じデータを変更する可能性が低いシナリオに推奨される。」が正解。

# 4 同期処理の実行
モバイルアプリケーションを作ると、デフォルトで同期の仕組みが組み込まれています。その仕組に関する問題です。
OfflineDataSyncフォルダ内にあるActionが該当します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/6ead02ff-5605-b62b-69eb-6d7de6949de6.png)

ざっくりいうと
- OfflineDataSync: 同期処理の本体。ここに自分で作った同期用ロジックを組み込む
- OfflineDataSyncConfiguration: 同期を自動で行うタイミングの設定を行う。ログイン時、オフラインからオンラインに復帰したとき、アプリケーションを復帰させたときに同期するかどうか
- TriggerOfflineDataSync: 同期処理をAction Flowから任意に開始する処理。背後で（部品が）JavaScriptを使って非同期に同期処理を行える。OfflineDataSyncを直接呼び出すこともできるが、その場合非同期にならないのでこちらを呼ぶのが推奨されている
- ServerDataSync: OfflineDataSyncから呼び出される。端末内で発生した同期用データを受け取ってデータベースエンティティに反映する

よって、「同期手順は『必ず』非同期的にバックグラウンドで実行される」は、『必ず』の部分が正しくない。TriggerOfflineDataSyncの説明に書いたように、OfflineDataSyncを呼び出すと同期処理が同期的に実行される。ただし、非推奨であり、TriggerOfflineDataSyncを使うことが勧められている。

# 他のSpecialization試験のサンプル問題
[Architecture Specializationのサンプル問題についてメモ 1/2(#1-#5)](https://qiita.com/jyunji_watanabe/items/c503f8a1ef128b3f5cdb)
[Architecture Specializationのサンプル問題についてメモ 2/2](https://qiita.com/jyunji_watanabe/items/0c2ca229caa155d22c51)