AdventureWorksをモデリングしてDDDしながらドメインモデルで実装してみる(1)
都合の良いシナリオでサンプルを作成するのではなく、既存のDBを使って実際に概念モデリングを行い、ドメイン駆動設計からドメインモデルにつなげて行きたいと思います。
ターゲットのデータベース
AdventureWorksのテーブル定義はここにあります。並べるとこれだけです。それなりにあります。
Address | ProductModelProductDescriptionCulture | AddressType | ProductPhoto |
AWBuildVersion | ProductProductPhoto | BillOfMaterials | ProductReview |
Contact | ProductSubcategory | ContactCreditCard | ProductVendor |
ContactType | PurchaseOrderDetail | CountryRegion | PurchaseOrderHeader |
CountryRegionCurrency | SalesOrderDetail | CreditCard | SalesOrderHeader |
Culture | SalesOrderHeaderSalesReason | Currency | SalesPerson |
CurrencyRate | SalesPersonQuotaHistory | Customer | SalesReason |
CustomerAddress | SalesTaxRate | DatabaseLog | SalesTerritory |
Department | SalesTerritoryHistory | Document | ScrapReason |
Employee | Shift | EmployeeDepartmentHistory | ShipMethod |
EmployeePayHistory | ShoppingCartItem | ErrorLog | SpecialOffer |
Illustration | SpecialOfferProduct | Individual | StateProvince |
JobCandidate | Store | Location | StoreContact |
Product | TransactionHistory | ProductCategory | TransactionHistoryArchive |
ProductCostHistory | UnitMeasure | ProductDescription | Vendor |
ProductDocument | VendorAddress | ProductInventory | VendorContact |
ProductListPriceHistory | WorkOrder | ProductModel | WorkOrderRouting |
ProductModelIllustration |
概念モデルのエンティティを識別する
パッケージ(スキーマ)ごとに上記のテーブルのPKを調べていきます。PKには通常ビジネス上で利用されている識別子が利用されているいます。識別子から指し示すエンティティ見つけてエンティティ候補を洗い出します。
さらにエンティティ候補の内トップレベルでアクセスされるエンティティ(ファーストクラス)かどうかを判断して概念モデルレベルのエンティティを識別します。
AdventureWorksのキーは基本IDがついているようなのでID付のカラム名探せば十分かもしれませんが、汎用的な方法で進めます。
HumanResources
識別子 | エンティティ候補 | 日本語 | トップ | 区分 | 説明 |
---|---|---|---|---|---|
EmployeeID | Employee | 従業員 | ○ | リソース | |
DepartmentID | Department | 部署 | ○ | リソース | |
ShiftID | Shift | 勤務シフト | × | リソース | |
JobCandidateID | JobCandidate | 求職者 | × | リソース | |
AddressID | →Personパッケージ |
Sales
識別子 | エンティティ候補 | 日本語 | トップ | 区分 | 説明 |
---|---|---|---|---|---|
SalesPersonID | SalesPerson | 販売担当者 | ○ | リソース | |
TerritoryID | SalesTerritory | 担当販売区域 | × | リソース | |
CustomerID | Customer | 顧客 | ○ | リソース | 個人と再販業者がある |
ContactID | →Personパッケージ | ||||
CreditCardID | CreditCard | クレジットカード | × | リソース | |
SalesOrderID | SalesOrder | 販売注文 | ○ | イベント | 処理中、承認済み、バックオーダー中、拒否、出荷済み、キャンセルの状態を持つ |
SalesReasonID | SalesReason | 販売理由 | × | リソース | |
CurrencyRateID | CurrencyRate | 為替レート | × | ルール | |
CurrencyCode | Currency | 通貨 | × | リソース | |
SalesTaxRateID | SalesTaxRate | 消費税 | × | ルール | |
ShoppingCartItemID | ShppingCartItem | ショッピング カート | × | イベント | |
SalesOrderDetailID | SalesOrderDetail | 販売注文(明細) | × | イベント | |
SpecialOfferID | SpecialOffer | 割引 | × | リソース | |
ProductID | →Productionパッケージ |
Person
識別子 | エンティティ候補 | 日本語 | トップ | 区分 | 説明 |
---|---|---|---|---|---|
ContactID | Contact | 連絡先 | × | 汎用 | |
AddressID | Address | 住所 | × | 汎用 | |
ContactTypeID | ContactType | 連絡先タイプ | × | リソース | |
AddressTypeID | AddressType | 住所タイプ | × | リソース | |
CountryRegionCode | CountryRegion | 国・地域 | × | リソース | |
StateProvinceID | StateProvince | 都道府県 | × | リソース |
Production
識別子 | エンティティ候補 | 日本語 | トップ | 区分 | 説明 |
---|---|---|---|---|---|
ProductID | Product | 製品 | ○ | リソース | |
ProductReviewID | ProductReview | 製品レビュー | × | イベント | |
ProductPhotoID | ProductPhoto | 製品画像 | × | リソース | |
ProductModelID | ProductModel | 製品モデル | × | リソース | |
IllustrationID | Illustration | 組み立て図 | × | リソース | |
BillOfMaterialsID | BillOfMaterials | 部品構成 | × | ルール | |
ProductSubcategoryID | ProductSubcategory | 製品サブカテゴリ | × | リソース | |
ProductCategoryID | ProductCategory | 製品カテゴリ | × | リソース | |
UnitMeasureCode | UnitMeasure | 単位コード | × | 汎用 | |
TransactionID | Transaction | トランザクション | × | イベント | |
LocationID | Location | 場所 | × | リソース | |
DocumentID | Document | 製品ドキュメント | × | リソース | |
WorkOrderID | WorkOrder | 製造作業指示 | ○ | イベント | |
ScrapReasonID | ScrapReason | 製造エラー理由 | × | リソース | |
ProductDescriptionID | ProductDescription | 製品説明 | × | リソース | |
CultureID | Culture | 製品説明言語 | × | リソース |
Purchasing
識別子 | エンティティ候補 | 日本語 | トップ | 区分 | 説明 |
---|---|---|---|---|---|
VendorID | Vendor | 仕入先 | ○ | リソース | |
PurchaseOrderID | PurchaseOrder | 購買発注 | ○ | イベント | 保留、承認済み、拒否、完了の状態を持つ |
ShipMethodID | ShipMethod | 輸送手段(会社) | × | リソース | |
PurchaseOrderDetailID | PurchaseOrderDetail | 購買発注(明細) | × | イベント |
概念モデル クラス図を作成する
識別したトップレベルのエンティティをクラス図に整理します。関連はテーブルを分析して付与しました。
なお、エンティティの識別と合わせて、各エンティティの状態やバリエーション(サブタイプ)を調べます。概念モデルのエンティティの識別子をPKにもつテーブルを調べればいろんなことがわかります。AdventureWorksにはCustomerIDをPKに持つテーブルはCustomer以外にIndividualとStoreがありました。これは、CustomerのバリエーションにIndividualとStoreがあることを意味しています。また、エンティティの状態はテーブルにStatusなどのカラムがないか調べます。状態を表すカラムはトップレベルのイベント型のエンティティに良く含まれており、Activityやユースケースシナリオを記述する際のビジネスフローのヒントになります。