次の方法で共有


モデル、クラス、リレーションシップについて

ドメイン固有言語 (DSL) は、DSL 定義ファイルと、記述できるカスタム プログラム コードによって定義されます。 DSL ソリューションのプログラム コードのほとんどは、このファイルから生成されます。

このトピックでは、DSL 定義の主要な機能について説明します。

DSL 定義

Dsl\DslDefinition.dslを開くと、Visual Studio ウィンドウは次の図のようになります。

DSLデザイナー

DSL 定義の最も重要な情報は、DSL 定義図に表示されます。 DslDefinition.dsl の一部でもある追加情報は、通常は図の横に表示される DSL エクスプローラーに表示されます。 最も頻繁に実行されるタスクの図と、より高度なカスタマイズのための DSL エクスプローラーを使用します。

DSL 定義図は、モデル要素を定義するドメイン クラスと、モデル要素間のリンクを定義するリレーションシップを示しています。 また、モデル要素をユーザーに表示するために使用される図形とコネクタも表示されます。

スイムレーンを備えた dsl デザイナー

図または DSL エクスプローラーで DSL 定義内の項目を選択すると、その項目に関する情報が [プロパティ] ウィンドウに表示されます。 [DSL の詳細] ウィンドウに追加情報が表示される場合があります。

モデルは DSL のインスタンスです

モデルは、ユーザーによって作成された DSL のインスタンスです。 モデルには、定義するドメイン クラスのインスタンスであるモデル要素と、定義するドメイン リレーションシップのインスタンスである要素間のリンクが含まれます。 モデルには、図にモデル要素とリンクを表示する図形とコネクタを含めることもできます。 DSL 定義には、図形クラス、コネクタ クラス、および図のクラスが含まれます。

DSL 定義は ドメイン モデルとも呼ばれます。 DSL 定義またはドメイン モデルはドメイン固有言語のデザイン時表現ですが、モデルはドメイン固有言語の実行時インスタンス化です。

ドメイン クラスでモデル要素を定義する

ドメイン クラスはドメイン内のさまざまな要素を作成するために使用され、ドメイン リレーションシップは要素間のリンクです。 これらは、モデルの作成時にデザイン固有の言語のユーザーによってインスタンス化される要素とリンクのデザイン時表現です。

この図は、音楽ライブラリ DSL のユーザーによって作成されたモデルを示しています。 ミュージック アルバムは、曲のリストを含むボックスで表されます。 アーティストは角が丸いボックスで表され、彼らが貢献したアルバムに関連付けられています。

生成された DSL のインスタンス モデル

DSL 定義は、2 つの側面を分離します。 モデル ダイアグラム上のモデル要素の外観は、図形クラスとコネクタ クラスを使用して定義されます。 モデルで伝達される情報は、ドメイン クラスとドメイン リレーションシップを使用して定義されます。

次の図は、音楽ライブラリの DSL 定義のドメイン クラスとリレーションシップを示しています。

リレーションシップの埋め込みと参照

この図は、音楽、アルバム、アーティスト、ソングの 4 つのドメイン クラスを示しています。 ドメイン クラスは、名前、タイトルなどのドメイン プロパティを定義します。 インスタンス モデルでは、これらのプロパティの一部の値が図に表示されます。

クラス間には、MusicHasAlbums、MusicHasArtists、AlbumbHasSongs、ArtistAppearedOnAlbums というドメインリレーションシップがあります。 リレーションシップには、1..1、0..* などの多重度があります。 たとえば、すべての曲は AlbumHasSongs の関係を通じて 1 つのアルバムに正確に関連付けられている必要があります。 すべてのアルバムは、曲の任意の数を持つことができます。

DSL 定義図の並べ替え

この図のアルバムと同様に、ドメイン クラスが DSL 定義図に複数回表示される場合があることに注意してください。 常に 1 つのメイン ビューがあり、 いくつかの参照 ビューを使用できます。

DSL 定義図を再配置するには、次の操作を行います。

  • [ ツリーをここに持ち込む ] コマンドと [ツリーの分割 ] コマンドを使用して、メイン ビューと参照ビューを交換します。 これらのコマンドを表示するには、1 つのドメイン クラスを右クリックします。

  • Ctrl + 上および Ctrl + Down キーを押して、ドメイン クラスと図形クラスの順序を変更します。

  • 各図形の右上にあるアイコンを使用して、クラスを折りたたみまたは展開します。

  • ドメイン クラスの下部にあるマイナス記号 (-) をクリックして、ツリーの一部を折りたたみます。

継承

ドメイン クラスは、継承を使用して定義できます。 継承派生を作成するには、[継承] ツールをクリックし、派生クラスをクリックして、基本クラスをクリックします。 モデル要素には、独自のドメイン クラスで定義されているすべてのプロパティと、基底クラスから継承されたすべてのプロパティがあります。 また、リレーションシップ内の役割も継承します。

継承は、リレーションシップ、図形、コネクタの間でも使用できます。 継承は同じグループ内に維持しなければなりません。 図形はドメイン クラスから継承できません。

ドメイン リレーションシップ

モデル要素はリレーションシップによってリンクできます。 リンクは常にバイナリです。彼らはちょうど2つの要素をリンクします。 ただし、どの要素にも他のオブジェクトへのリンクが多数あり、同じ要素のペア間に複数のリンクが存在する場合もあります。

異なる要素のクラスを定義できるのと同様に、さまざまなクラスのリンクを定義できます。 リンクのクラスは、 ドメインリレーションシップと呼ばれます。 ドメインリレーションシップは、そのインスタンスが接続できる要素のクラスを指定します。 リレーションシップの各エンドは ロールと呼ばれ、ドメイン リレーションシップは 2 つのロールの名前とリレーションシップ自体の名前を定義します。

ドメイン リレーションシップには、埋め込みリレーションシップと参照リレーションシップの 2 種類があります。 DSL 定義図では、埋め込みリレーションシップは各ロールに実線を持ち、参照リレーションシップには破線が付きます。

リレーションシップの埋め込み

モデル内のすべての要素 (ルートを除く) は、1 つの埋め込みリンクのターゲットです。 したがって、モデル全体が埋め込みリンクの単一ツリーを形成します。 埋め込みリレーションシップは、包含または所有権を表します。 この方法で関連する 2 つのモデル要素は、親と子とも呼ばれます。 子は親に埋め込まれていると言われます。

埋め込みリンクは、通常、図のコネクタとして明示的に表示されません。 代わりに、通常は包含によって表されます。 モデルのルートは図で表され、その中に埋め込まれた要素は図に図形として表示されます。

この例では、ルート クラス Music には MusicHasAlbums と Album の埋め込みリレーションシップがあり、AlbumHasSongs が Song に埋め込まれています。 曲は、各アルバム内のリスト内の項目として表示されます。 また、Music には Artist クラスに MusicHasArtists が埋め込まれています。そのインスタンスは図の図形としても表示されます。

既定では、埋め込み要素は親が削除されると自動的に削除されます。

モデルを XML 形式でファイルに保存すると、シリアル化をカスタマイズしていない限り、埋め込み要素は親要素の中にネストされます。

埋め込みは継承と同じではありません。 埋め込みリレーションシップの子は、親のプロパティを継承しません。 埋め込みは、モデル要素間のリンクの一種です。 継承はクラス間のリレーションシップであり、モデル要素間のリンクは作成されません。

埋め込み規則

インスタンス モデル内のすべての要素は、モデルのルートを除き、正確に 1 つの埋め込みリンクのターゲットである必要があります。

したがって、ルート クラスを除くすべての非抽象ドメイン クラスは、少なくとも 1 つの埋め込みリレーションシップのターゲットであるか、基底クラスから埋め込みを継承する必要があります。 クラスは 2 つ以上の埋め込みのターゲットにすることができますが、そのインスタンス モデル要素には一度に 1 つの親のみを含めることができます。 ターゲットからソースまでの多重度は、0..1 または 1..1 である必要があります。

エクスプローラーに埋め込みツリーが表示される

DSL 定義では、ユーザーがモデル図と共に表示するエクスプローラーも作成されます。

DSL の生成されたエクスプローラー

エクスプローラーには、図形を定義していない要素であっても、モデル内のすべての要素が表示されます。 要素と埋め込みリレーションシップが表示されますが、参照リレーションシップは表示されません。

要素のドメイン プロパティの値を表示するには、ユーザーはモデル ダイアグラムまたはモデル エクスプローラーで要素を選択し、[プロパティ] ウィンドウを開きます。 ダイアグラムに表示されないドメイン プロパティも含め、すべてのドメイン プロパティが表示されます。 この例では、各曲にはタイトルとジャンルの両方がありますが、図にはタイトルの値のみが表示されます。

参照リレーションシップ

参照リレーションシップは、埋め込まれていないあらゆる種類のリレーションシップを表します。

参照リレーションシップは、通常、図形間のコネクタとしてダイアグラムに表示されます。

モデルの XML 表現では、2 つの要素間の参照リンクが モニカー を使用して表されます。つまり、モニカーはモデル内の各要素を一意に識別する名前です。 各モデル要素の XML ノードには、リレーションシップの名前と他の要素のモニカーを指定するノードが含まれています。

役割

すべてのドメインリレーションシップには、ソース ロールとターゲット ロールの 2 つのロールがあります。

次の図では、 Publisher ドメイン クラスと PublisherCatalog ドメインリレーションシップの間の行がソース ロールです。 ドメインリレーションシップと Album ドメイン クラスの間の行がターゲット ロールです。

役割と属性。

リレーションシップに関連付けられている名前は、モデルを走査するプログラム コードを記述するときに特に重要です。 たとえば、DSL ソリューションをビルドすると、生成されたクラス Publisher には、アルバムのコレクションであるプロパティ Catalog があります。 Album クラスには、Publisher クラスの単一インスタンスであるプロパティ Publisher があります。

DSL 定義でリレーションシップを作成すると、プロパティ名とリレーションシップ名に既定値が指定されます。 ただし、変更することはできます。

多重性

多重度では、ドメインリレーションシップで同じロールを持つ要素の数を指定します。 この例では、 Catalog ロールの 0 対多 (0..*) 多重度設定では、 Publisher ドメイン クラスのインスタンスに、指定する数の PublisherCatalog リレーションシップ リンクを含めることができます。

ダイアグラムに入力するか、[Multiplicity] ウィンドウで プロパティを変更して、ロールの多重度を構成します。 次の表では、このプロパティの設定について説明します。

Multiplicity タイプ Description
0..* (ゼロから複数) ドメイン クラスの各インスタンスは、リレーションシップの複数のインスタンスを持つ場合と、リレーションシップのインスタンスを持たない場合があります。
0..1 (ゼロから 1) ドメイン クラスの各インスタンスは、リレーションシップのインスタンスを最大1つ持つか、持たないかのどちらかです。
1..1 (一) ドメイン クラスの各インスタンスには、リレーションシップのインスタンスを 1 つ含めることができます。 ロール クラスのどのインスタンスからも、このリレーションシップの複数のインスタンスを作成することはできません。 検証が有効になっている場合、ロール クラスのインスタンスにリレーションシップのインスタンスがない場合、検証エラーが表示されます。
1..* (1 対多) この多重度を持つロールのクラスの各インスタンスは、リレーションシップの複数のインスタンスを持つ可能性があり、各インスタンスにはリレーションシップのインスタンスが少なくとも 1 つ必要です。 検証が有効になっている場合、ロール クラスのインスタンスにリレーションシップのインスタンスがない場合、検証エラーが表示されます。

クラスとしてのドメイン リレーションシップ

リンクは、ModelElement の派生クラスである LinkElement のインスタンスとしてストアで表されます。 これらのプロパティは、ドメイン リレーションシップのドメイン モデル 図で定義できます。

リレーションシップを他のリレーションシップのソースまたはターゲットにすることもできます。 ドメイン モデル図で、ドメイン リレーションシップを右クリックし、[ クラスとして表示] をクリックします。 追加のクラス ボックスが表示されます。 その後、それにリレーションシップを紐付けできます。

ドメイン クラスの場合と同様に、継承によってリレーションシップを部分的に定義できます。 派生リレーションシップを選択し、[プロパティ] ウィンドウで 基本リレーションシップ を設定します。

派生リレーションシップは、その基本リレーションシップを特殊化します。 リンクするドメイン クラスは、基本リレーションシップによってリンクされたクラスから派生するか、または基本リレーションシップによってリンクされたクラスと同じである必要があります。 派生リレーションシップのリンクがモデルに作成されると、派生リレーションシップと基本リレーションシップの両方のインスタンスになります。 プログラム コードでは、基本クラスまたは派生クラスによって生成されたプロパティを使用して、リンクの反対側の端に移動できます。