Finalidade
  • Garantir que a classe informe o comportamento necessário às realizações dos casos de uso.
  • Garantir que sejam fornecidas informações suficientes para implementar a classe sem ambigüidades.
  • Tratar dos requisitos não-funcionais relativos à classe.
  • Incorporar os mecanismos de design usados pela classe.
Passos
Artefatos Informados: Artefatos Resultantes:
Papel: Designer
Mentor de Ferramentas:

Detalhamentos do Fluxo de Trabalho:

As classes são o motor propulsor do esforço de design — elas executam o trabalho real do sistema. Os outros elementos de design — subsistemas, pacotes e colaborações apenas descrevem como as classes são agrupadas e como elas operam entre si.

As cápsulas também são classes estereotipadas, usadas para representar threads de execução simultânea em sistemas de tempo real. Nesses casos, outras classes de design são classes 'passivas', usadas no contexto de execução fornecido pelas cápsulas 'ativas'. Mesmo quando o arquiteto e o designer de software não usam uma abordagem baseada em cápsulas, é possível modelar comportamentos concorrentes com as classes 'ativas'.

As classes ativas são classes de design que coordenam e orientam o comportamento das classes passivas - uma classe ativa é aquela cujas instâncias são os objetos ativos que possuem seu próprio thread de controle.

Criar Classes de Design Inicial Início da página

Diretrizes:

Comece criando uma ou várias classes de design (iniciais) para a classe de análise usada como informação para essa atividade e atribua as dependências de rastreamento. As classes de design criadas nesse passo serão refinadas, ajustadas, divididas e/ou mescladas nos passos subseqüentes quando forem atribuídas várias propriedades de "design", como operações, métodos e uma máquina de estado, que descrevem como a classe de análise foi projetada.

Dependendo do tipo da classe de análise (fronteira, entidade ou controle) que será criada, há estratégias específicas que podem ser usadas para criar as classes de design iniciais.

Design das Classes de Fronteira

Como regra geral de análise, haverá uma classe de fronteira para cada janela ou para cada formulário na interface do usuário. Como conseqüência, as classes de fronteira podem ter responsabilidades de um nível bem alto e, por isso, precisam ser refinadas e detalhadas nesse passo.

O design das classes de fronteira depende das ferramentas de desenvolvimento de interface do usuário (GUI) disponíveis para o projeto. Usando a tecnologia atual, é bastante comum que a construção visual da interface do usuário seja feita diretamente na ferramenta de desenvolvimento, o que, por conseqüência, cria automaticamente as classes de interface do usuário que precisam estar relacionadas ao design das classes de controle e/ou entidade. Se o ambiente de desenvolvimento da interface gráfica do usuário criar as classes de suporte automaticamente, será necessário implementar a interface do usuário, mas não será preciso considerar essas classes no design - projete apenas o que o ambiente de desenvolvimento não criar para você.

Os esboços são fontes adicionais de informações para esse trabalho, assim como as capturas de tela de um protótipo de interface do usuário, que podem ser criadas para especificar melhor os requisitos estabelecidos nas classes de fronteira.

As classes de fronteira que representam as interfaces nos sistemas existentes são, em geral, modeladas como subsistemas, pois normalmente têm um comportamento interno complexo. Se o comportamento da interface for simples (talvez atuando apenas como um mecanismo de acesso para a API existente do sistema externo), é possível representar a interface com uma ou mais classes de design. Se este for o caminho escolhido, use uma única classe de design por protocolo, interface ou API, e observe os requisitos especiais da classe sobre os padrões usados e outros itens.

Design de Classes de Entidade

Durante o processo de análise, as classes de entidade representam unidades manipuladas de informações. Geralmente, os objetos da entidade são passivos e persistentes. Durante a análise, essas classes de entidade podem ser identificadas e associadas com o mecanismo de análise para garantir a persistência. O detalhamento de um mecanismo de persistência com base no banco de dados está definido em Atividade: Design de Banco de Dados. As considerações sobre desempenho podem impor a refatoração das classes persistentes, provocando mudanças no Modelo de Design, que serão abordadas em conjunto em Papel: Designer de Banco de Dados e Papel: Designer.

Uma abordagem mais ampla das questões de design para as classes persistentes será apresentada a seguir em Identificar Classes Persistentes.

Design de Classes de Controle

Um objeto de controle é responsável pelo gerenciamento do fluxo de um caso de uso e, portanto, coordena a maioria de suas ações. Os objetos de controle encapsulam a lógica que não está particularmente relacionada às questões da interface do usuário (objetos de fronteira) ou da engenharia de dados (objetos de entidade). Muitas vezes, essa lógica denomina-se lógica de aplicativo ou lógica de negócios.

Sendo assim, pelo menos as questões abaixo precisam ser consideradas durante o design das classes de controle:

  • Complexidade. O comportamento simples de controlar ou coordenar pode ser tratado pelas classes de fronteira e/ou de entidade. No entanto, à medida que aumenta a complexidade do aplicativo, podem surgir desvantagens significativas dessa abordagem:
  • O comportamento de coordenação dos casos de uso incorpora-se à interface do usuário, dificultando a realização de mudanças no sistema.
  • A mesma interface do usuário não pode ser usada em realizações de casos de uso distintas sem dificuldades.
  • A interface do usuário fica sobrecarregada com funcionalidades adicionais, o que prejudica seu desempenho.
  • Os objetos de entidade podem ficar sobrecarregados com o comportamento específico dos casos de uso, o que reduz sua generalidade.

Para evitar esses problemas, as classes de controle foram introduzidas para fornecer o comportamento relacionado à coordenação dos fluxos de eventos

  • Probabilidade de mudanças. Se houver pouca probabilidade de mudança dos fluxos de eventos ou se o custo for irrisório, a despesa extra e a complexidade de classes de controle adicionais não se justificam.
  • Distribuição e desempenho. A necessidade de executar partes do aplicativo em diversos nós ou em diversos espaços do processo gera a necessidade de especialização dos elementos de modelo de design. Freqüentemente, essa especialização é acompanhada da inclusão de objetos de controle e da distribuição de comportamento das classes de fronteira e das classes de entidade para as classes de controle. Com esse procedimento, as classes de fronteira passam a fornecer apenas serviços de interface do usuário, e as classes de entidade passam a fornecer apenas serviços de dados. As classes de controle fornecem os outros tipos de serviços.
  • Gerenciamento de transações. O gerenciamento de transações é uma atividade clássica de coordenação. Se não houver um framework para tratar do gerenciamento de transações, você pode ter uma ou mais classes de gerente de transações que interagirão para garantir a integridade das transações.

Lembre-se de que nos últimos dois casos, se a classe de controle representar um thread de controle separado, será melhor usar uma classe ativa para modelar o thread de controle.

Em um sistema de tempo real, o uso de Artefato: Cápsulas é a abordagem de modelagem preferencial nessas circunstâncias.

Identificar Classes Persistentes Início da página

As classes que precisam armazenar seu estado em uma mídia permanente são denominadas 'persistentes'. A necessidade de armazenar seu estado pode ser para registrar permanentemente as informações de classe, para fins de backup em casos de falhas do sistema ou para intercâmbio de informações. Uma classe persistente pode ter instâncias persistentes ou transientes. Denominar uma classe como 'persistente' significa que algumas instâncias da classe talvez precisem ser persistentes.

A identificação das classes persistentes serve para notificar o Papel: Designer de Banco de Dados de que a classe precisa de atenção especial às suas características de armazenamento físico. Notifica também o Papel: Arquiteto de Software de que a classe precisa ser persistente, e o Papel: Designer, responsável pelo mecanismo de persistência, de que as instâncias da classe precisam ser persistentes.

Devido à necessidade de uma estratégia persistente coordenada, o Papel: Designer de Banco de Dados é responsável por mapear classes persistentes no banco de dados usando um framework de persistência. Se o projeto estiver desenvolvendo um framework de persistência, o desenvolvedor do framework também será responsável por conhecer os requisitos de persistência das classes de design. Para oferecer a essas pessoas as informações necessárias, basta indicar que a classe ou, mais precisamente, as instâncias da classe, são persistentes. Incorpore também os mecanismos de design que correspondem aos mecanismos de persistência encontrados durante a análise.

Exemplo

O mecanismo de análise para a verificação de persistência pode ser executado por um dos seguintes mecanismos de design:

  • Armazenamento em memória
  • Placa Flash
  • Arquivo binário
  • Sistema de Gerenciamento de Banco de Dados (DBMS)
  • Depende do que for exigido pela classe.

Lembre-se de que os objetos persistentes podem não ser os únicos derivados das classes de entidade. Os objetos persistentes também podem ser necessários para tratar requisitos não-funcionais em geral. Exemplos são os objetos persistentes necessários para manter as informações relevantes ao controle do processo ou as informações de estado entre as transações.

Definir Visibilidade da Classe Início da página

Para cada classe, determine a visibilidade que ela terá no pacote em que reside. Uma classe 'pública' pode ser referenciada fora do pacote que a contém. Uma classe 'privada' (ou uma cuja visibilidade seja 'implementação') pode ser referenciada apenas pelas classes contidas no mesmo pacote.

Definir Operações Início da página

Identificar Operações

Para identificar Operações em classes de design:

  • Estude as responsabilidades de cada classe de análise correspondente criando uma operação para cada responsabilidade. Use a descrição da responsabilidade como a descrição inicial da operação.
  • Analise as realizações de casos de uso nas participações de classe para verificar como as operações são usadas por essas realizações. Expanda as operações, uma realização de casos de uso por vez, refinando as operações, suas descrições, tipos e parâmetros de retorno. Cada requisito de realização dos casos de uso identificado como classe é descrito textualmente no Fluxo de Eventos da realização do caso de uso.
  • Analise os Requisitos Especiais do caso de uso para certificar-se de não ter esquecido os requisitos implícitos da operação que deve ser informada nesse documento.

As operações devem oferecer suporte às mensagens que aparecem em diagramas de seqüência, porque os scripts e as mensagens (especificações de mensagens temporárias) que ainda não foram atribuídos às operações descrevem o comportamento esperado da classe. Este é um exemplo de diagrama de seqüência:

As mensagens são a base de identificação das operações.

As realizações de casos de uso fornecem informações suficientes para identificar todas as operações. Para encontrar as outras operações, considere o seguinte:

  • Há alguma maneira de inicializar uma nova instância da classe, inclusive por meio da conexão com instâncias de outras classes às quais ela esteja associada?
  • Há necessidade de executar testes para verificar se duas instâncias da classe são 'idênticas'?
  • Há necessidade de criar uma cópia de uma instância da classe?
  • Há necessidade de os mecanismos usados pela classe executarem alguma operação (exemplo: um mecanismo de 'coleta de lixo' pode exigir que algum objeto elimine todas as referências a outros objetos para liberar recursos não utilizados)?

Não defina operações que apenas obtêm e definem os valores de atributos públicos (consulte Definir Atributos e Associações). Geralmente, eles são gerados por recursos de criação de código e não precisam ser definidos explicitamente.

Nomear e Descrever as Operações

As convenções de nomes da linguagem de implementação devem ser usadas para nomear operações, tipos e parâmetros de retorno. Elas estão descritas em Artefato: Guia de Design.

Para cada operação, você deve definir:

  • O nome da operação. O nome deve ser curto e descrever o resultado da operação.
    • Os nomes de operação devem seguir a sintaxe da linguagem de implementação. Exemplo: find_location é um nome aceitável para C++ ou Visual Basic, mas não para Smalltalk (não utiliza sublinhados). Um nome mais adequado para todas as linguagens seria findLocation.
    • Evite nomes que sugerem como a operação é executada (exemplo: Funcionário.salário() é melhor do que Funcionário.calcularSalários(), porque o último implica a realização de um cálculo. A operação pode apenas retornar um valor em um banco de dados).
    • O nome da operação deve demonstrar claramente sua finalidade. Evite nomes não específicos, como obterDados, pois não são descritivos do resultado que retornam. Use um nome que indique exatamente o que é esperado, como obterEndereço. Ainda melhor, seria dar à operação o nome da propriedade retornada ou definida. Se houver um parâmetro, ele definirá a propriedade. Se não houver, ele obterá a propriedade. Exemplo: a operação address retorna o endereço de um Cliente, enquanto address(aString) define ou altera o endereço do Cliente. A natureza 'obter' e 'definir' é implícita à assinatura da operação.
    • As operações que são teoricamente idênticas devem ter o mesmo nome, ainda que sejam definidas por classes distintas, implementadas de maneiras totalmente diversas ou que tenham vários parâmetros. Uma operação que cria um objeto, por exemplo, deve ter o mesmo nome em todas as classes.
    • Se as operações em várias classes têm a mesma assinatura, elas deverão retornar o mesmo tipo de resultado, apropriado ao objeto receptor. Este é um exemplo do conceito de polimorfismo, que indica que objetos distintos devem responder à mesma mensagem de maneira semelhante. Exemplo: a operação nome deve retornar o nome do objeto, independentemente de como o nome é armazenado ou obtido. Siga esse princípio para facilitar a compreensão do modelo.
  • O tipo de retorno. O tipo de retorno deve ser a classe do objeto retornada pela operação.
  • Uma descrição resumida. Deve ser o mais expressiva possível. O nome da operação é, geralmente, vago e, portanto, não é muito útil para demonstrar o que a operação executa. Atribua à operação uma descrição resumida que consista em algumas frases relativas à perspectiva que o usuário tem da operação.
  • Os parâmetros. Para cada parâmetro, crie um nome curto e descritivo. Escolha sua classe e atribua uma descrição resumida. Quando especificar parâmetros, lembre-se de que quanto menos parâmetros, maior é a usabilidade. Com poucos parâmetros, a operação fica mais fácil de ser entendida e, portanto, há maior probabilidade de encontrar operações semelhantes. Pode ser preciso dividir uma operação, com vários parâmetros usados em várias operações. A operação deve ser compreendida por aqueles que desejam utilizá-la. A descrição resumida deve incluir as seguintes informações:
    • O significado dos parâmetros (se não estiver evidente em seus nomes).
    • Se o parâmetro é passado por valor ou por referência
    • Os parâmetros que devem ter valores informados
    • Os parâmetros que podem ser opcionais e seus valores padrão, caso nenhum valor seja especificado
    • Faixa de parâmetros válidos (se aplicável)
    • O que é feito na operação.
    • Os parâmetros passados por referência que são alterados pela operação.

Depois de definir as operações, complete os diagramas de seqüência com as informações sobre as operações disparadas por cada mensagem.

Consulte a seção "Operações de Classe", em Diretrizes: Visão de Design, para obter mais informações. Consulte também a seção "Definição de Operações", em Diretrizes: Design de Classes em Visual Basic, para obter informações sobre o Visual Basic®.

Definir Visibilidade da Operação

Para cada operação, identifique a visibilidade de exportação da operação. Estas são as opções possíveis:

  • Pública: a operação é visível para elementos de modelo que não sejam a própria classe.
  • Implementação: a operação é visível somente dentro da própria classe.
  • Protegida: a operação é visível somente para a própria classe e suas subclasses ou para amigos da classe (dependente de linguagem)
  • Privada: a operação é visível somente para a própria classe e para os amigos da classe

Escolha a visibilidade que, embora seja a mais restrita, possa atender aos objetivos da operação. Para fazer isso, verifique os diagramas de seqüência e, para cada mensagem, determine se ela é originária de uma classe externa ao pacote do receptor (requer visibilidade pública), de uma classe interna ao pacote (requer visibilidade de implementação), de uma subclasse (requer visibilidade protegida), da própria classe ou de um amigo (requer visibilidade privada).

Definir Operações de Classe

Em geral, as operações são operações de 'instância', ou seja, elas são executadas em instâncias da classe. Em alguns casos, no entanto, uma operação se aplica a todas as instâncias da classe e, portanto, ela é uma operação executada no escopo de classe. O receptor da operação de 'classe' é, na verdade, uma instância de uma metaclasse, a descrição da própria classe, e não uma instância específica da classe. Entre os exemplos das operações de classe estão as mensagens que criam novas instâncias e que retornam todas as instâncias de uma classe e assim por diante.

Para indicar uma operação no escopo de classe, a seqüência de caracteres da operação deve ser sublinhada.

Definir Métodos Início da página

Um método especifica a implementação de uma operação. Em muitos casos, os métodos são implementados diretamente na linguagem de programação. Isso ocorre quando o comportamento exigido pela operação é suficientemente definido pelo nome, pela descrição e pelos parâmetros da operação. Quando a implementação requer o uso de um algoritmo específico ou requer mais informações do que as apresentadas na descrição da operação, é necessário usar uma descrição de método separada. O método descreve como a operação funciona, e não apenas o que ela faz.

Se for descrito, o método deverá abordar:

  • Como as operações devem ser implementadas.
  • Como os atributos devem ser implementados e usados para implementar as operações.
  • Como os relacionamentos devem ser implementados e usados para implementar as operações.

Naturalmente, os requisitos variam entre um caso e outro. Contudo, as especificações do método para uma classe devem sempre informar:

  • O que deve ser feito de acordo com os requisitos?
  • Quais são os outros objetos e suas operações a serem usados?

Requisitos mais específicos podem incluir:

  • Como os parâmetros devem ser implementados.
  • Os algoritmos especiais que serão usados.

Os diagramas de seqüência são uma importante fonte para esse tipo de informação. A partir daí, ficará claro quais serão as operações usadas em outros objetos quando uma operação for executada. É necessária uma especificação de quais operações serão usadas em outros objetos para permitir a implementação completa da operação. A produção de uma especificação de método completa requer que você identifique as operações para os objetos envolvidos e que você verifique os respectivos diagramas de seqüência.

Consulte a seção "Definição de Métodos (UML) ", em Diretrizes: Design de Classes em Visual Basic, para obter informações sobre o Visual Basic®.

Definir Estados Início da página

Em algumas operações, o comportamento depende do estado do objeto receptor. Uma máquina de estado é uma ferramenta para descrever os estados em que o objeto pode estar e os eventos que fazem o objeto passar de um estado para outro. Consulte Diretrizes: Diagrama de Estados. As máquinas de estado são bastante úteis para descrever as classes ativas.

A utilização de máquinas de estado é particularmente importante para definir o comportamento de Artefato: Cápsulas.

Este é um exemplo de máquina de estado simples:

Um diagrama de estados para uma Bomba de Combustível

Cada evento de transição de estado pode ser associado a uma operação. Dependendo do estado do objeto, a operação pode apresentar um comportamento diferente. Os eventos de transição descrevem como isso ocorre.

A descrição do método para a operação associada deve ser atualizada com as informações específicas de estados, indicando, para cada estado relevante, o que a operação deve fazer. Em geral, os estados são representados com o uso de atributos. Os diagramas de estados funcionam como fonte de informações para a identificação do atributo.

Para obter mais informações, consulte Diretrizes: Diagrama de Estados.

Consulte a seção "Definição de Estados ", em Diretrizes: Design de Classes em Visual Basic, para obter informações sobre o Visual Basic®.

Definir Atributos Início da página

Durante a definição de métodos e a identificação de estados, os atributos requisitados pela classe para executar suas operações são identificados. Os atributos permitem o armazenamento de informações para a instância da classe e, geralmente, são usados para representar o estado da instância da classe. As classes usam atributos quando mantêm suas próprias informações. Para cada atributo, defina:

  • seu nome, que deve obedecer às convenções de nomeação do projeto e da linguagem de implementação;
  • seu tipo, que será um tipo de dados elementar, com suporte da linguagem de implementação;
  • seu valor padrão ou inicial, com o qual o atributo será inicializado quando novas instâncias da classe forem criadas;
  • sua visibilidade, que adotará um dos seguintes valores:
    • Pública: o atributo é visível tanto dentro como fora do pacote que contém a classe.
    • Protegida: o atributo é visível somente para a própria classe e suas subclasses ou para amigos da classe (dependente de linguagem)
    • Privada: o atributo é visível somente para a própria classe e para os amigos da classe.
    • Implementação: o atributo é visível somente para a própria classe.
  • para as classes persistentes, se o atributo é persistente (padrão) ou transiente. Mesmo que a própria classe seja persistente, nem todos os atributos da classe precisam ser persistentes.

Verifique se todos os atributos são necessários. Os atributos devem ser justificados - é fácil incluir atributos no início do processo e mantê-los, mesmo quando não são mais necessários, por falta de perspectiva. Os atributos extras, multiplicados por milhares ou milhões de instâncias, podem causar um forte efeito sobre os requisitos de desempenho e armazenamento do sistema.

Consulte a seção "Atributos", em Diretrizes: Classe de Design, para obter mais informações sobre atributos.

Definir Dependências Início da página

Para os casos nos quais é necessária a comunicação entre os objetos, levante as seguintes questões:

  • A referência feita ao receptor é passada em forma de parâmetro para a operação? Se for, estabeleça uma dependência entre as classes emissora e receptora em um diagrama que contenha as duas classes. Além disso, se for usado o formato do diagrama de colaboração para as interações, qualifique a visibilidade do vínculo, definindo-o como 'parâmetro'.
  • O receptor é 'global'? Se for, estabeleça uma dependência entre as classes emissora e receptora em um diagrama que contenha as duas classes. Além disso, se for usado o formato do diagrama de colaboração para as interações, qualifique a visibilidade do vínculo, definindo-o como 'global'.
  • O receptor é um objeto temporário criado e destruído durante a própria operação? Se for, estabeleça uma dependência entre as classes emissora e receptora em um diagrama que contenha as duas classes. Além disso, se for usado o formato do diagrama de colaboração para as interações, qualifique a visibilidade do vínculo, definindo-o como 'local'.

Lembre-se de que os vínculos modelados dessa maneira são transientes, existem apenas por um período limitado, no contexto específico da colaboração. Nesse sentido, eles são instâncias do papel de associação na colaboração. Contudo, o relacionamento em um modelo de classe (isto é, independente do contexto) deve ser, como descrito acima, uma dependência. Como definido em [RUM98], em transient link (vínculo transitório): "É possível modelar esses vínculos como associações, mas as condições nas associações devem ser definidas muito amplamente, pois perdem muito de sua precisão ao limitarem as combinações de objetos ". Nessa situação, a modelagem de uma dependência é menos importante do que a modelagem do relacionamento na colaboração, porque a dependência não descreve o relacionamento completamente, somente indica que ele existe.

Definir Associações Início da página

As associações proporcionam o mecanismo para os objetos se comunicarem entre si. Elas oferecem aos objetos um "conduto" ao longo do qual as mensagens podem fluir. Elas também documentam as dependências entre as classes, destacando que as mudanças efetuadas em uma classe poderão se refletir em muitas outras classes.

Examine as descrições de método para cada operação a fim de entender como as instâncias da classe se comunicam e colaboram com outros objetos. Para enviar uma mensagem para outro objeto, o objeto deve fazer uma referência ao receptor da mensagem. Um diagrama de colaboração (uma representação alternativa de um diagrama de seqüência) mostrará a comunicação do objeto em termos de vínculos, como indicado abaixo:

Definir Associações e Agregações

As mensagens restantes usarão uma associação ou uma agregação para especificar o relacionamento entre as instâncias de duas classes que se comunicam. Consulte Diretrizes: Associação e Diretrizes: Agregação para obter informações sobre como escolher a representação apropriada. Para essas duas associações, defina a visibilidade do vínculo como 'campo' nos diagramas de colaboração. Outros tarefas:

  • Estabelecer a navegabilidade das associações e agregações. Para fazer isso, considere o tipo de navegabilidade necessário para as instâncias do vínculo nos diagramas de interação. Como, por padrão, a navegabilidade tem um valor verdadeiro, você só precisa encontrar as associações (e agregações) nas quais os papéis em vínculos opostos de todos os objetos de uma classe da associação não precisem de navegabilidade. Nesses casos, defina a navegabilidade com um valor falso no papel da classe.
  • Se houver atributos na própria associação (representada por "classes de associação"), crie uma classe de design para representar a 'classe de associação', com os atributos adequados. Intercale essa classe entre as outras duas classes e estabeleça associações com a multiplicidade adequada entre a classe de associação e as outras duas classes.
  • Especifique se as "extremidades da associação" devem ser ordenadas ou não. Faça isso se os objetos associados a um objeto na outra extremidade da associação tiver um ordenamento a ser preservado.
  • Se a classe associada (ou agregada) é referenciada apenas pela classe atual. Considere se a classe deve ser aninhada. Entre as vantagens das classes aninhadas estão o serviço de mensagens mais rápido e um modelo de design mais simples. As desvantagens incluem o espaço para classe aninhada alocado estaticamente, mesmo que haja instâncias da classe aninhada, falta de identidade de objetos separada da classe em que ele está contido e incapacidade de fazer referência a instâncias da classe aninhada fora da classe que a contém.

As associações e agregações são melhor definidas em um diagrama de classes que ilustre as classes associadas. O diagrama de classes deve estar incluído no pacote que contém as classes associadas. Este é um exemplo de diagrama de classes, indicando as associações e agregações existentes:

Exemplo de Diagrama de Classe, com as Associações, Agregações e Generalizações entre as Classes.

Tratamento de Associações de Assinatura entre as Classes de Análise

As associações de assinatura entre as classes de análise são usadas para identificar dependências de eventos entre as classes. No Modelo de Design, devemos tratar explicitamente dessas dependências de eventos, usando os frameworks para tratar eventos disponíveis ou por meio do design e da criação do nosso próprio framework para esse fim. Em algumas linguagens de programação, como Visual Basic, esse é um procedimento direto executado com a declaração, ocorrência e tratamento dos eventos correspondentes. Em outras linguagens, talvez seja necessário usar alguma biblioteca adicional de funções reutilizáveis para tratar assinaturas e eventos. Se não for possível adquirir a funcionalidade, ela terá que ser projetada e criada. Consulte também Diretrizes: Associação de Assinatura.

Definir Generalizações Início da página

As classes podem ser organizadas em uma hierarquia de generalização para refletir um comportamento e uma estrutura comuns. Uma superclasse comum pode ser definida para que suas subclasses possam herdar tanto o comportamento quanto a estrutura. A generalização é uma comodidade notacional, que permite definir uma estrutura e um comportamento comuns em um único local para serem reutilizados em outros locais, onde a mesma estrutura e o mesmo comportamento serão encontrados. Consulte Diretrizes: Generalização, para obter mais informações sobre os relacionamentos de generalização.

Em caso de generalização, crie uma superclasse comum para conter os atributos, as associações, as agregações e as operações comuns. Remova o comportamento comum das classes que passarão a ser subclasses da superclasse. Defina um relacionamento de generalização da subclasse com a superclasse.

Resolver Conflitos entre Casos de Uso Início da página

Finalidade
  • Evitar conflitos de simultaneidade causados pelo acesso de dois ou mais casos de uso às instâncias da classe de design, possivelmente de formas incompatíveis.
Conceitos: Simultaneidade

Uma das dificuldades em utilizar um caso de uso após o outro no processo de design é o fato de dois casos de uso ou mais poderem disparar simultaneamente operações nos objetos de design, possivelmente de maneiras conflitantes. Nesses casos, os conflitos de simultaneidade devem ser identificados e resolvidos explicitamente.

Se o serviço de mensagens síncronas for usado, a execução de uma operação bloqueará as chamadas subseqüentes feitas para os objetos, até a conclusão da operação. O serviço de mensagens síncronas implica uma ordem na qual o primeiro a chegar é o primeiro a ser atendido para o processamento das mensagens. Esse procedimento pode resolver o conflito de simultaneidade nos casos em que todas as mensagens têm a mesma prioridade ou quando elas são executadas no mesmo thread. Nos casos em que um objeto pode ser acessado por diversos threads de execução (representados por classes ativas), devem ser usados mecanismos explícitos para impedir ou resolver o conflito de simultaneidade.

Em sistemas de tempo real, nos quais os threads são representados por Artefato: Cápsulas, esse problema ainda precisa ser solucionado para o acesso simultâneo a objetos passivos. Por outro lado, as cápsulas proporcionam um mecanismo de enfileiramento e impõem uma semântica de execução-conclusão para tratar o acesso simultâneo. Uma solução recomendada é inserir os objetos passivos em cápsulas. Dessa forma, não há problema de acesso simultâneo, por causa da semântica da própria cápsula.

É possível que diversas operações executadas no mesmo objeto sejam disparadas simultaneamente por threads de execução distintos sem ocorrer conflito de simultaneidade. O nome e o endereço de um cliente podem ser modificados ao mesmo tempo sem que haja conflito. O conflito só ocorre quando dois threads de execução distintos tentam modificar a mesma propriedade do objeto.

Para cada objeto que pode ser acessado simultaneamente por diversos threads de execução, identifique as seções do código que precisam ser protegidas de acesso simultâneo. No início da fase de Elaboração, é impossível identificar os segmentos de código específicos. As operações que devem ser protegidas são suficientes. Em seguida, selecione ou projete os mecanismos de controle de acesso apropriados para evitar o conflito devido ao acesso simultâneo. Exemplos desses mecanismos são o enfileiramento de mensagens para serializar o acesso, o uso de semáforos (ou 'tokens') para permitir o acesso a apenas um thread por vez ou outras variantes de mecanismos de bloqueio. A escolha do mecanismo depende bastante da implementação e, em geral, varia de acordo com a linguagem de programação e o ambiente operacional. Consulte o Artefato: Guia de Design específico ao projeto, para obter informações sobre como selecionar os mecanismos de simultaneidade.

Tratar Requisitos Não-funcionais em Geral Início da página

As Classes de Design devem ser refinadas para tratar de requisitos não-funcionais gerais, como descrito no Guia de Design específico do projeto. Uma informação importante para esse passo são os requisitos não-funcionais para uma classe de análise, que já podem estar descritos em seus requisitos especiais e responsabilidades. Esses requisitos são, muitas vezes, especificados em termos dos mecanismos arquiteturais (análise) necessários para a realização da classe. Nesse passo, a classe é refinada para incorporar os mecanismos de design correspondentes a esses mecanismos de análise.

Os mecanismos de design disponíveis são identificados e caracterizados pelo arquiteto de software em Artefato: Guia de Design. Para cada mecanismo de design necessário, qualifique quantas características puder, informando grupos quando possível. Consulte Atividade: Identificar Mecanismos de Design, Conceitos: Mecanismos de Análise e Conceitos: Mecanismos de Design e Implementação para obter mais informações sobre os mecanismos de design.

Pode haver vários mecanismos e guias gerais de design a serem considerados quando as classes são projetadas:

  • Como usar os produtos e componentes existentes,
  • Como adaptar-se à linguagem de programação,
  • Como distribuir objetos,
  • Como obter um desempenho aceitável,
  • Como garantir certos níveis de segurança,
  • Como tratar os erros,
  • E outros..

Consulte a seção "Gerenciamento de Requisitos Não-funcionais em Geral" em Diretrizes: Design de Classes em Visual Basic, para obter informações sobre o Visual Basic®.

Avaliar os Resultados Início da página

Nesse ponto, analise o modelo de design para verificar se o seu trabalho está indo na direção correta. Não há necessidade de revisar o modelo detalhadamente, mas é importante considerar os seguintes pontos de verificação:

Copyright  (c) 1987 - 2001 Rational Software Corporation


Exibir o Rational Unified Process usando quadros

Rational Unified Process