新しいアプリケーションの 概念モデル を作成する場合、分析中に、employee, department ..etc
のような一部のオブジェクトが別のシステムの一部であることがわかりました。従業員の名前や番号など、それらに関連するすべてのデータがそのシステムに存在します。
ここに私の質問:
asp.net MVC and EF6 code-first
を使用します)私見では、これらのオブジェクトを、アプリケーションで必要な程度にモデル化する必要があります。たとえば、使用可能なすべての属性をモデル化するのではなく、プログラムに必要な属性のみをモデル化します。システムに1つまたは2つの属性しか必要としない外部エンティティがある場合は、それらの属性を既存の内部エンティティに追加することを検討できます。さらに必要な場合は、必要な属性を使用して外部エンティティをモデル化することを検討してください。ただし、名前を同一にするか、少なくとも一貫性を保つようにしてください。
これは、アプリケーションのコードを実装するための貴重な情報です。モデルからオブジェクトを除外すると、まとまりのある記述を書くことがはるかに難しくなります。
概念モデルの対象者にとって役立つと思われる場合は、エンティティまたは属性に外部エンティティとしてタグを付ける一貫した方法を使用してください。たとえば、UMLでは、これに特別なステレオタイプを導入できます。または、モデルに使用している表記に応じて、ある種のコメントまたは注釈を使用します。
後でこれを実装するときは、外部エンティティにアクセスするために、上記でモデル化した属性を正確に含む、何らかのプロキシのようなオブジェクトがおそらく必要になります。したがって、この意味で、オブジェクトareも少なくともある程度はシステムの一部です。
それらをどのように実装するかは、詳細に大きく依存します。例えば、
システムがこれらの外部エンティティへの読み取り専用アクセスまたは書き込みアクセスのみを必要とする場合、
システムが参照を作成できる(または作成できない)エンティティに不変のキーがある場合、
システムのプロキシと外部システムの間に許容できる不整合がある場合(少なくとも一定期間)
外部システムが提供するAPIの種類
そのような詳細に応じて、
何らかの同期戦略を使用して、これらのオブジェクトのプロキシテーブルを実装するか、または単に
それらをデータベースビューとして実装する、または
なんらかのコードを使用して属性をクライアントオブジェクトにプルするだけで、データベース表現はまったくありません。
大丈夫!あなたのアプリケーションは「シフト管理アプリ」です
本質的に、このアプリは従業員や部門を実際には気にしません。営業日がいつ始まるか、いつ終わるか、何人が会社で働いているか、どれだけシフトが長いかなどが気になります。
したがって、それらを概念モデルから除外する必要があります。それはそれを複雑にするだけです。たとえば、他のシステムで定義されているように、シフトが「従業員」によって満たされない場合があります。おそらく、その契約労働者などです。
Shift、Person、BusinessDayなどが必要なオブジェクトの新しいモデルを作成し、それらの用語でシステムを説明します。
実際にシステムが同じオブジェクトを使用するようになると、データを操作するのに十分な柔軟性が得られますが、別のエクスポートレイヤーまたはマッピングレイヤーを使用して他のシステムにリンクできます。
例えば。独自のシフト管理アプリを作成する代わりに、「既製品」を購入することを想像してみてください。既成のアプリが既存の従業員モデルに直接接続できるとは思わないでしょう。多くの可能なデータソースを処理できる必要があります。
ただし、既存のシステムをそれにリンクできるようにするAPIまたはインポート/エクスポート関数があることが期待されます。従業員データを使用して、ShiftWorkerデータを入力します。
独自の自社製品を作成すると、既製の製品よりも2つのモデルをより密接に結び付けることができます。ただし、2つのシステム間の懸念の分離を尊重し、それらの間にマッピング層または腐敗防止層の抽象化を提供する必要があります。
@Ewanからの回答は提供された特定のシナリオをカバーしていると私は信じているので、可能な場合は、これはより一般的/一般的なルートに従います。 (以下の例は、同様の視点を示すためにのみ使用されていることに注意してください)
混乱を解消するために最初に頭に浮かぶのは、異なる名前空間を処理するときに見られるいくつかの関連する問題を示すことです。この場合、列挙型を見ることができます。たとえば、特定のエントリのタイピングを定義する「マスター」列挙体として機能するオブジェクトがデータレイヤーにある場合です。 (例:PersonEnum {従業員= 1、マネージャー= 2、請負業者= 3、CEO = 4、ベンダー= 5、...})
ユースケースに到達すると、ユースケースに有効なPersonEnum値を示すために列挙型(ValidPersonEnum)が定義されている場合があります。たとえば、従業員とマネージャーは給与レポートにのみ表示でき、請負業者は給与レポートとプロジェクトコストの概要の両方に表示でき、ベンダーはプロジェクトコストの概要に表示できます。
これらの値を相互にチェックするとき(タイプEmployeeの指定されたエントリですか?)、エラーが発生し、名前空間を使用して列挙型を定義します。これを念頭に置いて、私たちはあなたの例を使用して高レベルの立場にアプローチすることができます。
外部システムの従業員については、その概念の一部としてそのシステム内で定義されます。システムでは、データまたはメソッドを介してEmployeeを使用できますが、そのEmployeeは、基本的にExternalSystem.EmployeeではなくYourSystem.Employeeに変更されます。
モデルの場合、外部システムの使用方法ではなく、現在のアプリケーションがそれをどのように使用するかに関して、従業員を表示できます。 @Ewanのポイントに分岐するために、この混乱はある種の抽象化を介して解消することができます。これは、アプリケーションでPersonをベースとして、EmployeeをPersonの実装として使用できます。
一般的なことから、外部システムからの概念を含めたい/する可能性がある場合があることに注意したいと思います。これらは、新しいアプリケーションが外部システム内のデータを操作(作成/変更)する拡張タイプのアプリケーションにさらに当てはまります。
したがって、最初の質問では、外部システムに関する従業員の責任を必ずしも述べる必要はありません。従業員はモデルでの責任について説明する必要があり、必要に応じて同様の方法が存在する可能性があります。このモデルは、ターゲットアプリケーションに関連します。別のシステムを中心にモデルを設計しようとすると、個別のアプリケーションではなく、既存のシステムへの追加のように見える可能性があります。
また、オブジェクトが別のシステムでどのように使用されているかに依存するモデルの場合、オブジェクトは外部の理由でいつでも変更される可能性があるため、新しいアプリケーションを地上から取得するのがより困難になる可能性があります。新しいアプリケーションの(コンセプトモデルの設計中および設計後)。
各アイテムのデータソースを指定する場合は、パス(ファイル、データベースサーバーなど)または名前付きプロセスの依存関係(夜間更新またはその他の外部データ処理)を含めることができます。
実装に関する質問に関しては、ここでさまざまなレベルを確認できます。このコンセプトは、アプリケーションのロードマップを提供します(Xクラスは、アクションZを実行できるかどうか、またはLクラスなしではMクラスが存在できないかどうかを決定するYクラスのリストを保持します)。コンセプトにはソースを定義する機会がない可能性があるため、コンセプトを実装するときに、データソースを定義できます。これらの実装ステップは、他のシステムとの相互作用を定義する場所になります(従業員データは外部システムに基づいて取得されます)。
繰り返しますが、上記の例は、同様の視点を示すための試みとしてのみ提供されたものであり、@ Ewanの回答はあなたの例に関して同じ点をカバーしていると思います。私の例が、提供された概念を橋渡しするのに役立つことを願っています。
これらのエンティティは実際にはあなたのものではなく、「システム」の外部で変更できますが、それらへのリンクを提供できます。
たとえば、yourEmployee
モデルエンティティ(これはEFコードの最初のクラスにもなります)です。
public class Employee
{
// Your key and anything else besides whatever the external entity provides
public int Id { get; set; }
// 1-to-1 relationship to the external entity
public virtual ExternalEmployee ExternalEmployee { get; set; }
}
そして、これがExternalEmployee
モデルエンティティ(およびコードの最初のクラス)であり、外部エンティティマッピングによってからデータベースビューに必要なプロパティを提供します(DbContext
未満):
public class ExternalEmployee
{
public int Id { get; set; }
public string Name { get; set; }
// 1-to-1 relationship to your Employee
public virtual Employee Employee { get; set; }
}
EF DbContext
(vw_ExternalEmployees
は、すべてのデータをExternalEmployee
)に提供するデータベースビューです。
public partial class MySystemContext : DbContext
{
// ...
public virtual DbSet<Employee> Employees { get; set; }
public virtual DbSet<ExternalEmployee> vw_ExternalEmployees { get; set; }
}
もちろん、あなたのEmployeeRepository
はyourEmployee
に対してのみ責任があります。結果として、サービスレイヤー(例:EmployeeService
)で外部データに変更を加える必要がある場合は、外部エンティティを担当する対応するサービスに委任する必要があります。