Disciplina: Modelagem de Sistemas
Notas de Aula 06: Diagrama de classes de
domínio
Objetivos da aula:
 Compreender um modelo de negócio pela representação das classes de
uma entidade
 Modelar as entidades e seus relacionamentos de um domínio por meio
de um diagrama de classes
 Discutir decisões de modelagem
Recordando...
Na aula passada você estudou um exemplo de descrição de um caso de uso.
Ao descrever um caso de uso podemos definir uma interface homem-máquina
que determina quais as informações são relevantes para uma determinada
funcionalidade. Mais do que isso, foi possível perceber que as informações
eram pertinentes a uma conjunto de descrições que iam além das
funcionalidades e podiam ser aplicadas mais de uma vez...
Introdução
Os casos de uso são uma excelente forma de demonstrar o comportamento
de um sistema sob o ponto de vista de uma funcionalidade ou um conjunto de
tarefas. Ao descrever uma funcionalidade do sistema, estamos também
relatando quais dados (variáveis) são importantes para uma interação com um
determinado ator.
A visão de um sistema por casos de um uso é uma visão tradicional de
desenvolvimento de um sistema. Legado da abordagem procedimental, a
visão simplista do sistema como um conjunto de funções traz problemas de
reutilização, pois, invariavelmente, certo conjunto de dados é utilizado em
mais de uma função.
Por exemplo, seja o domínio de uma universidade. Para um caso de uso de
“Inserir Professor”, necessitaremos de dados referentes a uma entidade do
mundo real – neste caso um Professor (CPF, endereço, telefone, etc.). Para o
caso de uso “Alocar Turma”, também precisaremos, ao menos, do CPF do
professor a ser alocado. Não é difícil enxergar que o atributo de uma
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
determinada entidade (neste exemplo o CPF de um professor) pode ser
utilizado para duas ou mais funções diferentes.
Isso não significa que os casos de uso são dispensáveis. Os casos de uso
necessitam de uma complementação para que a visão sobre o sistema seja
mais aderente ao real e ao mesmo tempo pragmática.
Classes e objetos
A Orientação a Objetos (OO) une duas características fundamentais a serem
feitas em um sistema: os dados mais as funções (que operam sobre estes
dados).
Os diagramas de classes da UML ajudam em dois aspectos do problema:
visualizar o modelo de negócio e implementar o projeto de software. Uma das
grandes vantagens de se utilizar a OO é a conversão direta do modelo de
negócios (diagrama de classes de domínio) para artefatos de software
(diagrama de classes de projeto). A literatura correlata separa ainda os
diagramas de classes em três níveis: conceitual (domínio), lógico (projeto) e de
implementação (projeto estendido).
É evidente, então, que o elemento fundamental da OO é a classe. Uma classe
descreve uma entidade do mundo real, abstrata ou não, relevante para um
domínio de sistema. Uma classe descreve os atributos e as operações que são
comuns a uma entidade.
Os atributos endereço, telefone e nome descrevem uma classe PessoaJuridica¸
mas também descrevem uma classe PessoaFisica. Na inexistência de
diferenças entre estas classes, podemos descrevê-las genericamente como
uma classe que atenda ambos os casos. Que tal uma classe Pessoa? Na UML,
uma classe é representada como um retângulo. O nome da classe vem na parte
superior. Na segunda parte do retângulo vêm os atributos de uma classe. A
terceira parte do retângulo se destina as operações de uma classe, assunto
que será visto posteriormente.
A UML sugere que os nomes de classes sejam no singular e comecem com a
primeira letra maiúscula. Além disso, nomes de atributos começam com letras
minúsculas. Classes ou Atributos com nomes compostos tem o segundo nome
subsequente, sem caractere separador, com a primeira letra maiúscula.
Exemplo: PessoaJuridica, endereçoComercial.
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
De fato, entender como uma classe deve ser descrita não possui uma receita
de bolo. A descrição de uma classe por meio de seus atributos é uma solução
que varia de domínio para domínio. Por exemplo, se estivéssemos criando um
sistema para um estacionamento, não faria muito sentido descrever o carro
com um atributo chamado financiado (indica se o carro está financiado ou
não). A informação de financiamento para cadastro de um carro não tem
relevância para um sistema de estacionamentos (ao contrário do atributo
mensalista). No entanto, se estivéssemos fazendo um sistema para uma
concessionária de carros, tal informação seria vital para o modelo de negócios.
Cabe ao Analista de Sistemas decidir sobre o que é relevante.
Concessionária
Estacionamento
A manifestação de uma classe é chamada de objeto ou instância. Os objetos
são ocorrência de uma classe. Por exemplo, uma instância de um objeto da
classe Pessoa é Manoel, que possui o CPF 567.987.342-20, mora na Rua dos
Canudos n. 17 e possui telefone (23) 9878-7656. Da classe Carro (do domínio
estacionamento), um possível objeto da classe é Pálio, cor prata, placa ERJ
1608 e não é mensalista. Outro objeto desta mesma classe é Ka, cor branca,
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
placa XYZ 1909 e é mensalista. Depreende-se, então, que uma classe pode
possui diversos objetos. Outros exemplos:
CLASSE
OBJETOS
Carro
Meu Gol
Empregado
João
Formulários Demissão
Seu Corsa Pálio dele
Ana
Carlos
Cadastro
Vendas
Associação de classes
No mundo real, as entidades não estão sozinhas e a sua existência está
intrinsicamente relacionada com a existência de outros objetos. A descrição
de domínios complexos não está limitada a criação de classes sem nenhum
tipo de interação com outras classes. Além da própria existência da classe, as
associações entre classes constituem um dos agente promotores da
reutilização de código.
Afinal, o que é uma associação de classes? A associação de classes é um
relacionamento estrutural que especifica objetos de um item conectados a
objetos de outro item. A associação indica que existe uma ligação entre
objetos das classes associadas. Cada associação pode ter um nome que
descreve a natureza do relacionamento.
Herança
O conceito de herança permite estabelecer uma hierarquia entre as classes. É
um mecanismo que permite a uma classe herdar as operações e os atributos
de outra classe. Com o uso da herança, quando se escreve uma classe é
necessário especificar apenas no que ela é diferente da classe-mãe, classebase ou superclasse. O mecanismo da herança dá acesso automático às
informações contidas na classe base. Através da herança, uma classe possui
imediatamente toda a funcionalidade de uma classe já existente. A classe que
herda características da outra é chamada subclasse ou classe-filha e a classe
que fornece a herança é chamada superclasse ou classe-mãe.
Quando estávamos aprendendo o conceito de classes, foi utilizado como
exemplo a classe PessoaJuridica e a classe PessoaFisica. Em um determinado
momento percebeu-se que as duas classes possuíam atributos em comum. O
resultado foi a fusão destas classes em uma classe mais genérica chamada
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
Pessoa. Se o nosso domínio de problema fosse bem restritivo, esta solução
estaria suficiente. Ocorre que no mundo real, apesar de terem vários atributos
em comum, em algum momento deveremos colocar os atributos que são
específicos para cada entidade. Por exemplo, se colocarmos o atributo cnpj,
que é aplicado a uma empresa na classe Pessoa, estaremos cometendo um
erro no nosso modelo, pois os objetos da classe Pessoa que efetivamente são
cidadãos não terão informação para preencher neste caso (isso pode acarretar
problemas computacionais também). O correto então, é especificar três
classes por meio de uma herança e colocar os atributos que são pertinentes a
todas as classes filhas na classe mãe e especificar os atributos que são
aplicáveis para cada classe:
A herança é, portanto, o compartilhamento de atributos e operações entre
classes, baseado em um relacionamento hierárquico do tipo pai-filho (ou mãefilho), em que a classe pai possui definições que podem ser utilizadas nas
classes filhas. Estas funcionam como uma especialização da classe pai (as filhas
estendem a sua utilização básica da classe pai para outras utilizações mais
especializadas).
A seguir uma figura ilustrativa do conceito de herança.
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
Uma superclasse direta é a superclasse a partir da qual a subclasse herda
explicitamente. Uma superclasse indireta é qualquer superclasse acima da
superclasse direta. Desta forma, no exemplo acima, Mamífero é uma
superclasse direta de SerHumano e Animal é uma superclasse indireta de
SerHumano.
Na UML, uma herança pode ser definida como múltipla, o que significa que
uma classe filha pode ter mais de uma classe mãe. Além de trazer problemas
conceituais severos, a herança múltipla é rejeitada por diversas linguagens de
programação. Assim, verifique se a herança múltipla não pode ser convertida
em outro tipo de associação.
Associações simples
As classes de um domínio possuem outras associações que não estão em uma
estrutura hierárquica. A modelagem compreende a tarefa de identificar que
classes cooperam no entendimento do problema. Na UML existe uma maneira
de representar esta compressão por meio dos conectores associativos e suas
multiplicidades.
Seja o nosso domínio da concessionárias de carros além da classe Pessoa já
definida anteriormente. Ao descrevermos o problema, percebemos que todo
carro tem uma pessoa como proprietária. Uma maneira de representar a
relação que existe entre o proprietário e o carro é liga-los através de uma
associação simples (uma linha que liga duas classes e possui um nome
opcional):
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
Além da ligação conceitual que estas classes têm, a quantificação de
ocorrências desta ligação é muito importante. É a multiplicidade que
determina quantas vezes um objeto se relaciona com outro objetos da classe
associada. As associações estabelecem uma multiplicidade mínima e uma
multiplicidade máxima de ocorrência.
Se, ao informar que uma pessoa tem ao menos um carro, então a
multiplicidade deve garantir que o modelo esteja especificando que para cada
objeto do tipo Pessoa existirá ao menos um objeto do tipo Carro. Da mesma
forma, podemos dizer que uma pessoa terá no máximo cinco carros
associados, o que significa que um objeto da classe Pessoa estará associado a
um máximo de cinco objetos da classe Carro.
Devemos especificar a multiplicidade nas duas vias. Se do ponto de vista de
um objeto da classe Pessoa a associação já está resolvida, as condições não
estão associados para os objetos da classe Carro. Se for afirmado que um carro
não necessariamente possui um dono, então a multiplicidade mínima é zero.
Além disso, se dissermos que um carro deverá ter exatamente um dono, então
a multiplicidade máxima é um.
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
Muitas vezes não conseguimos determinar a multiplicidade máxima ou
simplesmente torna-se perigoso presumi-la. Por exemplo, poderíamos dizer
que uma pessoa tem ao menos um carro e no máximo muitos (sem especificar
quantos). A multiplicidade máxima pode ser definida com um * que deixa em
aberto o valor máximo. A multiplicidade máxima com * é a padrão quando
averiguado omissão.
Pelo princípio da herança, as classes PessoaJuridica e PessoaFisica também
podem ser proprietárias de um carro:
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
Classes associativas
Alguns objetos de classes do nosso modelo só fazem sentido existir quando
para a ocorrência de uma certa associação. Classes associativas expressam
classes cujos objetos dependem da existência de outros objetos em conjunto.
Por exemplo, a classe Turma. Uma turma (que não é a atriz – isso era para ser
uma piada) corresponde a uma disciplina e tem um professor alocado. Uma
possível solução é esta:
A leitura deste modelo corresponde a “Um professor pode estar alocado em
alguma turma e uma turma tem um professor” e “Uma disciplina pode ter
várias turmas e uma turma é de uma disciplina”.
Apesar de não estar errada, o valor semântico do modelo é pobre, pois dá a
entender a existência de um objeto que de fato não faz sentido sem um objeto
da classe Professor ou da classe Disciplina. O mais adequado é modelar a classe
Turma como uma classe associativa, de forma que fique explícito que a
existência de um objeto desta classe está conceitualmente ligada a existência
dos objetos da classe Professor e Disciplina. Assim, um professor leciona uma
ou mais disciplinas e uma disciplina é lecionada por um ou mais professores. A
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
manifestação dessa associação implica na existência de um objeto da classe
Turma, que entre outras coisas, pode conter os atributos horário e sala.
Contudo, uma classe associativa não está limitada as “classes de origem”. A
classe Turma pode ter relacionamentos simples. Por exemplo, uma turma deve
ter ao menos um aluno e no máximo 50.
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
Agregação e composição
A granularidade de uma classe varia bastante até mesmo em um único
domínio. Muitas vezes queremos demonstrar que uma classe ajuda a compor
o entendimento da outra, em uma relação todo-parte. O relacionamento todoparte expressa uma classe que é o todo (totalidade) e as classes que forma
este todos são expressas como partes. Apenas a leitura em conjunto expressa
conceitualmente a ideia. O relacionamento é dito “faz parte de” ou “tem um”.
A representação é feita com um losango na extremidade do todo.
As associações de todo-parte cuja parte é independente do todo são
chamadas de agregação. A existência dos objetos considerados partes não
estão condicionadas a existência do objeto todo. Para a agregação, a
representação do losango é aberta.
Seja, por exemplo, um cinema. Um combo é composto de ao menos um
refrigerante e exatamente uma pipoca. Uma pipoca ou refrigerante pode ser
comercializado em nenhum combo ou em vários combos.
As associações de todo-parte cuja parte é dependente do todo são chamadas
de composição. A existência dos objetos considerados partes estão
condicionadas a existência do objeto todo. Em função da dependência, o
objeto parte sempre estará associado a apenas um objeto todo. Para
associação de composição, o losango é fechado.
Seja, por exemplo, um sistema empresarial. Uma empresa é composta de
departamentos e um departamento pertence a uma única empresa. A
exclusão do objeto empresa implica, necessariamente, na exclusão do objeto
departamento.
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
Auto associação
Os modelos de classes reais podem apresentar situações onde uma classe
possui uma relação recursiva, isto é, quando existe associação de uma classe
consigo própria.
Seja, por exemplo, um funcionário de uma empresa. É dito dentro de uma
cadeia de comandos de uma empresa que um funcionário supervisiona outro
funcionário. Uma solução possível perfaz-se pela criação de classes diferentes
para o funcionário supervisionado e outra para o funcionário supervisor.
Ocorre que esta não é uma solução válida. Primeiro, estamos limitando
conceitualmente um objeto. Estamos definindo, implicitamente, que uma vez
sendo objeto da classe FuncionarioSupervisor não será objeto da classe
FuncionarioSupervisionado. Esta assunção é errônea já que é razoável cogitar
que um funcionário pode ser supervisor e ser supervisionado por outro
funcionário.
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
Uma outra possibilidade para manter este modelo é criar dois objetos como
instâncias se referenciando a uma mesma entidade. Se conceitualmente já era
ruim, agora computacionalmente é pior.
A melhor solução reside numa auto referência. Nesta abordagem, os objetos
de uma mesma classe estão associados entre si e precisam comunicar-se uns
com os outros. Estas associações também são chamadas de associação
reflexiva ou associação unária e diferenciam pelo papel que exercem (neste
exemplo supervisor e supervisionado)
Discussão: é um atributo, são vários atributos ou é
uma classe?
Uma questão recorrente durante o processo de modelagem é a definição da
informação como um atributo, vários atributos ou uma classe.
Por exemplo, seja a classe Pessoa. Na primeira definição da classe o atributo
endereço engloba todas as características de um endereço, tais como CEP, tipo
de logradouro (rua, avenida, beco, estrada, etc.), logradouro, bairro, cidade,
estado e país. Ao adotar um atributo único para representação de uma
informação composta, estamos deixando a cargo da interface homemmáquina estabelecer o critério para preenchimento do endereço. As
informações do endereço estarão estabelecidas de uma maneira sequencial
em um único atributo e a grande vantagem desta abordagem reside no fato
de ser escalável pois não entra no mérito do padrão de formação do endereço.
Nos Estados Unidos, por exemplo, o padrão de formação dos endereços é
diferente.
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
Nesta abordagem, as informações do endereço estarão estabelecidas de uma
maneira sequencial em um único atributo, o que pode dificultar a
decomposição futura. Por exemplo, como saber quais são as pessoas que
moram na cidade do Rio de Janeiro? Será necessário fazer uma análise (parser)
todas as vezes que a informação necessitar ser decomposta. Uma
possibilidade, então, é criar atributos separados:
Fica claro que um padrão rígido de endereço perde a aplicabilidade para outros
países. Contudo, a grande vantagem é que as informações estão decompostas
e permitem operações de maneira mais simplificada.
Utilizar um atributo composto ou decompor em vários atributos simples tem
implicação direta no modelo de negócios. O sistema será (ou pretende ser)
utilizado em outros países? Você muito provavelmente está inclinado a adotar
o padrão flexível, pois este não limita a expansão. No entanto, lembre-se que
existe um custo em relação a isso: em algum momento, o seu código e a sua
interface homem-máquina terá de lidar com o parser. Não existe uma resposta
definitiva. O Analista de Sistemas deverá pesar os prós e contras de cada
abordagem para cada domínio de problema.
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
Uma outra questão recorrente é: em associações um-para-um, não existe uma
real necessidade de criarmos uma classe. Se uma pessoa só possui um
endereço, então não é necessário criarmos uma classe chamada endereço. De
forma composta ou não, o endereço pode ser um atributo da classe Pessoa, o
que facilitará a implementação (menos um objeto a ser instanciado). No
entanto, esta não é uma boa prática.
Em razão da legibilidade, atributos compostos tem grande potencial para
virarem uma classe. Fica mais simples decompormos o atributo composto em
atributos simples em um classe separada para tal. Além disso, esses atributos
tendem a ser mostrar com multiplicidade crescente durante o
desenvolvimento do sistema. O seu cliente pode jurar de pés juntos que a
pessoa cadastrada no sistema só deverá ter um endereço. No entanto, com
passar do tempo, ele poderá mudar de ideia e dizer que uma pessoa tem
endereço comercial e um endereço residencial (nem pense em repetir
atributos...). Se você modelou desde o início como uma classe separada, isso
irá significar apenas a mudança de multiplicidade e a instanciação de mais
objetos. Se a abordagem tivesse sido outra, muitas outras coisas teriam de ser
mudadas: a criação de uma nova classe, a remoção do atributo na classe
antiga, a adequação do modelo de dados, etc. Então, mesmo que a
multiplicidade seja um-para-um, analise a possibilidade de crescimento do
sistema e defina se a criação de uma classe é válida.
Esta discussão não é aplicável para atributos simples, pois não dá para
caracterizá-los como classes. Alguns de vocês dirão que o atributo nome pode
ser uma classe com dois atributos (primeiroNome, sobrenome). Forçação de
barra total! Uma pessoa não tem vários nomes de registro que justifiquem
uma mudança de multiplicidade. Talvez em um domínio muito específico. Mas,
no caso geral, não justifica.
Professor: Pablo Rangel, D.Sc.
Disciplina: Modelagem de Sistemas
Exercícios
1. Como os diagramas de classes podem ajudar a compreender melhor um
modelo de negócios?
2. A agregação e a composição são dois tipos de relações com objetivos
conceituais claros. No entanto, a agregação tem difícil compreensão
prática quando comparada a uma composição. Você concorda?
Apresente seus argumentos.
3. Explique de que forma a herança aumenta a riqueza semântica da
descrição do domínio.
4. Dada as seguintes afirmações, faça o diagrama de classes.
“Em uma fábrica, um carro é composto por exatamente cinco rodas
(quatro + um estepe). Uma roda, que possui um tamanho de aro,
está associada a um carro.”
“Uma fábrica de carros tem um nome e um número de carros
fabricados por mês. A fábrica é montadora exclusiva de uma marca
de carros que possui um nome e um país sede. Uma marca de carro
tem ao menos uma fábrica.”
“Uma fábrica de carros tem um nome e uma cidade de
fornecimento. A fábrica não é montadora exclusiva de uma marca
de carros e tem uma cota de carros fabricados por mês. Uma marca
de carro tem ao menos uma fábrica.”
“Um pessoa é casada com no mínimo zero ou no máximo 1 pessoa.”
5. Faça o diagrama de classes de domínio do estudo de caso 1 (disponível
no site).
Professor: Pablo Rangel, D.Sc.