パート 2 - アーキテクチャ

クロスプラットフォーム アプリの構築に関する重要な理念は、プラットフォーム間でのコード共有の最大化に役立つアーキテクチャを作成することです。 次のオブジェクト指向プログラミングの原則に従うと、適切に設計されたアプリケーションを構築できます。

  • カプセル化 – クラスとアーキテクチャ レイヤーでは、必要な機能を実行する最小限の API のみを公開し、実装の詳細を隠します。 これは、クラス レベルでは、オブジェクトは "ブラック ボックス" として動作し、使用するコードはタスクの実現方法を知る必要がないことを意味します。 アーキテクチャ レベルでは、抽象度の高いレイヤーでコードに代わってより複雑な相互作用を調整する簡素化された API を奨励する、ファサードのようなパターンを実装することを意味します。 つまり、(たとえば) UI コードは、画面の表示とユーザー入力の受け入れだけを行い、データベースとの直接的なやり取りは行わないようにする必要があります。 同様に、データ アクセス コードはデータベースの読み取りと書き込みのみを行い、ボタンやラベルとは直接やり取りしないようにする必要があります。
  • 責任の分離 – 各コンポーネントの目的を (アーキテクチャとクラス両方のレベルで) 明確に定義するようにします。 各コンポーネントでは、定義されたタスクのみを実行し、それを使う必要がある他のクラスからアクセスできる API を介して、その機能を公開する必要があります。
  • ポリモーフィズム – 複数の実装をサポートするインターフェイス (または抽象クラス) のプログラミングは、プラットフォーム固有の機能と引き続き対話しながら、コア コードを記述してプラットフォーム間で共有できることを意味します。

その自然な結果は、個別の論理レイヤーを持つ現実のエンティティまたは抽象エンティティに従ってモデル化されたアプリケーションです。 コードをレイヤーに分離すると、アプリケーションの理解、テスト、メンテナンスが容易になります。 各レイヤーのコードを、物理的に分離する (ディレクトリに、または非常に大きなアプリケーションの場合は個別のプロジェクトに) と共に、論理的にも分離する (名前空間を使って) ことをお勧めします。

一般的なアプリケーション レイヤー

このドキュメントとケース スタディを通じて、次の 6 つのアプリケーション レイヤーに言及します。

  • データ レイヤー – 非揮発性のデータ永続化。SQLite データベースがよく使われますが、XML ファイルまたは他の適切なメカニズムを使って実装することもできます。
  • データ アクセス レイヤー – 呼び出し元に実装の詳細を公開することなく、データの作成、読み取り、更新、削除 (CRUD) アクセスを提供するデータ レイヤーのラッパー。 たとえば、DAL にはデータのクエリまたは更新を行うための SQL ステートメントが含まれる場合がありますが、参照元のコードはこのことを知る必要はありません。
  • ビジネス レイヤー – (ビジネス ロジック レイヤーまたは BLL と呼ばれることもあります) ビジネス エンティティの定義 (モデル) とビジネス ロジックが含まれます。 ビジネス ファサード パターンの候補。
  • サービス アクセス レイヤー – 複雑な Web サービス (REST、JSON、WCF) から、リモート サーバーからのデータとイメージの単純な取得まで、クラウド内のサービスにアクセスするために使われます。 ネットワーク動作をカプセル化し、アプリケーションと UI のレイヤーで使われる簡単な API を提供します。
  • アプリケーション レイヤー – 通常はプラットフォーム固有の (一般にプラットフォーム間で共有されない) コード、またはアプリケーションに固有の (一般に再利用可能ではない) コード。 コードをアプリケーション レイヤーと UI レイヤーのどちらに配置するか決めるのによいテストは、(a) クラスに実際の表示コントロールがあるかどうか、または (b) 複数の画面またはデバイス (iPhone と iPad など) 間で共有できるかどうかを判断することです。
  • ユーザー インターフェイス (UI) レイヤー – ユーザーとやり取りするレイヤー。画面、ウィジェット、それらを管理するコントローラーなどです。

1 つのアプリケーションにすべてのレイヤーが含まれるとは限りません。たとえば、ネットワーク リソースにアクセスしないアプリケーションには、サービス アクセス レイヤーは存在しません。 非常に単純なアプリケーションでは、操作が極めて基本的であるため、データ レイヤーとデータ アクセス レイヤーが統合されることがあります。

モバイル ソフトウェアの一般的なパターン

パターンは、一般的な問題に対して繰り返される解決策をキャプチャするための確立された方法です。 メンテナンスまたは理解しやすいモバイル アプリケーションを構築する場合に理解しておくと役に立つ重要なパターンがいくつかあります。

  • Model、View、ViewModel (MVVM) – Model-View-ViewModel パターンは、Xamarin.Forms などのデータ バインドをサポートするフレームワークでよく使われます。 これは、Windows Presentation Foundation (WPF) や Silverlight のような XAML 対応の SDK によって普及しました。ViewModel は、データ バインドとコマンドにより、データ (Model) とユーザー インターフェイス (View) の間の仲介者として機能します。
  • Model、View、Controller (MVC) – 一般的で、誤解されることが多いパターンです。MVC は、ユーザー インターフェイスを構築するときに最もよく使われ、UI 画面の実際の定義 (View)、その背後にあって操作を処理するエンジン (Controller)、それを設定するデータ (Model) の間の分離を提供します。 Model は実際には完全に省略可能な部分であるため、このパターンの理解の核心部分は View と Controller にあります。 MVC は、iOS アプリケーションで人気のあるアプローチです。
  • ビジネス ファサード – マネージャー パターンとも呼ばれ、複雑な作業への簡単なエントリ ポイントを提供します。 たとえば、タスク追跡アプリケーションでは、GetAllTasks()GetTask(taskID)SaveTask (task) などのメソッドを含む TaskManager クラスを使う場合があります。TaskManager クラスは、タスク オブジェクトの保存や取得を実際に行う内部作業に対するファサードを提供します。
  • シングルトン – シングルトン パターンは、特定のオブジェクトのインスタンスが 1 つだけ存在できるようにする方法を提供します。 たとえば、モバイル アプリケーションで SQLite を使う場合、データベースのインスタンスは 1 つだけである必要があります。 シングルトン パターンを使うと、これを簡単に実現できます。
  • プロバイダー – Silverlight、WPF、WinForms アプリケーション間でのコードの再利用を促進するために、Microsoft が作成したパターンです (ほぼ間違いなく、戦略または基本的な依存関係挿入に似ています)。 共有コードはインターフェイスまたは抽象クラスに対して記述でき、コードの使用時にプラットフォーム固有の具象実装が記述されて渡されます。
  • 非同期 – Async キーワードと混同しないでください。非同期パターンは、UI または現在の処理を妨げることなく、実行時間の長い作業を実行する必要がある場合に使われます。 最も単純な形式の非同期パターンでは、実行時間の長いタスクを別のスレッド (またはタスクなどの同様のスレッド抽象化) で開始する一方、現在のスレッドは処理を続けて、バックグラウンド プロセスからの応答をリッスンし、データや状態が返されたら UI を更新する、ということだけが記述されています。

この後、実用的な使用方法が示されているケース スタディで、各パターンをさらに詳しく調べます。 Wikipedia には、MVVMMVCファサードシングルトン戦略プロバイダーの各パターン (および一般的な設計パターン) についてのさらに詳しい説明があります。