Partilhar via


Compreender modelos, classes e relações

Uma linguagem específica de domínio (DSL) é definida por seu arquivo de definição DSL, juntamente com qualquer código de programa personalizado que você possa escrever. A maioria do código do programa na solução DSL é gerada a partir deste arquivo.

Este tema explica as funcionalidades principais da definição de DSL.

A definição DSL

Quando abre Dsl\DslDefinition.dsl, a sua janela do Visual Studio é semelhante à imagem abaixo.

Designer DSL

As informações mais importantes na definição DSL são exibidas no diagrama de definição DSL. Informações adicionais, que também fazem parte de DslDefinition.dsl, são exibidas no DSL Explorer, que geralmente aparece ao lado do diagrama. Você trabalha com o diagrama para as tarefas mais frequentes e com o DSL Explorer para personalizações mais avançadas.

O diagrama de definição DSL mostra as classes de domínio que definem elementos de modelo e as relações que definem links entre elementos de modelo. Ele também mostra as formas e conectores que são usados para exibir os elementos do modelo para o usuário.

DSL Designer com faixa funcional

Quando você seleciona um item na definição DSL, no diagrama ou no DSL Explorer, as informações sobre ele são exibidas na janela Propriedades. Informações adicionais podem ser exibidas na janela Detalhes DSL.

Os modelos são instâncias de DSLs

Um modelo é uma instância da sua DSL criada por um usuário. Um modelo contém elementos de modelo, que são instâncias das classes de domínio que você define, e links entre os elementos, que são instâncias das relações de domínio que você define. Um modelo também pode ter formas e conectores, que exibem os elementos e links do modelo em um diagrama. A definição DSL inclui as classes de forma, classes de conector e uma classe para o diagrama.

Uma definição DSL também é conhecida como um modelo de domínio. Uma definição DSL ou modelo de domínio é a representação em tempo de design da linguagem específica do domínio, enquanto o modelo é a instanciação em tempo de execução da linguagem específica do domínio.

Classes de domínio definem elementos de modelo

As classes de domínio são usadas para criar os vários elementos no domínio, e as relações de domínio são os links entre os elementos. Eles são a representação em tempo de design dos elementos e links que serão instanciados pelos usuários da linguagem específica de design quando criarem seus modelos.

Esta ilustração mostra um modelo que foi criado pelo usuário de uma biblioteca de música DSL. Os álbuns de música são representados por caixas que contêm listas de músicas. Os artistas são representados por caixas redondas e estão ligados aos álbuns para os quais contribuíram.

Modelo de instância de DSL gerado

A definição DSL separa dois aspetos. A aparência dos elementos do modelo no diagrama de modelo é definida usando classes de forma e classes de conector. As informações transportadas no modelo são definidas usando classes de domínio e relações de domínio.

A ilustração a seguir mostra as classes de domínio e relacionamentos na Definição DSL da Biblioteca de Música.

Relações de incorporação e referência

A ilustração mostra quatro classes de domínio: Música, Álbum, Artista e Canção. As classes de domínio definem propriedades de domínio como Name, Title e assim por diante. No modelo de instância, os valores de algumas dessas propriedades são exibidos no diagrama.

Entre as classes estão as relações de domínio: MusicHasAlbums, MusicHasArtists, AlbumbHasSongs e ArtistAppearedOnAlbums. As relações têm multiplicidades como 1..1, 0..*. Por exemplo, cada Canção deve estar relacionada a exatamente um Álbum através da relação AlbumHasSongs. Cada álbum pode ter qualquer número de músicas.

Reorganizando o diagrama de definição DSL

Observe que uma classe de domínio pode aparecer várias vezes no diagrama de definição DSL, como Album faz nesta imagem. Há sempre uma visualização principal, e pode haver algumas visualizações de referência.

Para reorganizar o diagrama de definição DSL, você pode:

  • Troque as visualizações principal e de referência usando os comandos Bring Tree Here e Split Tree . Clique com o botão direito do mouse em uma única classe de domínio para ver esses comandos.

  • Reordene as classes de domínio e as classes de forma pressionando Ctrl+Up e Ctrl+Down.

  • Recolher ou expandir classes usando o ícone no canto superior direito de cada forma.

  • Recolha partes da árvore clicando no sinal de menos (-) localizado na parte inferior de uma classe de domínio.

Herança

As classes de domínio podem ser definidas usando herança. Para criar uma derivação de herança, clique na ferramenta Herança, clique na classe derivada e, em seguida, clique na classe base. Um elemento de modelo tem todas as propriedades que são definidas em sua própria classe de domínio, juntamente com todas as propriedades herdadas da classe base. Também herda os seus papéis nas relações.

A herança também pode ser usada entre Relacionamentos, Formas e Conectores. A herança deve manter-se dentro do mesmo grupo. Uma forma não pode herdar de uma classe de domínio.

Relações de Domínio

Os elementos do modelo podem ser ligados por relações. Os links são sempre binários; eles ligam exatamente dois elementos. No entanto, qualquer elemento pode ter muitos links para outros objetos, e pode até haver mais de um link entre o mesmo par de elementos.

Assim como você pode definir diferentes classes de elementos, você pode definir diferentes classes de links. A classe de um link é chamada de relação de domínio. Uma relação de domínio especifica quais classes de elemento suas instâncias podem se conectar. Cada extremo de um relacionamento é chamado de papel, e a relação de domínio define nomes para os dois papéis, bem como para o próprio relacionamento.

Existem dois tipos de relações de domínio: relações de incorporação e relações de referência. No diagrama de definição DSL, as relações de incorporação têm linhas sólidas em cada função e as relações de referência têm linhas tracejadas.

Incorporando relacionamentos

Todos os elementos de um modelo, exceto sua raiz, são o alvo de um link de incorporação. Portanto, todo o modelo forma uma única árvore de links de incorporação. Uma relação de encapsulamento representa contenção ou propriedade. Dois elementos de modelo que estão relacionados dessa maneira também são conhecidos como pai e filho. Diz-se que a criança está inserida no progenitor.

Os links de incorporação geralmente não são mostrados explicitamente como conectores em um diagrama. Em vez disso, eles são geralmente representados pela contenção. A raiz do modelo é representada pelo diagrama, e os elementos incorporados nele são exibidos como formas no diagrama.

No exemplo, a classe raiz Music tem uma relação de incorporação MusicHasAlbums para Album, que tem uma incorporação AlbumHasSongs para Song. As músicas são exibidas como itens em uma lista dentro de cada álbum. A música também tem uma incorporação de MusicHasArtists à classe Artist, cujas instâncias também aparecem como formas no diagrama.

Por padrão, os elementos incorporados são excluídos automaticamente quando seus pais são excluídos.

Quando um modelo é salvo num ficheiro no formato XML, os elementos embutidos são aninhados dentro dos seus pais, a menos que tenha personalizado a serialização.

Observação

A incorporação não é igual à herança. Os filhos em uma relação de incorporação não herdam os bens dos pais. Uma incorporação é um tipo de ligação entre elementos do modelo. A herança é uma relação entre classes e não cria ligações entre elementos do modelo.

Regras de incorporação

Cada elemento em um modelo de instância deve ser o destino de exatamente um link de incorporação, exceto a raiz do modelo.

Portanto, cada classe de domínio não abstrata, exceto a classe raiz, deve ser o destino de pelo menos uma relação de incorporação ou deve herdar uma incorporação de uma classe base. Uma classe pode ser o destino de duas ou mais incorporações, mas seus elementos de modelo de instância só podem ter um pai de cada vez. A multiplicidade do destino para a origem deve ser 0..1 ou 1..1.

O Explorer exibe a árvore de incorporação

Sua definição DSL também cria um explorador, que os usuários veem ao lado do diagrama de modelo.

Explorador de DSL gerado

O explorador mostra todos os elementos no modelo, mesmo aqueles para os quais você não definiu nenhuma forma. Mostra elementos e relações de incorporação, mas não relações de referência.

Para ver os valores das propriedades de domínio de um elemento, o usuário seleciona um elemento no diagrama de modelo ou no explorador de modelos e abre a janela Propriedades. Ele exibe todas as propriedades do domínio, incluindo aquelas que não são exibidas no diagrama. No exemplo, cada Canção tem um Título e um Género, mas apenas o valor do Título é mostrado no diagrama.

Relações de referência

Uma relação de referência representa qualquer tipo de relação que não esteja incorporada.

As relações de referência são normalmente exibidas em um diagrama como conectores entre formas.

Na representação XML do modelo, um link de referência entre dois elementos é representado usando monikers. Ou seja, apelidos são nomes que identificam exclusivamente cada elemento no modelo. O nó XML para cada elemento de modelo contém um nó que especifica o nome da relação e o apelido do outro elemento.

Funções

Cada relação de domínio tem duas funções, uma função de origem e uma função de destino.

Na imagem a seguir, a linha entre a classe de domínio Publisher e a relação de domínio PublisherCatalog é a função de origem. A linha entre a relação de domínio e a classe de domínio Album é a função de destino.

Funções e propriedades.

Os nomes associados a um relacionamento são especialmente importantes quando você escreve código de programa que atravessa o modelo. Por exemplo, quando você cria a solução DSL, a classe gerada Publisher tem uma propriedade Catalog que é uma coleção de álbuns. A classe Album tem uma propriedade Publisher que é uma única instância da classe Publisher.

Quando você cria um relacionamento em uma definição DSL, as propriedades e os nomes de relacionamento recebem valores padrão. No entanto, você pode alterá-los.

Multiplicidades

Multiplicidades especificam quantos elementos podem ter a mesma função em uma relação de domínio. No exemplo, a configuração de multiplicidade zero-para-muitos (0..*) na função Catalog especifica que qualquer instância da classe de domínio Publisher pode ter quantos links de relacionamento PublisherCatalog você quiser dar.

Configure a multiplicidade de uma função digitando no diagrama ou modificando a Multiplicity propriedade na janela Propriedades . A tabela a seguir descreve as configurações dessa propriedade.

Tipo de multiplicidade Description
0..* (Zero a muitos) Cada instância da classe de domínio pode ter várias instâncias da relação ou nenhuma instância da relação.
0..1 (Zero a um) Cada instância da classe de domínio não pode ter mais de uma instância da relação ou nenhuma instância da relação.
1..1 (Um) Cada instância da classe de domínio pode ter uma instância da relação. Não é possível criar mais de uma instância dessa relação a partir de qualquer instância da classe de função. Se a validação estiver habilitada, um erro de validação aparecerá quando qualquer instância da classe de função não tiver nenhuma instância da relação.
1..* (Um para muitos) Cada instância da classe na função que tem essa multiplicidade pode ter várias instâncias da relação, e cada instância deve ter pelo menos uma instância da relação. Se a validação estiver habilitada, um erro de validação aparecerá quando qualquer instância da classe de função não tiver nenhuma instância da relação.

Relações de domínio como classes

Um link é representado no Store como uma instância de LinkElement, que é uma classe derivada de ModelElement. Você pode definir essas propriedades no diagrama de modelo de domínio em relações de domínio.

Você também pode fazer de um relacionamento a origem ou o alvo de outros relacionamentos. No diagrama de modelo de domínio, clique com o botão direito do rato na relação de domínio e, em seguida, clique em Mostrar como classe. Será exibida uma caixa de classe adicional. Em seguida, você pode conectar relacionamentos a ele.

Você pode definir um relacionamento parcialmente por herança, assim como pode fazer com classes de domínio. Selecione a relação derivada e defina Relação base na janela Propriedades.

Uma relação derivada especializa a sua relação base. As classes de domínio que ele vincula devem ser derivadas ou iguais às classes vinculadas pela relação base. Quando um link da relação derivada é criado num modelo, é uma instância de ambas as relações derivada e base. No código do programa, você pode navegar para a extremidade oposta do link usando as propriedades geradas pela base ou pela classe derivada.