Conceitos: Classe Estruturada
Tópicos
Definição
De acordo com a UML ([UML04]), uma Classe
é um subtipo das Classes EncapsulatedClassifier e metaclass, que instaura em
uma Classe o recurso para ter uma estrutura interna e portas. Além disso, um componente é definido pela UML como um subtipo de Classe. Portanto, dentro do contexto do RUP, nos referimos aos
componentes e às classes como sendo classes estruturadas.
Peça
Uma instância de classe estruturada contém um objeto ou conjunto de objetos correspondente
a cada peça. Todas essas instâncias são destruídas quando a instância da classe
estrutura que as contém é destruída.
O exemplo a seguir mostra duas visualizações possíveis da classe Carro:
Na figura (a), Carro é mostrado como tendo uma associação de composição
com o nome de função traseira para uma classe Roda e
uma associação de composição com o nome de função e para uma classe Motor.
Qualquer instância da classe Motor pode ser vinculada a um número
arbitrário de instâncias da classe Roda.
Na figura (b), o mesmo é especificado. Além disso, na figura (b),
especifica-se que:
-
traseira e e pertencem à estrutura interna
da classe Carro. Isso permite a especificação de detalhes que
se aplicam somente às instâncias das classes de Roda e de Mecanismo
dentro do contexto da classe Carro, mas que não guardam
rodas e mecanismos em geral.
-
no contexto da classe Carro, a instância que desempenha
a função e só pode ser conectada a duas instâncias
que desempenham a função traseira. Além disso, as instâncias
que desempenham as funções e e traseira só
poderão ser vinculadas se forem da mesma instância da classe Carro.
Ou seja, restrições adicionais se aplicam às instâncias das classes
Roda e Motor, quando elas estão desempenhando
as respectivas funções em uma instância da classe Carro. Essas
restrições não são verdadeiras para as instâncias Roda e Motor
em geral. Outras rodas e mecanismos podem estar
arbitrariamente vinculados conforme especificado na figura (a).

Exemplo: Partes exercendo suas funções dentro de uma classe estruturada
Conector
Um conector é uma instância de relacionamento entre duas peças em uma classe
estruturada. É um link para permitir a comunicação. Os conectores podem ser implementados
por associações comuns ou por relacionamentos transientes, como parâmetros de procedimentos,
variáveis, valores globais ou outros mecanismos.
A "fiação" interna de uma classe estruturada é especificada com conectores
de montagem e conectores de delegação:
- Na implementação de uma classe estruturada, conectores de montagem
conectam portas de diferentes peças. Uma mensagem enviada em uma porta de uma classe
estruturada é recebida em uma porta conectada de uma outra classe estruturada. Um conjunto
de peças podem ser cabeadas juntas por meio de suas portas. Uma peça não precisa saber nada
sobre as outras peças, exceto que elas existem e atendem às restrições sobre portas
conectadas. A comunicação entre classes estruturadas é modelada por suas portas.
- Um conector de delegação conecta uma porta externa de uma classe
estruturada a uma porta em uma de suas peças internas. Uma mensagem recebida pela porta
externa é transmitida para a porta na parte interna; uma mensagem enviada pela porta
interna é transmitida para a porta externa e, em seguida, para a classe estruturada
conectada a ela.
Porta
Uma porta é um recurso estrutural de uma classe estruturada. O encapsulamento pode
ser aumentado, forçando as comunicações de fora da classe estruturada serem transmitidas
por meio de portas que obedecem a interfaces declaradas, resultando em exatidão adicional
na especificação e interconexão dessa classe estruturada.
As interfaces requeridas e fornecidas de uma porta especificam tudo o que é necessário
para interações por meio do ponto de interação. Se todas as interações de uma classe
estruturada com seu ambiente forem alcançadas por meio de portas, as partes internas da
classe estruturada serão totalmente isoladas do ambiente. Isso permite que
uma classe estruturada seja utilizada em qualquer contexto que atenda às restrições
especificadas por suas portas.
Não há nenhuma suposição sobre como uma porta é implementada. Ela poderia ser implementada
como um objeto explícito ou poderia simplesmente ser um conceito virtual que não
aparece explicitamente na implementação.
Exemplos de portas são fornecidos a seguir:
Exemplo 1

Porta de um Motor sendo utilizado por um Carro e um Barco
A figura acima mostra uma classe Motor com uma porta p
e duas interfaces:
- Uma interface fornecida trem de força, que especifica os serviços
que o motor oferece nesta porta (isto é, as operações e
recepções acessíveis por comunicação que chegam a esta porta).
- Uma interface requerida motor, que especifica os serviços
que o motor espera que seu ambiente forneça.
Na porta p, a classe Motor está completamente
encapsulada; ela pode ser especificada sem qualquer conhecimento do ambiente em que
o motor será incorporado. Desde que o ambiente obedeça às restrições
expressas pelas interfaces fornecidas e requeridas do motor, este
funcionará corretamente.
Para ilustrar isso, dois usos da classe Motor são mostrados
neste exemplo:
- A classe Carro conecta a porta p do mecanismo
a um conjunto de rodas por meio do eixo.
- A classe Barco conecta a porta p do mecanismo
a uma hélice por meio do eixo.
Desde que a interação entre o Motor e a peça
vinculada a sua porta p obedeça às restrições especificadas pelas
interfaces fornecidas e requeridas, o motor funcionará conforme especificado,
independentemente se é um motor de um carro ou um motor de um barco.
Além disso, mesmo se o Mecanismo tivesse outras portas declaradas, como uma
porta f para Consumo de Combustível, as rodas de
um carro e a hélice de um barco ainda acessariam o Mecanismo
pela porta p. A porta f seria do interesse de
um medidor de combustível, não importa que tipo de combustível está sendo utilizado e que tipo de medidor
de combustível os carros e os barcos podem ter.
Exemplo 2
Este exemplo de portas baseia-se na API de Log Java ([JAV03]), que é um pacote que
fornece as classes e interfaces a seguir dos recursos de log núcleo da
plataforma Java 2, entre outros:
Registrador é a entidade principal na qual os aplicativos fazem
chamadas de log. Ele é utilizado para registrar mensagens de um sistema ou componente de aplicativo específico
Nível fornece uma orientação para a importância e urgência de uma
mensagem de log
Filtro fornece controle granular do que é registrado,
além do controle fornecido pelos níveis de log
Rotina de Tratamento obtém as mensagens de um Registrador e a exporta para
diferentes destinos (memória, fluxos de saída, consoles, arquivos e soquetes)
Formatador fornece suporte para formatar registros de log
Essas classes e interfaces estão envolvidas em dois tipos importantes
de colaborações. Algumas classes e interfaces são utilizadas para gravar no log enquanto
outras são utilizadas para administrar o log. A figura a seguir mostra duas colaborações
diferentes que os clientes e administradores têm com o log, modeladas como
colaborações UML:
Colaboração de Gravação, em que a função LogClient
conecta-se à função LogWriter para gravar no
log.
A colaboração de Administração em que a função de LogAdministrator
se conecta à função de LogController para acessar oe log e alterar as configurações do
log.

Diferentes colaborações que clientes e administradores
têm com o log
Uma representação possível da UML 2.0 para modelar os serviços de log e suas colaborações
seria utilizar um componente com portas e interfaces declaradas, conforme mostrado
na figura a seguir:

O pacote da API de Log Java seno implementado como um componente
com interfaces fornecidas agrupadas em portas
Na especificação da API de Log Java, alguns dos serviços de log foram implementados
como classes e outros como interfaces. Neste exemplo, modelamos cada um desses serviços
conforme as interfaces fornecidas, que poderiam ser realizadas pelas peças dentro do componente. Os dois tipos diferentes de comportamento relacionados às colaborações de Gravação
e Administração mencionadas acima poderiam ser representados
por interfaces logicamente agrupadas em portas. Portanto, temos:
As interfaces Registrador e Nível agrupadas na porta
LogWriter. Essas interfaces são acessadas por clientes de log para
gravar no log.
As interfaces Rotina de Tratamento, Filtro e Formatador
agrupadas na porta LogController. Essas interfaces
são acessadas por administradores de log, que acessam o log e alteram as configurações.
Essa alternativa de modelagem conduz a uma separação de interesses, agrupando logicamente
as interfaces em diferentes portas. Temos precisão adicional para a especificação
do componente e a interconexão que ela pode ter com o mundo externo.
Modelagem
Durante o design, as classes e os componentes podem ser decompostos em coleções de
peças conectadas que, por sua vez, podem ser decompostas ainda mais.
Um diagrama de estrutura composta pode ser utilizado para mostrar a decomposição
de uma classe estruturada. Como exemplo, a figura a seguir mostra um diagrama de estrutura
composta para bilheteria no sistema de ingressos. Esta classe é decomposta
em três partes:
- Uma interface com o vendedor de ingressos
- Um guia de desempenho que recupera desempenhos de acordo com a data e outros
critérios
- Um conjunto de bancos de dados que contém os dados nos desempenhos e ingressos.
Cada peça interage por meio de uma interface bem definida especificada por suas portas.
Toda a bilheteria interage com o exterior por meio de uma porta. As mensagens nessa
porta são enviadas para a classe de vendedor de ingressos, mas a estrutura interna
da classe de bilheteria é oculta para os clientes externos.

Exemplo: Diagrama de estrutura composta para um sistema de registro.
Representação da UML 1.x
Observe que a Classe Estruturada é um novo conceito na UML 2.0.
Se a sua ferramenta suporta somente UML 1.5, uma representação alterantiva também é discutida
em Artefato: Cápsula e Diretrizes:
Cápsula.
Consulte Diferenças entre a UML
1.x e a UML 2.0 para obter informações adicionais.
|