インタフェースによる実装の隠蔽
公開サンプル
このページで説明する設計プラクティスを盛り込んだサンプルを GitHub で公開しています。
外部リンク: ArchitectureSample
実装の分離
インタフェースによる実装の隠蔽を徹底することで、ドメイン層のクラス実装は原則internal化できます。これにより設計変更に非常に強いアーキテクチャを実現できます。
- サービスのインタフェースのみを公開し、実装クラスは非公開にします。
- 利用する側はインタフェースだけでサービスを利用し、実装クラスを参照しないようにします。
実装クラスを変更しても、利用している側は一切影響を受けなくなります。 ただし、利用する側でサービスのインスタンスを取得する必要があるので、ファクトリを公開する必要があります。
このページではこの設計について説明します。
全体像
プロジェクトとクラス、インタフェースの関連は以下のようになります。
- ArchitectureSample - プレゼンテーション層のプロジェクト
- CreateUseCasesCommandクラス - サービスを利用します。
- ArchitectureSample.Core - ドメイン層のプロジェクト
- IUseCaseCreationServiceインタフェース - サービスのインタフェース定義を公開します。
- UseCaseCreationServiceクラス - IUseCaseCreationServiceインタフェースを実装します。プロジェクト外に公開しません。
- SampleServiceFactoryクラス - プロジェクト外からサービスのインスタンスを取得するためのファクトリです。
以下でそれぞれを詳しく説明します。
サービスの実装とインタフェースの公開
ドメイン層のプロジェクトで、以下のようなインタフェースを公開します。
IUseCaseCreationService.cs
using System.Collections.Generic;
using NextDesign.Core;
namespace ArchitectureSample.Core.Services
{
/// <summary>
/// ユースケースを作成するサービスのインタフェース定義
/// </summary>
public interface IUseCaseCreationService
{
/// <summary>
/// ユースケースを作成する
/// </summary>
/// <param name="owner">作成したユースケースを所有させるモデル</param>
/// <param name="names">作成するユースケー スにつける名前</param>
/// <returns>作成したユースケースのコレクション</returns>
IEnumerable<IModel> CreateUseCases(IModel owner, IEnumerable<string> names);
}
}