Logo Passei Direto
Buscar

246975149-Modelagem-Orientada-a-Objetos-Com-UML

Ferramentas de estudo

Material
páginas com resultados encontrados.
páginas com resultados encontrados.

Prévia do material em texto

Dedicatória
Ao meu filho, Murilo, pelo estímulo, carinho e compreensão.
A quem se destina este livro
Este livro se destina a diferentes classes de leitores, que tem em comum o desejo de
conhecer técnicas para se descrever um software, seja porque são profissionais da área
da computação, seja porque acreditam que um software possa ajudá-los a melhorar o
seu negócio, seja ele qual for. Os leitores deste livro podem ser:
· Estudantes e Professores que podem encontrar neste livro apoio para o
desenvolvimento de cursos de Engenharia de Software, de Análise e Projeto de
Sistemas e para o desenvolvimento de projetos de software. Apesar da abordagem dada
a este trabalho não ter uma ênfase didática, ele pode ser utilizado como uma leitura
complementar. Especialmente nos capítulos iniciais, onde o livro tece os fundamentos
da orientação a objetos, o teor introdutório pode ser de grande ajuda a estudantes de
computação e áreas afins.
· Analistas de Sistema e Programadores de Computador envolvidos em
projetos de sistemas de software, que encontrarão reunidas neste livro algumas técnicas
úteis para o desenvolvimento de modelos orientados a objeto destes projetos. A adoção
destas técnicas pode ajudá-los a construir sistemas de software mais robustos, mais
confiáveis e de manutenção mais fácil.
· Usuários ou Gerentes de Projeto de Software que podem adotar algumas
das idéias presentes no livro para facilitar o planejamento de um projeto de software. A
leitura ajudará a criar uma linguagem comum entre o usuário, o gerente de projeto e a
equipe técnica de desenvolvimento. Como um projeto orientado a objetos requer uma
grande dose de modelagem, este livro pode uniformizar os termos usados na
comunicação com a equipe de projeto e ajudar a definir as etapas e produtos do projeto
de software.
Convenções adotadas neste livro
Para facilitar a leitura, este livro adota as seguintes convenções tipográficas:
· Os termos e conceitos importantes para o texto são escritos em negrito na
primeira vez em que eles aparecem. Estes termos podem ser encontrados novamente no
glossário, ao final do livro, onde recebem uma breve explicação.
· Os comandos e extratos de código, escritos em linguagem de programação
usam fonte currier, assim como os nomes de componentes e elementos do modelo,
quando citados no texto são escritos também em fonte currier, para diferenciá-los do
seu significado fora do escopo do programa.
· As citações, os extratos de textos da bibliografia e palavras em língua
estrangeira são escritos com caractér itálico.
· A lista de referências bibliográficas escontra-se no final do livro. Quando
citadas no texto, as referências aparecem entre parênteses com o nome do autor e o ano
de publicação. Por exemplo: (Beck, 1999) ou citado por Beck (1999).
· Os endereços de websites citados no texto e na bibliografia que podem ser
acessados pela internet são grifados como no exemplo: www.omg.org 
 
 
 
 
 
 
 
http://www.omg.org/
1. Introdução
 
Este capítulo discute a importância de se criar um modelo nos projetos de
software. Inicialmente, apresenta o caráter dualista do software: ora produto da
criatividade, ora trabalho sistemático de engenharia, para então discutir o porquê,
em ambos os casos, o modelo do software ser colocado no centro do processo de
desenvolvimento, como forma de unificar a visão do software entre os participantes
do projeto. O capítulo termina fazendo uma apresentação do restante do livro e de
como ele pode ser lido.
1.1. Introdução ao Desenvolvimento de Software
software é um produto da inteligência humana, por meio dele é possível se
preservar uma boa idéia e transmití-la para muitas outras pessoas. O software é uma
das poucas maneiras disponíveis capazes de capturar o conhecimento de alguém e
colocá-lo à serviço de outros. Existem algumas formas para se fazer isso, como os
livros ou as aulas nas escolas, mas nenhuma delas tem a capacidade de interação que o
software oferece, e que pode transformar o conhecimento capturado, diretamente, em
uma habilidade para o seu usuário. Um usuário, de posse de um software
adequadamente contruído, passa a ter novas habilidades e pode fazer coisas que antes
não sabia. Esta versatilidade, faz com que haja um grande interesse em converter
conhecimentos e habilidades, cada vez mais complexas, em software. Este livro trata
desta conversão, discute-se aqui como se transforma uma idéia em um software útil.
Como se captura uma idéia para que o desenvolvedor crie um sistema de software que
irá dar esta habilidade ao usuário:
Figura 1- O software pode transformar uma idéia em uma habilidade
Na construção de um software existe uma boa dose de criatividade, mas há uma
dose ainda maior de pensamento lógico e trabalho discipliando. O computador, uma das
maiores invenções do homem, é uma mero escravo do software. Todas as maravilhas
que um computador é capaz de desempenhar, dependem, diretamente, da
disponibilidade de um software projetado para realizá-las. Além da criatividade são
necessários métodos, procedimentos e muita disciplina para criar um software útil.
Toda esta organização é conseqüência da distância que separa os computadores dos
homens, e das suas idéias. Os computadores são meros autômatos, sabem realizar com
grande velocidade, e por repetidas vezes, tarefas simples, escritas em um programa de
computador. Os programas de computador são seqüências de comandos simples
escritos em uma linguagem de programação que pode ser entendida pelo computador, e
que ainda está muito longe da linguagem humana, e da complexidade do pensamento
humano.
A distância entre o conhecimento humano e as linguagens de programação se reflete
nas inúmeras dificuldades encontradas durante o desenvolvimento de um software.
Utiliza-se aqui o termo software para descrever um conceito muito mais amplo do que
um mero programa de computador. O sofware, que se refere este livro, compreende
toda a estratégia utilizada para resolver um problema real com apoio de um
computador. Mais do que uma série organizada de instruções, o software atende uma
finalidade, serve a um objetivo do seu utilizador. Nesta visão, o software se completa
ao hardware, o computador propriamente dito, e seus equipamentos periféricos, que em
conjunto compõem o que se pode chamar de sistema computacional. O conjunto de
partes relativa ao software no sistema computacional é o chamado sistema de
software.
A atividade de programação de computadores é apenas uma etapa do trabalho de
desenvolvimento de um software. Programar é escrever a solução de um problema, que
já está definida, em uma linguagem que possa ser entendida pelo computador.
Desenvolver um software compreende ainda muitas outras atividades como a de
analisar o problema que se pretende resolver, e fazer o design da solução. Desenvolver
software é resolver problemas por intermédio da programação de computadores é uma
atividade de engenharia, da assim chamada “ Engenharia de Software”.
Engenharia de Software é a ciência da computação aplicada na transformação do
computador em uma ferramenta de trabalho para os seus utilizadores. Ela é aplicada
hoje aos mais diferentes desafios, desde a manipulação de dados administrativos em um
sistema de informação gerencial até a transmissão de voz e imagem em equipamentos
de telecomunicação. O software é hoje uma tecnologia onipresente. Do telefone ao
despertador, da televisão ao supermercado, do brinquedo ao avião, do elevador à
internet, o software está presente, dando uma importante contribuição à produtividade
das empresas e à qualidade de vida das pessoas.
Pressman (1995) destaca a importância da Engenharia de Software afirmando, que 
as práticas de engenharia de software se intensificaram com o agravamento dos
problemas relativos ao software:
a) A sofisticação dos problemas ultrapassaram a nossa capacidade de construir
software que extraia o potencial oferecido pelo hardware,
b) Nossa capacidade de construir software de qualidadenão pode acompanhar a
demanda por novas aplicações da computação, e
c) Nossa capacidade de manter os software existentes foi ameaçada por projetos
ruins e recursos inadequados
Observa-se, nestas considerações, que a Engenharia de Software lida intimamente
com as limitações da capacidade humana em criar software. O crescimento do poder
dos microprocessadores torna mais aparente os limites da nossa capacidade de
conceber e criar software que aproveite todo esta potencialidade. As demandas
crescentes por parte dos usuários pressionam os desenvolvedores para uma luta contra
o tempo na busca por bons projetos de software, que possam ser construídos e mantidos
adequadamente. Os problemas atuais, a serem resolvidos pelo software, não apenas se
tornaram complexos, eles estão se modificando continuamente, e se integrando a outros
problemas, igualmente complexos, em uma rede global de computadores que é a
internet. A digitalização da informação, por exemplo, ajuda a criar novas demandas
por software, com a possibilidade da distribuição ampla da informação promovida
pela internet.
Aparentemente, a distância entre os desafios propostos para o software e as
linguagens de programação disponíveis para construí-los é intransponível. As
linguagens se mantém relativamente simples, com instruções elementares, criando
programas de computador longos, ambígos e sujeitos à muitas falhas. A principal razão
desta limitação é a própria arquitetura das máquinas de Von Neumann, base de todos
computadores e processadores comerciais existentes hoje (Eck, 1995). Este uso, quase
universal, da arquitetura de Von Neumann, como base para os computadores é o fator
mais importante para o projeto de linguagens de programação, e conseqüentemente, dos
métodos disponíveis para se criar software, como observa Sebesta (1996).
Para se aproximar o mundo dos problemas reais do universo virtual de um
computador é necessário que se selecione um paradigma único, no qual se possam
descrever os problemas reais, ao mesmo tempo, que possuam uma trqadução direta
para a linguagem do computador. A busca deste paradigma pode ser usada para retratar
o histórico das linguagens de programação desde a sua criação, e resulta no que hoje
são as linguagens de programação que se utilizam do paradigma de objetos, as
chamadas linguagens orientadas a objetos. Essencialmente, a programação orientada a
objetos busca a solução dos problemas de software pela identificação objetos do
mundo real, que são depois traduzidos em outros objetos de um modelo de software
(Sebesta, 1996). As linguagens orientadas a objeto como Java, Delphi, Visual Basic,
C++ e C# facilitam esta tradução por se utilizarem dos mesmos fundamentos do
paradigma de objetos que foram usados na modelagem. A disponibilidade e ampla
divulgação destas linguages são as grandes motivadoras para a evolução da análise e
do projeto de sistemas orientados a objeto, como tentativas para se transpor o abismo
entre as boas idéias e o software que as implementaria.
Este livro objetiva capacitar analistas, programadores e gerentes de projeto de
software na construção de um modelo orientado a objetos de um problema do mundo
real. A principal meta deste trabalho é organizar um conjunto coerente de técnicas de
análise e projeto de sistemas orientados a objetos, de modo que o modelo construído
por estas técnicas sirva de ponte para a construção do software.
1.2. Como este livro está organizado
Para cumprir os objetivos propostos para este livro, a construção de modelo de um
sistema de software foi dividida em 6 capítulos, um glossário de termos e um apêndice,
que são descritos a seguir:
Capítulo 1 – Introdução. Apresenta esta introdução aos objetivos do livro, a
organização proposta, como ele pode ser lido, o seu público alvo e destaca a
importância da modelagem para o desenvolvimento de software.
Capítulo 2 - Fundamentos da Modelagem Orientada a Objetos. Apresenta os
conceitos fundamentais da orientação a objetos e a sua relação com o processo de
desenvolvimento de software. As características que diferem a abordagem de objetos
das outras abordagens são aqui descritas com detalhe. Os conceitos de encapsulamento,
herança, mensagens e polimorfismo são definidos e exemplificados por uma aplicação
simples de automação comercial. É um capítulo de leitura obrigatória para quem deseja
revisar os conceitos da tecnologia de objetos e conhecer a nomenclatura utilizada no
restante do livro. Aos leitores que já possuem estes conceitos, a leitura deste capítulo
pode ser dispensada.
Capítulo 3 - O Modelo de Contexto. Apresenta o primeiro modelo a ser
desenvolvido para uma abordagem inicial de um problema de software. O modelo de
contexto é um modelo alto nível baseado na análise funcional, que visa definir a
fronteira do sistema e os seus objetivos principais. Neste modelo são utilizados os
diagramas de casos de uso propostos por Jacobson (1992) e adotados porteriormente
pela UML (Jacobson, 1998). A fronteira isola o sistema de software dos componentes
externos ao software, mas que interagem com ele. Este capítulo é especialmente
importante para os leitores envolvidos nas definições iniciais de um sistema
computacional, que devem, em contato direto com os clientes do software, especificar
os requisitos do sistema.
Capítulo 4 - O Modelo Conceitual apresentado é baseado nos cartões CRC.
 Descreve a técnica dos cartões CRC aplicada na definição inicial de um sistema
orientado a objetos. Esta técnica utiliza cartões comuns de arquivo para representar os
objetos, e ajudam na distribuição das funcionalidades esperadas entre os objetos do
modelo. Este capítulo é recomendado para os leitores envolvidos na concepção de
sistemas, com experiência ou não em sistemas não orientados a objetos e que devem
passar a "pensar" em objetos. Não é um capítulo essencial para quem já posssui os
conceitos de objetos bem consolidados. Mesmo neste caso este leitores podem se
servir da técnica dos cartões CRC como um método que permite envolver os clientes e
usuários no levantamento de requsitos de projeto e no processo de concepção do
software.
Capítulo 5 - O Modelo de Detalhado de Objetos. Descreve, finalmente, os
diagramas do modelo orientado a objetos na notação proposta pela UML: diagrama de
classes, estados, seqüência, atividades, colaboração, componentes e distribuição. Cada
diagrama é descrito em conjunto com seus elementos componentes e aplicado em
diversos exemplos, que permitem ao leitor visualizar as diversas alternativas da sua
aplicação na modelagem de sistemas. É um capítulo essencial para a compreensão da
notação e dos detalhes construtivos dos diversos diagramas que compõem os modelos
orientados a objeto.
Capítulo 6 – Estudo de Casos. Aplica os modelos apresentados nos capítulos 3, 4
e 5 em três estudos de caso. Inicialmente o estudo de caso da aplicação comercial do
capítulo 2 é revisado, assim como o exemplo do jogo da forca utilizado no capítulo 4, e
o exemplo de estoque do capítulo 5. Desenvolvido com uma visão didática, ele permite
ao leitor compreender a integração que existe entre os modelos e diagramas. O leitor
pode, se desejar, iniciar a leitura do livro por este capítulo tendo uma abordagem
inicial mais prática, para dai se aprofundar nos assuntos de maior interesse nos
capítulos anteriores.
Um Glossário finaliza o trabalho listando os principais termos utilizados na
modelagem orientada a objetos. Como alguns destes termos pode ter um significado
diferente fora do contexto da modelagem, o glossário deve ser consultado sempre que
surgir dúvida em algum termo durante a leitura do texto.
O Apêndice mostra o resultador da tradução dos modelos da UML em códigos Java,
transformando os exemplos em aplicações completas. Lá encontram-se os códigos dos
programas e o endereço do website para executá-los. Todos os exemplos usados ao
longo do texo estão disponíveis para acesso pela internet.
São várias as possibilidades de leitura do texto do livro, e elas estão
esquematizadas na figura abaixo, partindo dointeresse do leitor por uma visão teórica,
uma visão prática ou por um interesse específico por algum tema:
Figura 2 - Encadeamento possível para leitura dos capítulos
Pode-se iniciar a leitura pelo Capítulo 2 para os que desejam consolidar os
fundamentos da orientação a objetos. No entanto, se os leitores já são familiares a estes
conceitos, podem utilizar este capítulo para familiarizarem-se com a nomenclatura
utilizada no restante do texto. Os capítulos 3, 4 e 5 são relativamente independentes
por se tratarem de 3 modelos que diferem em escala e objetivo. Podem, por isso, ter
uma leitura independente, mas que em conjunto apresentam as possibildades de
modelagem que a orientação a objetos nos oferece. A leitura seqüencial destes três
capítulos favorece o entendimento da evolução dos modelos que ocorre, naturalmente,
durante o desenvolvimento de um sistema de software. Entretando, se o objetivo do
leitor é apenas criar uma especificação de alto nível do sistema pode interromper a sua
leitura no capítulo 3. Se além do modelo de especificação deseja um aprofundamento
dos conceitos do sistema em um modelo conceitual preliminar, ou se estiver
diretamente envolvido na análise do sistema, deve continuar sua leitura pelo capítulo 4.
O capítulo 5 se destina aos leitores que desejam compreender os detalhes de um
modelo orientado a objetos criado com a notação da UML, provavelmente por estarem
envolvidos nas etapas de design e construção de software. Uma alternativa possível
para o leitor que desejar uma visão rápida das técnicas de modelagem apresentadas
aqui é ir diretamente para o capítulo 6 e utilizar-se das referências citadas neste
capítulo para um aprofundamento nos itens de maior interesse nos capítulos anteriores.
Se no decorrer da leitura houver dúvida sobre algum termo técnico empregado, o leitor
pode procurar uma explicação no glossário de termos.
Com esta organização é possível cobrir várias possibilidades de abordagem da
orientação a objetos, desde uma abordagem mais formal, até uma abordagem mais
prática e informal. Com um grande número de exemplos, procura-se sempre apresentar
as aplicações típicas dos conceitos apresentados. O leitor deve, entretanto, manter-se
atento à limitação dos exemplos propostos e imaginar como utilizar estes conceitos em
seus próprios problemas e aplicações.
1.3. A importância da modelagem
É fácil observar que outras áreas do conhecimento, as outras disciplinas de
engenharia, usam extensivamente da modelagem para representar seus projetos. A
figura clássica de um engenheiro civil é alguém envolvido com plantas e diagramas,
gerenciando uma construção. Uma planta de uma obra civil é uma representação gráfica
do produto final, o edifício. A planta permite que o cliente avalie o produto e garanta
que o resultado final é muito próximo do que ele deseja. A capacidade de
gerenciamento da indústria da construção civil, permite uma razoável precisão na data
de entrega das obras graças à padronização de processos de construção e a uma intensa
padronização de componentes. Com exceção talvez apenas da alvenaria, uma
edificação é composta de partes já construídas e que são integradas para formar o
produto final. Estas partes pré-fabricadas são os objetos da construção civil.
A engenharia mecânica, na indústria automobilística por exemplo, é uma indústria
com um alto nível de automação, padronização e especialização. Um carro é fruto de
um projeto básico que define os requisitos para os projetos de cada peça. Ele
movimenta uma grande mercado para as indústrias de auto-peças que criam,
isoladamente, os objetos individuais do carro. A construção do carro é uma montagem,
uma integração de objetos.
A engenharia de software procura trazer para a ciência da computação estas lições,
e incentivar a elaboração de um projeto de software, em um modelo orientado a
objetos. Visando a padronização de componentes de software, o projeto e o processo
de desenvolvimento são desenvolvidos segundo a orientação de se criar objetos.
Projetar software nada mais é do que construir um modelo do software. Um modelo
que representa, simplificadamente, o que se pretende construir, como uma planta de
uma residência. Um modelo que mostra não só os requisitos do problema mas também
como eles serão atendidos pelos elementos da solução. Um modelo que permita avaliar
a qualidade da solução e simular o resultado final, de modo que projetista, cliente,
construtor tenham todos uma mesma visão do projeto.
O processso de desenvolvimento de software é um processo composto não apenas
de componentes tecnológicos. Uma componente importante, e decisiva para o sucesso
de um empreendimento, é a componente social. A componente tecnológica nos projetos
de software se encontra, principalmente, nas atividades de contrução do software. A
componente social está ligada ao relacionamento entre o usuário e o desenvolvedor, e
uma parcela importante da interação do usuário com o software. Pfleeger (1999) afirma
que o sucesso do software depende mais até do sucesso das interações sociais do que
da aplicação da tecnologia. Não se deve esquecer que software é desenvolvido por
pessoas para ser utilizado por outras pessoas. A interação do software é uma interação
entre pessoas, mediada pela tecnologia.
A qualidade de um software pode ser avaliada pela satisfação do cliente. O cliente
que se serve do software cria, ao estabelecer os requisitos de um software, uma
expectativa que só verá realizada quando o software estiver concluído. Ao
desenvolvedor cabe captar e atender estas expectativas com as possibilidades de
realização. Para isso cliente deve contar, desde o início com um modelo do software.
Este trabalho objetiva auxiliar os desenvolvedores na criação de modelos
orientados a objetos dos sistemas de software. A principal proposta é valorizar a
atividade de criação do modelo para reduzir a incerteza do software, aproximar a
expectativa da realização, facilitar a padronização e a automação dos projetos,
incentivar a reutilização dos componentes de software e aumentar a maturidade da
engenharia de software nas equipes de projeto.
 
 
 
 
 
 
 
2. Fundamentos da Modelagem
Orientada a Objetos
 
Este capítulo descreve os conceitos fundamentais da modelagem orientada a
objetos por intermédio de um exemplo de aplicação. O exemplo mostra a herança, o
encapsulamento e a troca de mensagens entre os objetos sob um ponto de vista
prático. Apresenta ainda as características principais do processo de
desenvolvimento de software, os fluxos de trabalho e a importância da modelagem de
objetos presentes neste processo.
2.1. Processo de Desenvolvimento de Software
O desenvolvimento de um software depende de muito trabalho disciplinado. Ter
uma boa idéia para um software só não basta, ela deve vir acompanhada da organização
e da disposição necessárias para realizar o trabalho de transformá-la em um produto.
Um sistema de software é resultado da união da criatividade , da tecnologia e do
trabalho organizado. Um não funciona bem sem os demais. A tecnologia sozinha não
resolve os problemas, o esforço solitário fica isolado se não for criativo. O que une a
tecnologia com a criatividade e direciona o trabalho é uma idéia comum, uma visão,
representada em um modelo. Estudando-se as etapas para transformar uma idéia em um
produto de software, verifica-se a importância em criar um modelo.
Os métodos para desenvolvimento de software descrevem a organização
necessária para se criar um software. Métodos sugerem passos a serem seguidos para
cumprir o vazio existente entre a idéia e o produto de software. Este estudo não
pretende desenvolver um novo método, nem tão pouco indicar um determinado método
como sendo o mais adequado. Pretende sim destacar algumas propriedades presentes
em todos os métodos, e observar que as técnicas de modelagem estão no centro dos
métodos, e dão a sustentação necessária para a edificação do software.
Os métodos são organizados em fases, que caracterizam as etapas de evolução pelas
quaiso software deve passar. Em cada fase uma série de atividades são realizadas,
produzindo documentos, esquemas e diagramas que finalizam no código do programa de
computador. Sobre cada um destes subprodutos do método de desenvolvimento podem
ser realizados testes, para garantir que se está evoluindo na direção prevista, e com a
qualidade esperada.
Ao avaliar as etapas de um projeto de software, observa-se que elas não são muito
diferentes das etapas de qualquer outro projeto típico de engenharia. Como todo projeto
de engenharia, o projeto de software tem como principal objetivo resolver um
problema. A solução do problema irá trazer benefícios para os usuários do produto do
projeto, no caso, o software. A solução do problema, no caso da engenharia de
software, é o próprio sistema de software.
Identificar os objetivos e reconhecer os requisitos do problema são as atividades
realizadas na fase de análise. Os requisitos variam de caso para caso, e dependem de
um bom entendimento da área de conhecimento na qual será desenvolvida o projeto, das
condições iniciais e das necessidades dos clientes. Pode-se dizer que a análise serve
para se formular o problema que o sistema irá resolver. Conhecidos os requisitos e as
necessidades do cliente pode-se elaborar uma estratégia para resolver o problema, ou
fazer, o que se chama aqui, do design da solução. Na fase de design são tomadas todas
as decisões que envolvem a solução do problema, e a partir dele inicia-se a
construção dos componentes da solução. Este componentes podem ser novos ou
reutilizados de outros projetos, já testados e aprovados. Com os componentes da
solução disponíveis realiza-se a integração que coloca todas as partes juntas para se 
obter o produto final. É interessante notar que esta descrição aplica-se igualmente à
construção de umar edificação, um projeto de instalação elétrica ou um projeto
mecânico qualquer. Esta coincidência sugere uma grande semelhança na organização
das atividades de engenharia seja qual for a disciplina.
Um elemento importante e presente em todos os projetos de engenharia são as
plantas de engenharia. Todo projeto de engenharia é realizado sobre uma planta, que é
uma representação gráfica minuciosa do que se pretende construir. Sobre a planta são
avaliadas possíveis alternativas de solução, tomadas as decisões de projeto e a partir
dela são obtidas as orientações para a construção do produto. A planta é,
essencialmente, um elemento de comunicação entre os participantes do projeto. A
planta representa o projeto de uma forma simplificada, é um modelo do sistema final.
Os modelos são contruídos para ajudar a entender um problema e para comunicar
este entendimento a outros. A simplicidade, própria dos modelos, permite apenas que
ele represente as informações importantes, deixando de lado detalhes que dificultem a
compreensão do problema. Entendido o problema, o analista pode utilizar o modelo
para comunicar ao cliente o que entendeu e como pretende resolvê-lo. O projetista
comunica, por um modelo, como deverão ser construídos os componentes e como estes
serão integrados na solução. Terminado o projeto, o modelo ainda ajuda a comunicar
aos responsáveis pela operação e manutenção do sistema, os cuidados que devem ser
tomados ao se realizar uma modificação ou um reparo no sistema. Como é uma
poderosa ferramenta de comunicação o modelo deve ser representado em uma
linguagem ao mesmo tempo precisa e clara, que comunique sem gerar dúvidas de
interpretação. Este é talvez o maior desafio da modelagem, e a principal razão deste
trabalho: como criar um modelo de software claro, preciso e ao mesmo tempo simples.
Outra propriedade importante dos modelos é a de poder acompanhar a evolução do
projeto. No início, é comum os modelos serem apenas linhas gerais e esboços. Em
alguns casos, nem os limites do problema estão ainda em definidos. Com um
entendimento melhor do problema, o modelo passa a agregar mais informação e a se
tornar-se uma visão mais completa de onde se pretende chegar. Um simples esboço
pode dar lugar a um diagrama mais preciso, a partir do qual várias decisões de projeto
podem ser tomadas. Concluída a etapa de design, o modelo contém todas as
informações necessárias para se iniciar a construção da solução, o modelo está agora
bastante detalhado e preciso. Finalmente, com o produto construído e em operação é
importante manter-se o modelo atualizado e vivo, refletindo nele as eventuais
alterações feitas no produto quando ele sofre uma manutenção, ou são realizadas
expansões.
O modelo é uma parte importante do projeto e deve evoluir com ele. Assim é
possível resumir as qualidades desejáveis de um modelo como sendo a clareza, a
precisão, a simplicidade e a facilidade de evolução. A figura mostra um esquema das
atividades em um projeto de desenvolvimento de software qualquer, e a correspondente
evolução do modelo deste sistema.
Figura 3 - Esquema de um projeto de software
Com base neste esquema analisa-se a evolução do modelo no projeto de sistemas,
as atividades realizadas para obtê-los e os principais personagens envolvidos nestas
atividades. Estuda-se, inicialmente, os dois principais fluxos de atividades
representados neste esquema: o ciclo de desenvolvimento, representado pelas
atividades do lado do desenvolvedor, e o ciclo de teste do produto, representado pela
seta vertical à esquerda, do lado do cliente.
2.1.1. Ciclo de teste do software
O ciclo de teste do software é um processo de responsabilidade do cliente, ou do
seu representante. Visa garantir que as necessidades levantadas para a definição dos
problemas estejam sendo atendidas pelo produto. No ciclo de teste o cliente verifica se
o produto fornecido pelo ciclo de desenvolvimento está de acordo com os requisitos de
projeto, e para isso ele realiza testes sobre o produto. Testes que colocam o produto em
situações de uso normal, e procuram detectar falhas e novos requisitos não
identificados ainda. Como um sub-produto dos testes surgem correções e novas
necessidades, que devem ser incorporadas aos requisitos de uma nova versão deste
produto, dando início a um novo ciclo de desenvolvimento.
Os clientes são todos os que contratam o serviço de desenvolvimento do software,
porque estão interessados pelo resultado que o software irá dar ao seu negócio. Os
clientes podem ser os usuários finais, que irão usar o software, podem ser seus gerentes
que devem garantir a qualidade e a funcionalidade do software ou patrocinadores do
software que irão incentivar o desenvolvimento e arcar com seus custos
Gerente da aplicação é o responsável pela operação do sistema no ambiente do
usuário. Durante o desenvolvimento do projeto o gerente é o lider dos usuários e
atua como facilitador dos relacionamento entre eles e a equipe de
desenvolvedores. Uma vez desenvolvido o sistema de software o gerente da
aplicação passa a responder por ele internamente à organização.
Usuário final é quem se utilizará do sistema para auxiliá-lo em suas atividades.
Em problemas complexos os usuários podem variar de departamento, função,
hierarquia na organização. Nestes casos é importante se criar um comissão de
usuários, representativa da comunidade, para orientar o desenvolvimento do
sistema.
Patrocinadores fazem parte do grupo de clientes que dão apoio financeiro,
técnico ou político ao desenvolvimento do sistema. Este apoio é vital para que os
desenvolvedores possam ter acesso às informações e possam executar, se
necessário, as alterações na organização para a implantação do sistema.
2.1.2. Ciclo de desenvolvimento do software
O ciclo de desenvolvimento do sistema é um fluxo de trabalho cíclico que gera
novos produtos a partir das informações obtidas no levantamento de necessidades do
problema. É dades cíclico porque o produto de saída alimenta o ciclo seguinte, de
modo que a cada volta aproxima-se o produto das necessidades levantadas. Espera-se
que o ciclo seja convergente, isto é, em um determinado estágio o produto atenderá
todos os requisitose poderá ser considerado terminado. Este ciclo é realizado
inteiramento no lado do desenvolvedor, mas possui interações com o lado cliente, no
ciclo de testes do produto.
O ciclo de desenvolvimento de um sistema é caracterizado por 4 atividades
principais: análise, design, construção de componentes e integração. A seguir verifica-
se o papel do modelos nas fases e os papel dos participantes de cada uma delas.
Fase de Análise
A análise é a fase de levantamento dos requisitos do problema a ser resolvido. Nela
estabelecem-se os limites do problema, e identificam-se as necessidades do sistema.
Deve-se procurar limitar a análise exclusivamente ao problema em estudo, evitando a
influência de elementos que estão fora do escopo do problema. Detalhes de
implementação que podem ofuscar a definição do problema, falsos requisitos,
limitações inexistentes devem ser deixadas de lado. Para ajudar o analista na busca de
uma maior clareza nas definições inciais, ele deve criar um modelo do problema. Este
modelo deverá ter apenas as informações relevantes para o entendimento do problema e
deverá receber a aprovação por parte do cliente, garantindo que o caminho está correto
e servindo de base para as demais fases do projeto.
As técnicas aplicáveis à análise são muitas, e dependem, grandemente, da
experiência do analista. Quanto mais complexo o problema, mais difícil é a análise e
mais importante o uso de modelos para reduzir e gerenciar esta complexidade. Todas as
informações obtidas do cliente devem ser avaliadas e levadas em consideração na
análise. Não existe um momento preciso que indica o final da análise, mas o analista
pode identificar este momento quanto todas as facetas do problema foram exploradas e
a visão que o modelo traduz é suficiente para iniciar as fases seguintes do projeto.
Mesmo que alguns requisitos foram esquecidos, não é motivo de preocupação, como o
processo de desenvolvimento é cíclico sempre será possível rever a análise e incluir
estes novos requisitos.
A análise é tarefa do analista de sistemas. Em projetos mais simples esta atividade
pode ser desempenhada por um desenvolvedor sênior, ou pelo próprio gerente de
projeto, se estes possuirem um conhecimento básico de modelagem de sistemas, e a
disponibilidade para entrevistar usuários, levantar e organizar as informações
disponíveis para o início do projeto. Em projetos mais complexos esta tarefa pode ser
dividida entre diversos profissionais como o Analista de Negócios, o Analista de
Documentação e o Analista de Banco de Dados.
Analista de Negócios - deve ser um especialista na área de conhecimento a que o
sistema se destina, e tem como objetivo identificar as responsabilidades que o
sistema deve cumprir para o negócio do cliente. O analista de negócios pode
desenvolver uma análise do retorno esperado com o invetimento no sistema, e
estudar a viabilidade técnica do sistema, integrando-o ao ambiente computacional
existente. Os requisitos de negócio, as regras e os processos de negócios devem
ser modelados por este profissional.
Analista de Banco de Dados - como uma grande parte dos sistemas de informação
são baseados na tecnologia de banco de dados, é importante ter um entendimento
preciso das informações já existentes em bancos de dados, antes de iniciar um
novo projeto. O analista pode se utilizar de técnicas próprias e ferramentas de
software para criar os esquemas dos bancos de dados existentes e que serão úteis
para o novo projeto de sistema.
Analista de Documentação - é o responsável por elaborar a documentação do
sistema, os documentos de especificação, manuais e diagramas. Como a fase de
análise é uma fase onde a geração de documentos é maior, é importante ter-se um
profissional técnico especializado encarregado da produção desta documentação.
Uma prática interessante pode ser a de produzir o manual do usuário do sistema já
na fase de análise, e utilizá-lo com parte da especificação técnica de requisitos do
sistema.
Como parte importante da fase de análise temos um modelo inicial do sistema que
fará parte do documento de especificação, produto da fase de análise. Porque as
correções nas fases iniciais de um projeto são sempre mais fáceis de serem feitas, do
que em fases mais avançadas, os documentos e os modelos desta fase devem ser,
continuamente, avaliados e verificados pelos clientes.
Fase de Design
O design se concentra na solução do problema identificado na fase de análise.
Busca incorporar aos modelos, os elementos que formam um sistema para resolver o
problema de projeto. Como quase sempre a seleção de uma estratégia de solução traz
compromissos com outros sistemas, deve-se, nesta fase, avaliar o melhor caminho,
testar e escolher a alternativa de solução mais adequada. O designer conta com a sua
experiência e o apoio de modelos do sistema em projeto para apoiar sua decisão.
O design é uma tarefa para engenheiros de software experientes. Em um projeto
mais complexo, diversos aspectos de um sistema de software devem ser considerados,
o que exige a participação de outros especialistas, como o Engenheiro de Redes e o
Designer de Interfaces.
Engenheiro de Software - é o especialista em criar o operar os modelos dos
sistemas para levá-los ao código. Deve possuir habilidade de conceber os
componentes do sistema e caracterizá-los de modo a que atendam os requisitos do
problema. Pode testar soluções e se utilizar de padrões de soluções já consagradas
e aplicá-las a novos problemas. O engenheiro de software deve garantir também
que as boas práticas de engenharia sejam respeitadas no projeto, assegurando a
qualidade do produto.
 Engenheiro de Redes - é um especialista importante quando o sistema será
implementado em um ambiente de processamento distribuído. Neste caso, a
comunicação entre os componentes do sistema será feita pela rede de comunicação
de dados, que deve ser projetada para dar vazão ao volume de comunicação
esperado. Existindo uma grande interação entre os componentes da solução pode
exigir, em alguns casos, que componentes especiais de comunicação sejam
especificados e construídos.
Designer de Interfaces - é um especialista na comunicação entre os usuários e o
computador. É um profissional muito importante em sistemas com grande interação
com os usuários como os sistemas para internet. O aumento do número de
usuários nos sistemas de informação tem feito com que este profissional tenha um
papel cada vez mais importante para a aceitação e para a usabilidade do sistema.
Ele deve possuir a habilidade de e a criatividade para criar metáforas para a
operação do sistema.
Ao final da fase de design todas as definições do projeto devem estar registradas no
documento de especificação. Modelos, listas e esquemas servem como referências para
os construtores dos componentes e para a integração do sistema. O modelo produzido
pelo design pode variar muito no nível dos seus detalhes. No início do projeto
apresenta poucos detalhes mostrando conceitualmente a solução, para uma avaliação
inicial, ou para a validação de um cliente. Nos ciclos mais avançados do projeto, o
modelo deve estar muito bem detalhado para determinar aos programadores todos os
pormenores do software.
Fase de Construção doms Componentes
Na fase de construção de componentes inicia-se as atividades de programação na
construção do software. A boa prática de construção recomenda a adoção do conceito
de componentes de software reutilizáveis para reduzir prazos e custos no
desenvolvimento, mantendo a qualidadade do produto. É cada vez mais comum se
dispor de componentes pré-fabricados prontos para serem utilizados em diversos
projetos, organizados em um framework. Nestes casos a construção de componentes se
limitará a criar os componentes que são específicos para o novo projeto.
A construção civil é um exemplo típico de padronização de peças pré-fabricadas.
Poucas são as partes criadas específicamente para uma construção. Na área mecânica o
exemplo mais interessante de criação de componentes encontra-se na indústria
automobilística, onde um carroé efetivamente a montagem de peças e partes completas
feitas por outras empresas,. Muitas vezes a mesma peça é utilizada em diferentes
carros. Esta abordagem ainda é nova na engenharia de software, mas está, aos poucos,
revolucionando o desenvolvimento de software.
A construção dos componentes é um trabalho para o programador de 
computadores, que é o especialista nas linguagens de programação. Um mesmo sistema
pode possuir compontentes escritos em diferentes linguagens, no entanto, para facilitar
a manutenção e simplificar o sistema quanto menor o número de linguagens mais
facilmente o sistema será mantido. O programador segue princípios e práticas próprias,
que não farão parte deste trabalho. Como uma grande parte dos sistema atuais se utiliza
de um banco de dados para armazenar as informações e possui uma grande dose de
interação com os usuários, é importante também envolver na fase da construção outros
especialistas: o programador de banco de dados, o programador de componentes e o
programador de interfaces.
Programador de interfaces é o profissional responsável por desenvolver os
componentes de interação entre o sistema e os seus usuários. Os componentes de
interface devem se caracterizar pela facilidade de uso e pela precisão na
comunicação. O uso de uma interface gráfica e regras próprias para criar estes
componentes, projetador por um designer, exigem que um programador
especializado nesta tarefa seja convocado para realizá-la.
Programador de Componentes escreve os componentes de negócio obedecendo
as regras de negócio definidas pelo Analista de Negócios e projetadas pelo
Engenheiro de Software. Sua principal tarefa é garantir a qualidade do
componente, sua eficáfica e robustez. Utiliza, em geral, uma linguagem robusta em
um ambiente de desenvolvimento próprio.
 Programador de Banco de Dados é um profissional importante na fase de
construção se houver necessidade de criar componentes específicos para o
armazenamento e recuperação de informação. Em sistema orientados a objeto o
uso do banco de dados é limitado e organizado pelos objetos, sendo que este
profissional deve ser responsável por integrar os sistemas orientados a objeto com
os sistema legados em bancos de dados.
Analista de Teste. Como o produto final da fase de construção são os próprios
componentes. Cada componente próprio ou adquirido de ter terceiros deve ser
testado individualmente, para garantir que ele esteja de acordo com a
especificação do projeto. Este teste faz parte do processo de criação de
componentes mas não deve ser desprezado. Pode-se criar, em projetos maiores,
uma função específica com esta responsabilidade, garantindo a sua qualidade e
funcionalidade. O analista de testes não pode ter uma função acumulada com a
função de programador, para evitar um conflito de interesses.
Fase de Integração
A fase de integração encerra o processo de desenvolvimento gerando, como
produto final, uma nova versão do software. Nesta fase, a atividade mais importante é a
de configuração da versão do software, compilando e instalando os componentes
necessários nos equipamentos servidores. É uma fase de trabalho minucioso e
organizado, onde se deve assegurar que todos os componentes necessários foram
integrados. Após este integração é importante realizar uma fase de teste. É comum nesta
fase se criar roteiros automatizados de teste, assim como pode ser necessária alguma
atividade de programação para integração final dos componentes.
As atividades de integração podem, em sistemas mais simples, ser realizadas pelo
Engenheiro de Software ou pelo próprio Gerente de Projetos. Em sistemas mais
complexos é comum encontrarmos o Gerente de integração ou Gerente de
Configuração que irá coordenar uma equipe de profissionais, os Integradores que
responderão pela união correta dos componentes.
Os modelos, na fase de integração, servem de mapa para a configuração do sistema,
e união dos componentes. Em muitos casos, não se está interessado em criar um sistema
totalmente novo, mas sim em adaptar um sistema existente para as necessidades
específicas de um cliente. Chama-se ao processo de adaptar um software especialmente
para as necessidades de um cliente de customização[1]. O processo de customização
passa por todas as fases do processo de desenvolvimento, mas tem uma ênfase maior na
fase de integração, onde são realizadas a maior parte das atividades de configuração do
software.
2.2. Modelos de um Software
O processo de desenvolvimento de um software apresentado é baseado na evolução
de uma visão que os desenvolvedores controem, em conjunto com os clientes, sobre o
problema a ser resolvido. Esta visão é concretizada em modelos, que devem
representar esta visão e evoluir com ela. No início, a visão é incompleta e pode possuir
ambiqüidades e distorções, que ao longo do processo de desenvolvimento, com o
entendimento do problema, são eliminadas. No final, o modelo resultante é equivalente
em significado ao código gerado para implementar a solução do problema, eles devem
ter igual riqueza de detalhes e precisão.
Em um problema complexo, dificilmente uma visão única, completa e bem definida
será obtida logo no início do processo. É importante que os compromissos do software
representados no modelo sejam assumidos aos poucos, acompanhando o entendimento
que se tem do problema. As técnicas de modelagem, que serão exploradas em detalhes
nos próximos capítulos, ajudam os analistas e designers a documentar e comunicar o
entendimento que adquirem do problema em diagramas de forma precisa, evitando a
construção de sistemas de software inconsistentes.
Um único modelo apenas é insuficiente para representar todos os fenômenos
existentes em um sistema complexo, são necessários um conjunto coerente de modelos
com diferentes escalas, criados a partir de diferentes pontos de vista. Jacobson (1992)
propõe que a complexidade seja introduzida gradualmente no modelo do sistema, com a
ajuda de uma série de sucessivos modelos que aos poucos são capazes de gerenciar
essa complexidade. Ele propõe 5 tipos diferentes de modelos:
modelo de requisitos, que captura requisitos funcionais do sistema,
modelo de análise, que dá ao sistema uma estrutura de objetos,
modelo de design, que refina esta estrutura para a implementação,
modelo de implementação, que efetivamente implementa o sistema,
modelo de teste que verifica o sistema.
Este estudo utiliza apenas três modelos para representar os sistema de software:
modelo de contexto,
modelo conceitual e
modelo detalhado.
A idéia central aqui também é introduzir a complexidade aos poucos. O modelo de
contexto equivale ao modelo de requisitos de Jacobson, enquanto o modelo
conceitual se equivale ao modelo de análise de Jacobson. O modelo detalhado pode ser
aplicado ao design, à implementação ou ao teste do sistema, dependendo do nível de
detalhes e da finalidade a que ele se destina; assim, substitui os 3 outros modelos
propostos por Jacobson.
O modelo de contexto inicia a definição do problema. É construído em uma
escala grande, onde grande parte dos detalhes do problema estão encobertos.
Representa os aspectos funcionais de alto nível do sistema, analogamente ao modelo de
requisitos de Jacobson (1992). Serve para representar o sistema proposto no contexto
do negócio do cliente. Deve possuir uma representação simples, sem uma
formalidade excessiva, para poder ser entendido e validado pelo cliente, que
normalmente é leigo em assuntos de software. No modelo de contexto define-se a
fronteira do problema e os principais objetivos que o sistema deve cumprir para os
seus usuários. Este modelo é, essencialmente, desenvolvido durante a fase de
análise pois refere-se, principalmente, à uma visão do problema a ser resolvido. Deve
ser possível ao modelo de contexto situar o sistema no contexto do cliente,
identificando pontos de integração com outros sistemas já existentes e caracterizar a
contribuição do novo sistema.
O modelo conceitual é um modelo que reúne todos os conceitos presentes no
problema em estudo. Construídocom uma escala menor do que o modelo de contexto,
cria a estrutura do sistema, usando para isso um modelo simplificado de classes. Nele
devem estar representadas os principais componentes do sistema e suas relações. No
modelo conceitual está caracterizada as proposta de solução do problema, mas sem o
detalhe necessário para a sua implementação. A idéia central é representar,
simplificadamente, em poucos diagramas, o sistema como um todo e as partes
principais que o constituem. Como o modelo final do sistema pode ser muito complexo,
o modelo conceitual serve de índice, de orientação, para que dele sejam detalhados os
modelos de implementação. É um modelo desenvolvido nas fases de análise e design
porque recebe não só os detalhes do problema a ser resolvido, como também os
elementos incorporados ao modelo durante o design da solução.
A quantidade de detalhes do modelo conceitual deve estar entre a abstração do
modelo de contexto e a grande quantidade de detalhes do modelo detalhado. Como o
modelo conceitual possui um nível maior de detalhamento que o modelo de contexto, é
possível, a partir dele estabelecer um planejamento do desenvolvimento e um
dimensionamento mais preciso dos recursos necessários para a construção do sistema.
Estas definições são impossíveis de serem feitas apenas com o modelo contextual,
assim o modelo conceitual assume também um importante papel no gerenciamento do
processo de desenvolvimento de software. 
O modelo detalhado, por sua vez, incorpora todos os detalhes de uma versão
projetada do software. O modelo detalhado pode possuir um nível de detalhe
equivalente ao código do software, podendo-se até criar uma correspondência
biunívoca com ele. Para cada versão de um software o modelo detalhado pode mudar,
incorporando as novidades desta versão. Podem ser gerados quandos modelos
detalhados quantas versões do produto existirem. O objetivo principal do modelo
detalhado é a construção do sistema, assim nele devem estar representados todos os
detalhes construtivos e as definições de projeto. É um modelo que se inicia na fase de
design, com os detalhes com componentes a serem construídos e é detalhado na fase de
construção. Como o modelo detalhado possui uma escala ainda menor que o modelo
conceitual, os detalhes do sistemas são revelados com precisão, na medida da
necessidade do desenvolvimento, seja para uma maior definição precisa do design, seja
para implementação ou seja para testes.
A figura abaixo mostra, de forma esquemática, as relações entre a escala proposta
de modelos e os produtos de software em suas diversas versões. 
Figura 4 - Seqüência de Modelos em um Projeto de Software Típico
2.3. Documento de Especificação de Projeto
O principal documento do desenvolvimento do software é o Documento de 
Especificação de Projeto. Como seu próprio nome diz, ele deve descreve,
detalhadamente, o projeto de um software. Normalmente, a especificação é tomada
como um documento feito para orientar a construção do software, mas neste estudo a
especificação é tomada como um espelho do projeto do sistema, e assim deve ser
mantida atualizada durante toda a evolução do sistema, inclusive após a sua construção.
Na fase de análise a especificação deve considerar os objetivos do problema, 
apresentando os modelos de contexto e conceitual. Na fase de design a especificação
recebe os detalhes das soluções escolhidas, para que na construção todas as alterações
no sistema possam ser representadas em modelos detalhados na especificação.
Mantém-se assim o documento vivo, acompanhando todo o projeto do sistema.
Como este trabalho não se propõe a apresentar um método para desenvolvimento de
um software, o documento de especificação não será detalhado. Entretanto, é de
esperar, encontrar muitos diagramas e modelos em um documento de especificação de
software.
2.4. A Modelagem Orientada a Objetos
Para criar um modelo é preciso escolher o que é considerado importante, e por isso
será representado no modelo, do que pode ser omitido. A seleção do que é, e do que
não é, importante segue um paradigma, um ponto de vista, uma forma de olhar a
realidade que se vai modelar. Descreve-se aqui algumas características dos diferentes
paradigmas usados para modelar sistemas de software.
Para desenvolver um sistema de software é necessário criar uma visão do problema,
representada em um modelo que orienta o processo de desenvolvimento. Para se
estabelecer esta visão deve-se definir um ponto de vista, isto é, deve-se a olhar o
software segundo um paradigma. O paradigma define uma unidade de decomposição do
sistema, destacando alguns aspectos em prejuízo de outros. Algumas possíveis visões e
as unidades de decomposição associadas são:
A Visão Funcional decompõe um sistema em funções;
A Visão dos Dados decompõe um sistema em estruturas de dados; e
A Visão de Objetos decompõe um sistema em classes de objetos.
A visão funcional valoriza o fluxo de informação do sistema, buscando responder o
que o sistema deve fazer. A idéia, que se traduz em uma análise funcional, é a de definir
o sistema como uma grande função, que pode ser quebrada em funções menores, em
uma técnica de análise chamada de análise top-down (de cima para baixo). Este
procedimento parte do princípio que um sistema de software deve fazer algo para o seu
usuário. Uma função complexa pode ser decomposta em funções mais simples,
continuamente, até que a quebra funcional leva a funções tão simples a ponto de
poderem ser implementadas e testadas. Testadas isoladamente, as funções elementares
são agrupadas e integradas em uma estratégia de integração botton-up (de baixo para
cima). Integrando todas as funcionalidades tem-se, ao final, o sistema completo com
toda a funcionalidade pretendida.
O termo “função” é quem orienta todo o processo de desenvolvimento. O que o
sistema deve fazer conduz o processo de análise e construção. Por isso, se for
necessário introduzir alterações, modificações e novas funcionalidades nos softwares
desenvolvidos sobre este paradigma a tarefa mais difícil. Ao se introduzir uma
alterção, uma série de outras funcionalidades que decorreram desta podem ser afetada.
A quantidade de código envolvido pode ser muito grande, inviabilizando grandes
mudanças em sistemas desenvolvidos sob uma visão exclusivamente funcional.
Figura 5 - Esquema da Modelagem Funcional
Na modelagem de dados, outro paradigma possível no desenvolvimento de
software, o destaque se volta para a estrutura da informação que é tratada pelo sistema,
ao contrário das operações ou funções às quais estas informações estarão sujeitas. A
estrutura da informação de um sistema corresponde ao conjunto organizado de
entidades que guardam alguma informação para o software e como elas se relacionam.
O princípio por trás da modelagem de dados é que um sistema de informação processa
informação. Dá-se uma maior em qual informação é processada e não em como se dá
este processamento.
Na modelagem de dados não há lugar para representar as características dinâmicas
do problema, suas funções, operações ou algorítmos. Ainda que algumas regras de
negócio reflitam apenas em elementos estáticos ou limites destes elementos, a maioria
das regras de negócio exige a criação de algorítmos mais complexos que não encontram
abrigo no modelo de dados. Existe, entretanto, na modelagem de dados uma grande
reutilização das informações armazenadas e da sua estrutura. A capacidade em se
adaptar uma mesma estrutura de dados em problemas semelhantes é muito grande,
dando amplas possibilidades de uma grande reutilização deste tipo de modelo.
Problemas semelhantes usam estruturas de informação semelhantes.
É importante se observar que nem sempre a estrutura da informação reflete a
estrutura do problema. Algumas vezes redundâncias e hierarquias presentes no
problema são eliminadas ao se analisar apenas a informação armazenada. O processo
de normalização de tabelas de um banco de dados é um exemplo desta simplificação. 
Outra observação importante é que um sistema exige dados e funções,e que nem
sempre uma abordagem permite uma visão se integra perfeitamento na outra.
Desenvolver um sistema pelo paradigma de dados ou pelo paradigma funcional resulta
em um sistema com grande acoplamento, onde qualquer modificação necessária, seja
em dados, seja em funções pode resultar em um trabalho complexo demais. A figura
mostra que um dado pode ser necessário para mais de uma função e que que modificar
um dado requer modificar muitas funções.
 
Figura 6 - Um programa combina dados e funções
A orientação a objetos enfoca a busca da estrutura do problema, e não apenas da
informação. Identifica em objetos, os elementos importantes do domínio do problema,
que guardam dados e possuem funções que podem operar seus dados. Não são apenas
as funções que o sistema deve desempenhar, como na modelagem funcional, nem
somente os dados que serão armazendados, como na modelagem de dados; a
importância maior é encontrar os elementos do problema que possuem todas estas
propriedades.
Sebesta (1996) estuda a evolução das linguagens de programação e verifica que
enquanto a programação procedural foi desenvolvida na década de 70, na década de 80
começou-se a combinação de algoritmos e estruturas de dados em objetos com a
linguagem Smalltalk. As idéias da programação orientada a objetos foram incorporadas
à linguagem C gerando C++ que ajudou a popularizar as linguagens orientadas a objeto.
Apesar de ser possível haver programação orientada a objetos desde 1980, os
conceitos que envolvem o projeto de sistema com esta filosofia não são simples, e por
isso demoraram a ser utilizados pela comunidade de desenvolvedores. Os programas
continuavam, até meados da década de 90, a serem projetados com uma separação clara
entre a análise funcional e a análise de dados. Num sistema onde qualquer função
pudesse se utilizar de qualquer dado armazenado, seria impossível saber quais dados
são necessários para cada função, sem analisar cada uma das funções separadamente.
Esta grande dependência entre os dados e as funções dificulta uma alteração nos dados
ou nas funções, porque as conseqüências são imprevisíveis. É importante criar um
critério para se unir dados e funções em conjuntos organizados e coerentes. Desta idéia
surge a modelagem orientada a objetos.
Um objeto, segundo Jacobson et al (1992), é caracterizado por um conjunto de
operações e um estado que armazena os efeitos das operações que o objeto é capaz de
realizar. Assim os dados armazenados no estado objeto servem para armazenar o efeito
das funções, criando-se o vínculo desejado entre as operações e os dados. Os objetos
tem uma dimensão maior do que apenas os dados e as funções isoladamente, como
exemplifica a figura.
Figura 7 - Objetos reúnem dados e funções
A orientação a objetos parte da constatação que o mundo é formado por elementos
autônomos e relativamente independentes, e que criar um modelo de um sistema de
software é identificar quais destes elementos são relevantes para o software. Os
objetos que devem ser incluídos no modelo são os que realizam algo de destaque para o
problema em questão. Esta abordagem reduz a distância entre o modelo e o mundo real,
porque utiliza elementos da realidade para criar o modelo, facilitanto o entendimento
do problema pelo analista e pelo cliente.
Selecionar a orientação a objetos para analisar um problema, inclui uma série de
características intrínsicas à tecnologia de objetos que devem ser bem entendidas para
que o analista possa fazer um uso correto deste paradigma. Dentre estas características
destacam-se o conceito de encapsulamento das classes, a herança, a troca de mensagens
e o polimorfismo. Estas características serão apresentadas a seguir, acompanhadas de
exemplos práticos que visam a facilitar o entendimento.
2.4.1. Encapsulamento
Todos os dados e operações necessárias para um objeto existir, e realizar suas
responsabilidades para o sistema, devem estar armazenadas no próprio objeto. Diz-se
que o comportamento e os dados estão encapsulados no objeto. Envoltos em uma
cápsula os dados dos objetos não estão mais isolados das funções, eles caminham
juntos.
Figura 8 - Esquema do encapsulamento
O encapsulamento é a principal característica para se identificar um objeto. O
princípio por trás desta idéia é que o objeto possua todos os dados e as funções
necessárias para sua existência. Selecionar um objeto da realidade para o modelo
indica que ele representa algo que existe de fato no domínio do problema, e que será
transportado para o domínio do modelo do software, com toda a sua autonomia.
 
Figura 9 - Um objeto deve representar algo que existe de verdade
Um lâmpada, como a da figura, é um objeto importante, por exemplo, para um
sistema de controle doméstico. As propriedades que a lâmpada possui, para este
sistema são uma tensão elétrica e um preço. A lâmpada oferece para este sistema as
funcionalidades de acender a um determinado preço pelo qual foi comprada.
O encapsulamento protege os dados de um objeto do acesso descontrolado por
outros objetos. O acesso é realizado por intermédio de mensagens trocadas entre
objetos, que nada mais são do que chamadas das funções do objeto. Apenas a interface
do objeto, formada pelo conjunto de funções, é exposta, oferecendo serviços deste
objeto ao mundo exterior. Como as mensagens passam por uma função do objeto antes
de acessar os dados, esse acesso é controlado e o dado protegido. As informações do
objeto e como ele implementa estes serviços são mantidos ocultos. A este conceito
chamamos de ocultamento de informações, e é outra decorrência importante do
encapsulamento de objetos.
O encapsulamento dos objetos encontra analogia em diversas situações da vida
diária. Um exemplo de sucesso de encapsulamento presente em nossas casas é o caso
do aparelho de TV e do aparelho de reprodução de DVD. Vamos observar que as
funções da TV e da unidade de DVD são muito bem definidas: o aparelho de TV possui
como função apresentar imagens, enquanto o a unidade de DVD reproduz imagens
armazenadas no formato padrão do DVD. Eles se complementam para servir o seu
usuário, e ao mesmo tempo se mantêm independentes.
Figura 10 - Exemplos reais de encapsulamento
Além das funções específicas, os aparelhos possuem uma interface bem definida e
padronizada que permite que sejam operados sem a necessidade de se conhecer o
funcionamento interno dos aparelhos. Assim como nos objetos, estes aparelhos
protegem os componentes e suas informações de um uso indevido, expondo apenas uma
interface externa.
O encapsulamento implica em outra característica própia da orientação a objetos,
que é a colaboração entre os objetos pela troca de mensagens. A integração dos
componentes ocorre interligando a saída de um objeto com a entrada do outro, de modo
que um objeto possa acionar uma função do outro objeto. De modo análogo, o DVD se
comunica com a TV para utilizar a função de exibição de imagens. O aparelho de DVD
pede à TV que apresente as imagens, e para isso ele envia pela interface externa de
comunicação , a mensagem com a imagem a ser apresentada. A operação em separado
dos aparelhos é confiável e segura, o que leva a uma confiabilidade e segurança da
operação em conjunto.
O encapsulamento leva à reutilização, outro grande benefício da orientação a
objetos. Com ela é possível separar a criação de objetos, da integração destes objetos
em sistemas. A reutilização é uma das conseqüências mais procuradas no projeto
orientado a objeto, pois dela decorre uma redução no custo do desenvolvimento de
novos sistemas e uma maior facilidade de manutenção e expansão. Um objeto bem
projetado, testado e confiável pode ser utilizado em diversas situações, diluindo o seu
custo entre várias aplicações. A manutenção é simplificada e a expansão pode ser
realizada de forma mais controlada. Usando ainda o exemplo da TV e do DVD deve-se
observar que a TV pode ser utilizada como um objeto para apresentação de imagens em
diversos sistemas de multimídia, assim como quando um aparelho de vídeo cassetepode ser substituido, quase sempre, por um aparelho de DVD, mais moderno, sem
necessariamente alterar o aparelho de TV. 
Figura 11 - Exemplo de interface padronizada
A figura mostra uma interface padronizada para a operação da maioria dos
aparelhos eletrônicos de reprodução de som e imagem. O uso repetido permite que seja
qualquer for a implementação interna, o usuário saberá o que irá acontecer se escolher
a seta (reproduzir) ou o quadrado (interromper).
O que caracteriza um encapsulamento eficiente é a definição precisa da interface. A
interface é a a lista dos serviços que o objeto oferece, ela esconde como o objeto as
implementa. Muitas interfaces já estão padronziadas e há um grande esforço geral de
padronização para tornar o acesso aos serviços de objetos mais fácil e simplificado.
Existem boas perspectivas para a modelagem orientada a objetos nos serviços de
objetos distribuidos. Diversos serviços comuns a muitos sistemas podem ser oferecidos
aos objetos desde eles atendam a uma interface padronizada, como o padrão
CORBA ou o padrão EJB. (Orfali, 1998).
2.4.2. Mensagens
A comunicação entre os objetos se dá por meio de mensagens. Um objeto que
desejar uma informação de outros objetos deve solicitar às funções destes objetos, na
forma de mensagens, que responda ao seu pedido. Como um sistema é formado por um
conjunto de objetos, o processamento do sistemas é obtido mediante a troca de
mensagens entre os objetos.
Uma mensagem é a chamada de uma função de um objeto, é o acionamento de uma
operação encapsulada no objeto de destino, feita a partir do objeto de origem. A
informação transmitida é passada ao objetos de destino pelos parâmetros da função,
enquanto a resposta da mensagem é obtida pelo parâmetro de retorno da função. Assim,
por definição, toda mensagem tem uma resposta de retorno e pode transmitir uma
informação na chamada e no retorno.
Para que os objetos se comuniquem é necessário que haja algum tipo de
vínculo integrando estes objetos. Estes vínculos, que podem ser relacionamentos
existentes entre os objetos, asseguram um conhecimento que um objeto tem da
existência do outro.
 
Figura 12 - Troca de mensagens entre objetos
Retomando o exemplo o DVD, nota-se que ele se comunica com a TV por
intermédio da função de exibir imagens que a TV possui. Esta função está disponível na
interface da TV, o que permite que outros aparelhos possam servir a TV com imagens.
Outra forma interessante de comunicação existente entre estes objetos é a comunicação
existente entre os equipamentos eletrônicos e o controle remoto. O controle remoto
recebe os comando do usuário e os transmite para a TV como mensagens. Esta
comunicação é facilitada porque as interfaces entre o controle e a TV, e entre a TV e o
DVD são padronizadas.
O que permite esta forma de comunicação entre os objetos é a definição de uma
interface precisa. Assim, como o encapsulamento isola as estruturas internas do objeto,
ele deve expor uma interface que permita que o objeto receba mensagens de outros,
formando o sistema. Vale observar que a comunicação entre os objetos é bastante
restrita, as mensagens recebidas por um objeto se limitam às operações expostas na
interface. Caso o sistema exija que uma nova mensagem seja enviada, é necessário criar
uma função específica para receber esta mensagem no objeto de destino. A definição
das interfaces e das mensagens a serem implementadas nos objetos é uma importante
atividade de modelagem do sistema, desempenhada durante a fase de design no projeto
de um software.
Figura 13 - Exemplo da comunicação entre objetos
 
2.4.3. Tipos, Classes e Objetos
Aplicando o encapsulamento em larga escala, observa-se que existem grupos de
objetos compartilham a mesma interface, isto é, apesar se serem objetos distintos,
oferecem os mesmos serviços para o sistema. Estes objetos seguem a mesma estrutura e
definem o que chama-se de um tipo abstrato de dados. Um tipo é uma estrutura de dados
com um conjunto de definições de operações que afetam esta estrutura. No tipo não
existe a preocupação de implementar estas operações, ele serve apenas para se definir
um padrão no modelo, reduzindo a complexidade da modelagem.
A implementação de um tipo é uma classe. A classe possui, além das definições, a
implementação das operações, para criar um componente autônomo para o sistema. A
classe é um molde para a criação de objetos, porque permite descrever um conjunto de
objetos que compartilha a mesma estrutura de dados e as mesmas definições operações.
Todos os objetos de uma classe possuem as mesmas definições mas podem possuir
valores diferentes nos dados, respondendo de modo diferente às mensagens enviadas à
ele.
Figura 14 - Exemplos de Classes e Objetos
Um objeto é uma instância de uma classe, ele realiza a classe para o sistema. A
estrutura do objetos é definida pela classe, mas as operações e estados são definidos na
instância (Jacobson, 1992). No mundo real os objetos existem e trocam mensagens. É a
partir destes objetos que se abstrai as classes para o modelo, porque no modelo se está
interessado nas estruturas dos objetos. O processo de classificação dos objetos, isto é,
determinar a classe a que o objeto deva pertencer, é a essência da modelagem orientada
a objetos.
Em um exemplo típico de uma instalação de engenharia é possível classificar os
equipamentos como equipamentos elétricos e equipamentos hidráulicos. A figura
abaixo mostra esta classificação na forma de conjuntos . As classes estão associadas
aos conjuntos,e os objetos aos seus elementoss destes conjuntos, que compartilham as
mesmas propriedades. Pertencer ao conjunto equivale dizer que o elemento compartilha
algumas características. Podem existir equipamentos que possuem características de
mais de um conjunto.
Figura 15 - Subclasses da classe Reprodutor de Imagens
O exemplo pode mostrar a classificação não é única e pode estar sujeita a múltiplas
interpretações, dependendo do enfoque que se queira dar ao problema. O importante é
verificar em cada classe quais as propriedades que estão sendo compartilhadas pelos
seus elementos, para haver uma boa relação entre o modelo e a realidade.
Figura 16 - Classes se assemelham a conjutos de objetos
2.4.4. Herança
A herança é uma das principais características da orientação a objetos, e que está
intimamente associada ao conceito de agrupamento dos objetos segundo um conjunto de
propriedades comuns. Uma classe de um objeto é o agrupamento de objetos que
compartilham a mesma estrutura de dados e funções. É possível se encontrar grupos que
possuam um conjunto de propriedades, e que a partir deste grupo seja possível criar
outros grupos que possuam propriedades ainda mais específicas, formando assim um
subconjunto do anterior. A orientação a objetos permite criar uma relação entre as
classes de objetos de modo que classe pode ser gerada a partir de outra classe,
herdando dela suas propriedades estáticas (atributos) e dinâmicas (funções).
 A herança permite ainda que as características herdadas da classe mãe possam ser
alteradas e expandidas pela classe filha. Incluindo novas características, ou
modificando características existentes. Esta capacidade dos modelos orientados a
objetos permite que a modelagem seja feita em camadas de classes, criando uma árvore
para cada classe, com um nível decrescente de abstração, quando se caminha da mãe
para a filha.
O uso da herança permite criar classes mais genéricas, com funcionalidades gerais e
que podem ser herdadas por várias classes em diferentes situações simplificando a
modelagem e implementação. A herança de classes aumenta muito a capacidade de
reutilização das classes, porque pode-se criar classes genéricas com propriedades
gerais e que podem ser utilizadas em diversas situações. O reuso de classes apresenta
um efeito positivo no prazo e no custo do desenvolvimento de projetos de software.
Figura 17 - Exemplo real de herança
No exemplo, a herança é utilizada para distribuir os equipamentosem categorias.
Observa-se que, inicialmente, todos são equipamentos. Os equipamentos podem ser
para casa, podem ser elétricos e podem ser mecânicos. Alguns equipamentos para casa
são também elétricos, criando a classificação dos eletrodomésticos. 
O conceito de herança e de objetos em software não é novo, mas foi pouco utilizado
nos projetos de sistema até que as linguagens de programação que permitissem
implementar em software estes conceitos com facilidade. Hoje existem várias
linguagens orientada a objetos que permitem incorporar herança e encapsulamento nos
sistema de software.
2.4.5. Polimorfismo
Uma decorrência interessante da comunicação por mensagens e da herança a
orientação a objetos é o polimorfismo. Define-se polimorfismo como a propriedade
que o emissor de uma mensagem não precisa conhecer a instância da classe que recebe
esta mensagem. (Jacobson, et al, 1992). Esta propriedade leva ao fato de que uma
mesma mensagem pode ser interpretada de modos diferentes, quando for recebida por
objetos diferentes. Assim, como as implementações das funções que recebem a
mensagem são diferentes elas podem responder de forma diferente (poli = múltiplas,
morfo="forma"). Polimorfismo é a propriedade de que a mesma mensagem pode ser
respondida de forma diferente por duas ou mais classes.
Há alguma confusão entre o encapsulamento e o polimorfismo porque ambos se
referem ao ocultamento da implementação do mundo externo ao objeto. No entanto, o
polimorfismo está centrado na possibilidade de uma resposta diferente devido ao
desconhecimento do destinatário da mensagem, enquanto no encapsulamento a
implementação está apenas oculta do mundo exterior.
Figura 18 - Polimorfismo: a mesma mensagem tem respostas diferentes
2.4.6. Vantagens da Orientação a Objetos
Ao escolher desenvolver um software pelo paradigma de objetos, o
desenvolvedor procura obter uma série de vantagens, decorrentes das
características desta abordagem: 
O uso de objetos na modelagem torna mais fácil descrever as estruturas e o
comportamento existente no mundo real. Essa proximidade faz com que os clientes
possam se identificar mais diretamente com os problemas nos modelos.
O encapsulamento do conhecimento em componentes isola o comportamento, o que
permite que as mudanças nos requisitos possam também serem isoladas em cada
componente sem afetar o sistema como um todo.
O uso de classes e objetos facilita a integração das fases do processo de
desenvolvimento, porque ao contrario de outros modelos onde cada fase possui
técnicas e paradigmas próprios, na orientaçã a objetos o mesmo paradigma é
conduzido da análise à construção.
O encapsulamento favorece o teste dos sistemas de software, que pode ser isolado
para cada componente. O resultado é um aumento na qualidade do sistema.
O encapsulamento permite ainda que os componentes possam ser desenvolvido
por fornecedores diferentes,
A reutilização, decorrente do encapsulamento, reduz custos e prazos no
desenvolvimento de software porque possibilita que o mesmo componente seja
usado em vários projetos,
A herança associada ao encapsulamento permite abordar problemas mais
complexos do que com outras abordagems de desenvolvimento. A herança cria
uma família de objetos com uma complexidade crescente e que podem ser
aplicados em vários problemas diferentes.
Algumas das vantagens da orientação a objetos podem ser compravadas na prática
com o estudo de caso que se segue.
2.5. Estudo de Caso: Automação de Vendas
Para melhor entender os conceitos da tecnologia de objetos, segue um exemplo da
aplicação desta tecnologia. O objetivo é destacar, didaticamente, as características da
orientação a objetos em um sistema que reproduz uma automação de vendas. Não se
pretende resolver o problema de automação comercial, mas utilizar como exemplo o
problema do sistema de informações para apoio às vendas em uma loja. Como um
sistema de informação gerencial, ele deve atender as regras do negócio e,
simultaneamente, ser flexível para acomodar as mudanças destas regras, resultado
natural da evolução do negócio. A adoção do paradigma de objetos ajuda a obter esta
flexibilidade, conseguida pelo uso correto das características desta tecnologia como:
encapsulamento, as mensagens, a herança e o polimorfismo, que serão demonstradas a
seguir.
Este estudo de caso também serve para exemplificar a abrangência e aplicabilidade
dos modelos em um sistema prático. Inicia-se formulando o problema por meio de uma
visão do contexto onde este sistema se encontra. Segue-se construindo um modelo
conceitual do sistema, que define as principais classes do sistema e suas relações. Das
definições preliminares passa-se para um detalhamento que se traduz na implementação
do sistema. O escopo do exemplo é limitado ao entendimento dos princípios da
orientação a objetos, sem descer em detalhes excessivos dos códigos e das opções de
implementação, que podem ser encontrados no capítulo 6, no final do livro.
2.5.1. Contexto do Problema
O estudo de caso ocorre com uma loja de departamentos e o seu processo de venda.
Um cliente escolhe os produtos que deseja comprar. Ele se encaminha a um caixa que
deve finalizar a venda. Em geral, o caixa possui um terminal com um leitor de código
de barras que obtém, com base em um código, o preço dos produtos. Alguns produtos
podem ter descontos para pagamento a vista, ou parcelamento em 2 ou 3 vezes, com ou
sem juros. Este estudo se interessa pelas etapas de determinação do preço e das
condições de pagamento do produto. Deseja-se um sistema de informação que dado o
código do produto informe o preço e as condições de pagamento deste produto. As
condições de pagamento serão definidas em função do crédito que o cliente tem com a
loja em uma regra de negócio pré-estabelecida. Segue-se a arquitetura do sistema e as
regras de negócio:
Arquitetura do Sistema
O sistema é processado em uma rede de postos de venda, também conhecidos como
POS (do inglês: point of sale). Eles fazem a interface entre o caixa, funcionário da loja,
e um computador central que processa as requisições do processo de venda. A figura
abaixo descreve esta arquitetura:
 
Figura 19 - Esquema da Arquitetura do Sistema da Loja
O computador central armazena os dados dos produtos, dos clientes e do histórico
das vendas em um banco de dados. As regras do negócio também são processadas no
computador central. Os POS implementam uma camada de apresentação e comunicação
com o caixa, e fazem as requisições ao computador central. Existe um pequeno poder
de processamento local nos POS que pode ser utilizado, dependendo da aplicação e da
estratégia de desenvolvimento escolhida.
Regras de negócio
O processo de venda proposto para esta loja resume-se a três ações, executadas
pelo caixa, por meio do POS:
1. Identificar o produto pelo seu código,
2. Identificar o crédito do cliente e seus dados pessoais pelo seu CGC[2], e
3. Informando o número de parcelas, verificar se a venda parcelada foi aprovada.
A principal regra de negócio neste sistema está na aprovação do crédito nas vendas
à prazo. Por uma norma estabelecida pela administração da loja, todo cliente tem um
crédito gerenciado pela loja e que pode ser elevado pelo gerente, conforme as novas
compras do cliente na loja. No entanto, o cliente não pode financiar compras acima do
seu crédito. Se o saldo de uma compra parcelada for superior ao crédito do cliente, a
venda não é aprovada.
Por exemplo, se um cliente possui um crédito de R$1.200,00 e deseja comprar um
produto de R$ 2.100,00 ele pode comprar à vista porque não fica com saldo devedor.
Pode também parcelar em duas vezes de R$1.050,00 porque o saldo devedor será de
R$1.050,00 e inferior ao seu crédito de R$1.200,00. No entanto, se ele quiser parcelar
em 3 vezes iguais de R$700,00 terá um saldo de R$1400,00 superior ao seu crédito, e
não conseguirá aprovar a venda.
Esta regra pode ser expressa pelo pseudocódigo abaixo, para uma venda de n
parcelas, onde:
saldo - valor que restaa pagar após a entrada
 preco - preço do produto à vista
 n - número de parcelas da venda
 credito - limite de crédito do cliente com a loja
saldo = (n-1)*preco
 se (saldo<=credito)
 então vendaAprovada
 senão vendaNãoAprovada
Para incentivar a venda para alguns clientes especiais identificados como
ClientesVIP a loja dá um crédito dobrado para estes clientes, de modo que os clientes
considerados VIP podem fazer dívidas com a loja duas vezes superiores ao valor do
crédito, se não fossem VIP.
É possível que alguns produtos tenham, em época de promoções e descontos,
condições especiais de venda a serem definidos posteriormente. Por exemplo, uma
promoção pode permitir a venda de determinados produtos, em até 3 parcelas 
independente do crédito do cliente. O sistema a ser desenvolvido para automatizar a
loja deve ser flexível para acomodar estas modificações e outras novas regras de
negócio no futuro.
2.5.2. Modelo Conceitual
Estabelecendo-se este contexto e seus requisitos, é possível definir um sistema para
atendê-los, partindo dos principais conceitos deste problema. No modelo conceitual já
são percebidas as características da orientação a objetos, onde o primeiro passo é
identificar as classes presentes no sistema. Analisando a descrição do contexto do
sistema, observa-se que o processo de venda ocorre entre os seguintes personagens:
O Cliente, que pode ser VIP ou não e possui o crédito;
O Caixa que processa os pedidos como usuário final;
O POS que define a interface com o sistema;
A Loja onde estão aramazenadas as regras e informações e
 O Produto que possui o preço e as ofertas.
Com estes personagens, é possível se definir o processo de venda, sob o ponto de
vista da orientação a objetos, caracterizando as mensagens que os objetos trocam entre
si. Sob este ponto de vista, o processo de venda ocorre em 3 fases, a saber:
Fase 1 - Identificação do Produto
Para identificar o produto pelo seu código, o caixa inicialmente lê o código no
produto e pergunta para a loja: Qual é o produto com o código xxxxx? . A pergunta é
dirigida para a loja porque a loja é responsável por manter uma lista de seus produtos. 
A loja então, procura nesta lista o produto desejado e o retorna ao caixa com as
informações sobre este código. O caixa pode então, se quiser, descobrir o nome e o
preço do produto.
Fase 2 - Identificação do Cliente
Analogamente ao produto, o caixa pode pegar o número do CGC do cliente, e
perguntar para a a loja, quem é o cliente que possui o CGC yyyyyy? A resposta da loja,
caso o cliente esiver presente na lista de clientes da loja, será o próprio cadastro do
cliente, que retorna ao POS. Neste cadastro o caixa pode verificar os dados do cliente
como nome, o crédito que este cliente possui, entre outras informações.
Fase 3 - Autorização do Crédito, para vendas à Prazo
O caixa, representado pelo POS, possui, após as consultas anteriores, um produto e
um cliente. Sabendo que o cliente deseja fazer a compra em n parcelas, algum elemento
do sistema deve informar se esta venda pode ser realizada ou não. No exemplo, a venda
será realizada se a dívida do cliente, na compra parcelada, for menor do que o crédito
que o cliente possui com a loja, como manda a regra de negócio. Algum componente da
loja precisa ser responsável por testar esta regra de negócio. Tomando uma decisão de
projeto, optou-se em atribuir esta responsabildade para o produto. Assim, para saber se
a venda pode ser realizada o caixa pergunta para o produto: Você produto, pode ser
vendido para este cliente por n parcelas? O produto, conhecedor da regra de negócios,
responde com um sim ou não e termina esta etapa do processo de venda.
Estas três ações podem se decompostas na forma de mensagens trocadas entre os
componentes principais do negócio: caixa/POS, produto e cliente e loja. Imaginemos
estes componentes como personagens de um mundo fictício, onde o processamento do
sistema é realizado com uma coleção de perguntas e respostas entre estes componentes,
esquematizada na figura abaixo:
Figura 20 - Comunicação entre os Componentes da Loja
Neste modelo conceitual pode-se analisar as características de encapsulamento das
classes, integração com banco de dados, mensagens e herança; próprias do modelo
orientado a objetos.
Encapsulamento
A primeira característica que se observa na descrição do problema é a existência de
alguns objetos bem identificados. Na descrição foram usados o POS, a Loja, o Cliente
e o Produto. Nenhuma ação ficou sem uma origem ou um destino entre estes objetos. O
hábito de fazer compras em lojas, torna estes conceitos familiares para a maioria dos
leitores, o que facilita muito o entendimento do processo. Todos sabem que uma loja é
um estabelecimento comercial onde os clientes encontram os produtos e podem adquirí-
los. Pra facilitar o processo de venda a loja mantém, além de uma lista de produtos
para venda, uma lista de clientes cadastrados, com um limite de crédito.
A lista de produtos é análoga a uma estante onde os produtos a serem vendidos
estariam expostos para a venda. Cada Produto possui um preço, uma descrição e um
código para facilitar a venda. Qualquer outro objeto do sistema pode escolher um
Produto e verificar seu nome, preço e código simplesmente “perguntando” para ele. O
Produto possui estas informações a seu respeito, e possui ainda meios para responder à
perguntas o tipo: Qual é o seu preço? A característica do Produto de ser auto-
suficiente em prover informações sobre si mesmo é conseqüência do encapsulamento.
No modelo, a Loja é uma entidade que se relaciona com os POS para prover
informações para as vendas. O POS é uma interface de acesso às informações da Loja,
e por isso ele pergunta para a Loja o que ele quer saber. Para conseguir dar todas as
respostas como o preço do produto, ou o crédito do cliente a Loja conta com outros
objetos encapsulados na própria Loja: uma listaDeClientes, que guarda a lista de
todos os clientes da loja e uma listaDeProdutos, que guarda todos os produtos à
venda. Ao ser questionada sobre qual é o produto que possui um determinado código, a
Loja procura este produto na sua lista e devolve o objeto oProduto. Este produto é
criado e transferido para fora da classe Loja, para uso do POS. Esta é uma importante
característica relacionada ao encapsulamento dos objetos: o objeto oProduto é
transferido para o POS em resposta à esta mensagem, todas as informações e a
capacidade de receber mensagens e dar respostas vai com ele. Como está encapsulado
no objeto todas estas habilidades, elas são transferidas em conjunto com o objeto.
 
Figura 21 - Esquema dos Objetos do Sistema
O POS de posse do objeto Produto, fornecido pela Loja pode fazer perguntas
diretamente para ele, e prosseguir o processamento do sistema. Analogamente, a Loja
fornece um Cliente ao POS quando pede para identificar o Cliente pelo seu CGC. O
nome, o crédito próprios deste cliente são transferidos encapsulados no objeto. Em um
sistema orientado a objetos não há como separar uma informação do seu proprietário.
Não é possível existir um método sem que um objeto seja o seu dono. O
encapsulamento é obrigatório.
Temos, neste exemplo, duas classes: a dos Produtos e a dos Clientes. As classes
definem tipos de objetos. Uma classe define uma estrutura que é compartilhada por
todos os objetos que forem criados a partir daquela classe. Esta estrutura é formada por
um conjunto de dados armazenados pelo objeto, e um conjunto de funções que o objeto
usa para se comunicar. Os dados e as funções estão encapsuladas no objeto e só
existem enquanto existir o objeto. Cada função é uma possível mensagem que o objeto
está habilitado a responder.
A análise de um sistema parte, inicialmente, por uma definição das classes do
sistema para então definir como os objetos, gerados a partir destas classes, irão
interagir. O modelo conceitual de um sistema é, em síntese, um modelo das classes do
sistema, e da sua estrutura. No modelo conceitualdevem ser descritas as classes
extraídas do domínio do problema e como elas se organizam. É de se esperar que
terminada esta descrição, grande parte dos problemas estejam, conceitualmente,
resolvidos. Resta entretanto, o detalhamento necessário para a implementação.
Integração com Banco de Dados
A lista de clientes e a lista de produtos da loja devem estar disponíveis para a
pesquisa assim que o sistema inicia a operação. Para que isto seja possível elas devem
ficar armazenadas em um banco de dados, na forma das tabelas: Tabelas de Clientes,
Tabela de Produtos.
 
Figura 22 - Fluxo dos dados na carga do banco de dados
Para efeito de testes serão utilidadas as seguintes tabelas de dados, que mostram a
estrutura dos dados disponíveis para a loja
Um objeto pode receber chamadas de mensagens de outros objetos, para isso ele
dispõem de funções que são acionadas pelo objeto chamador. Uma mensagem pode
enviar com ela uma informação e recebe outras informações como resposta. A
comunicação entre o caixa, que é uma pessoa, e o POS, uma classe de um software
orientado a objetos, ocorre na forma de mensagens. O Caixa ativa eventos no POS,
pressionando botões para enviar as mensagens, e recebendo as respostas em uma tela.
As mensagens enviadas pelo Caixa ao POS se transformam e outras mensagens que o
POS e pode enviar a outros objetos do sistema como a Loja.A execução do sistema se
inicia com a criação da lista de clientes (listaClientes) e de produtos (listaProdutos).
Antes da execução do programa esta lista estava armazenada no banco de dados da
loja, para transferir estas tabelas para os objetos foi criada uma classe auxiliar:
BDLoja. Esta classe cria os objetos com base nos dados existentes no banco de dados.
Neste exemplo optamos por executar esta criação na inicialização do sistema. No
entando, ela pode ser feita em tempo de execução, isto é, na medida em que os objetos
são solicitados pelo sistema eles são procurados no banco de dados.
Mensagens
A comunicação entre os objetos ocorre na forma de mensagens. Uma mensagem é a
chamada de uma função de um objeto, requerida por outro objeto. O objeto POS é uma
interface gráfica criada para o caixa poder acionar as funcionalidades disponíveis nos
objetos da loja, ou em objetos locais. Ele recebe a solicitação feita pelo Caixa e as
transfere para os outros objetos do sistema. Esta seqüência de mensagens forma o
processamento em um sistema orientado a objetos.
O POS é uma classe criada para se colocar entre o usuário final, o caixa, e os
demais objetos do sistema. Os elementos presentes no POS são caixas de diálogo e
botões. Uma caixa de diálogo permite que se entre com dados em caixas de texto
apropriadas. Outras caixas de diálogo apresenta uma forma do POS se comunicar com
o usuário pelas mensagens escritas. Os botões representam as funcionalidade que o
POS oferece ao Caixa.
Figura 23 - Interface do POS
A classe Cliente, por exemplo, oferece ao sistema a funcionalidade de informar o
seu crédito. As mensagens podem ser entendidas como perguntas feitas de um objeto a
outro. As perguntas não são formuladas na forma interrogativa como Qual é o crédito?,
mas sim escritas na forma imperativa como obtenha o crédito ( ou getCredito ). Assim
dado o objeto comprador do tipo Cliente (Cliente:comprador); podemos perguntar ao
comprador qual o seu crédito, usando a função getCredito[3], que devolve um valor de
crédito como resposta, na forma da mensagem:
vCredito = comprador.getCredito()
Neste comando, a variável vCredito recebe o valor do crédito do comprador. Como
podemos ver, o formato típico de uma mensagem, também conhecida como a assinatura
de uma mensagem, é mostrado abaixo. Entre os parentesis “( )” da função podem ser
transferidos parâmetros e dados de entrada na pergunta.
Resposta = objeto.função( )
 O botão CLIENTE serve para enviar a pergunta para a Loja: Quem é o cliente que
possui o CGC yyy? Onde o valor do cgc foi digitado na área de entrada de dados. A
mensagem que é enviada ao objeto Loja é :
Comprador = loja.getCliente(yyy)
Figura 24 - Exemplo da Operação do Sistema
O botão PRODUTO pergunta para a Loja: Qual é o produto com o código xxx? ,
com o valor do código digitado na área de entrada de dados.
 
 oProduto = loja.getProduto(xxx)
O botão PARCELAS pergunta para o produto, se ele pode ser vendido para este
comprador por n parcelas? Onde n foi digitado na área de entrada de dados e o
oProduto e o comprador foram obtidos nas respostas das perguntas acionadas por
CLIENTE e PRODUTO.
 
Aprovado = oProduto.isAprovado(n, comprador)
 
Figura 25 - Exemplo do sistema em operação
A figura mostra o processamento que não aprovou a venda do item de código 101
para o cliente 1000 em 3 parcelas.
Herança
No exemplo, foi definida uma regra de negócio na qual o cliente pode se tornar um
cliente do tipo VIP que possui as mesmas características do cliente comum, mas com
uma capacidade de crédito dobrada. Isto é, ele pode fazer dívidas duas vezes maiores
que o seu crédito. Assim deve-se criar uma classe ClienteVIP que deriva da classe
Cliente, ou como se diz na linguagem da orientação a objetos, a classe ClienteVIP
herda da classe Cliente os seus dados e funções.
A capacidade de uma classe herdar de outra classe é uma das principais
características da orientação a objetos. A classe Cliente é chamada de super classe, ou
classe mãe, da subclasse ClienteVIP ou classe filha. O que isso que dizer que a classe
filha é, inicialmente, uma classe igual à classe mãe, mas pode modificar ou extender
suas habilidades, podendo ser mais especializada que a classe mãe original.
No exemplo, a classe ClienteVIP é uma classe Cliente possuindo por isso um
nome, um CGC e um crédito; no entanto, por ser um ClienteVIP ele terá o seu crédito
dobrado. Para implementar esta modificação a função de informar o crédito é reescrita
de modo a responder com o crédito em dobro, como mostra a tabela que compara estas
duas funções:
 
Cliente.getCredito( ) ClienteVIP.getCredito( )
public int getCredito () public int getCredito ()
{ return (credito);
}
 { return (2*credito);
 }
 
Como o ClienteVIP é também uma classe do tipo Cliente, os objetos gerados por
ClienteVIP podem assumir o papel dos objetos do tipo Cliente, isto é podem fazer
parte da lista de Clientes da Loja e também ser enviado como resposta ao POS. Em
qualquer situação onde um objeto do tipo Cliente possa ser usado um outro objeto do
tipo ClienteVIP também pode. Esta versatilidade dos sistemas orientados a objeto dá
ao analista uma liberdade muito grande para expandir o sistema sem perder as
funcionalidades já implementadas. O analista pode buscar as heranças próprias do
problema estudado, e criar árvores de classes, descrevendo o problema por intermédio
de camadas crescentes de significado e funcionalidade. Quando o sistema em projeto
atingir o nível de significao desejado é interrompido o desenvolvimento.
 
 
 
 
 
 
 
 
 
3. Modelo de Contexto
 
 
Este capítulo descreve o modelo de contexto do sistema, representado na
UML pelo diagrama de casos de uso. Este modelo, o primeiro a ser criado para
definir um problema, representa as expectativas funcionais dos usuários e por isso é
desenvolvido em conjunto entre analistas e usuários. São descritos aqui alguns
cuidados próprios deste tipo de modelagem, e o resultado da aplicação desta técnica
em um exemplo de aplicação.
 
 
3.1. Introdução
A escala de observação é o fator que define o nível dos detalhes observados em um
modelo. Alguém olhando de uma grande distância pode distinguir uma casa na paisagem
e até dizer se há fumaça saindo pela chaminé, mas não saberá dizer se as paredes são
lisas e bem cuidadas, ou se há alguém na sala. Ao se aproximar um pouco mais poderá
distinguir as portas e janelas e até enumerá-las. Aproximando-se ainda mais da janela
da sala, por exemplo, poderá olhar por ela e saber se há alguém na sala, mas deixa de
observar a chaminé. Perde-se anoção do todo ao se manter atento a um único detalhe.
Deve-se escolher a distância e o ponto de vista em função do que se pretende analisar
com o modelo.
Observando um fenômeno com uma grande escala pode-se ver o seu comportamento
global e o balanço entre as entradas e saídas, mas perde-se o detalhe de cada processo
independente. Reduzindo a escala, o número de detalhes aumenta, e observa-se
particularidades que estavam perdidas na visão geral, o problema é que agora perde-se,
inevitavelmente, a visão global. Não é possível observar globalmente e ao mesmo
tempo ter todos os detalhes. Cada fenômeno a ser estudado exige que selecionemos uma
escala adequada para modelá-lo.
Este estudo propõe-se organizar a modelagem de sistemas de software segundo três
modelos: modelo de contexto, modelo conceitual e modelo detalhado. Este capítulo
descreve o modelo de contexto, que observa o sistema a uma grande distância, de
modo que um único diagrama é suficiente para representar o sistema como um todo.
Não é possível, com o modelo de contexto, observar detalhes da operação, construtivos
ou de implementação. No entanto, é um modelo suficiente para se notar as
funcionalidades principais do sistema e se ter uma definição clara de quais são os
elementos externos ao sistema com quem ele deve se relacionar. O modelo de contexto
ajuda a definir onde o sistema estudado se insere na empresa, ou seja, em qual contexto
da empresa o sistema se encontra.
É com o modelo contextual que se inicia a definição do problema, colocando o
sistema no contexto do negócio e do cliente. A idéia de desenvolver um modelo que
faça a integração do sistema em estudo com o contexto do cliente exige que o modelo
seja simples, e de certo modo até intuitivo. Isto é, o cliente deve ser capaz de
reconhecer o sistema no modelo sem a necessidade de um treinamento especial. O
modelo de contexto não deve possuir uma formalidade excessiva, para poder ser
entendido e validado pelo próprio cliente. Deve ser possível ao cliente situar o sistema
no seu contexto de trabalho, identificando pontos de integração com outros sistemas e
com seus usuários.
Para criar o modelo de contexto usaremos dois recursos da UML: o diagrama de
pacotes e o diagrama de casos de uso. O modelo de pacotes ajuda a dividir um sistema
em subsistemas, e identificar as dependências entre os subsistemas. O modelo de casos
de uso ajuda a definir os requisitos funcionais e a desenhar a fronteria de cada
subsistema.
3.2. Pacotes, Sistemas e Subsistemas
Ao se estudar um sistema de informações, que se pretende automatizar, pode-se
chegar a um número de problemas que impledem o seu tratamento, como um todo
porque o conjunto é complexo demais. O analista precisa ter neste momento,
ferramentas para organizar este sistema complexo em partes menores, às quais chamam-
se de subsistemas. Um subsistema possui todas as características de um sistema, e é
parte integrante de um sistema completo maior.
A organização em subsistemas surge, naturalmente, da análise detalhada de um
problema. Ela pode ser realizada por um particionamento funcional, organizacional,
operacional, ou por diversas outras formas. A única exigência é que a união destas
partes, ao final, formem o sistema completo proposto inicialmente.
O pacote é o elemento da UML utilizado para agrupar os elementos de um sistema,
para organizá-los, um pacote pode abrigar outros elementos, outros diagramas, e até
outros pacotes. O pacote assume a simbologia de uma pasta com o nome do sistema.
Um sistema, ou subsistema, quando visto de longe, como uma unidade, pode ser
modelado na UML por um pacote.
Figura 26 - Representação de um pacote
A representação gráfica de um pacote é feita pelo o ícone de uma pasta, metáfora
que recorda um armazenador, um conjunto de conteúdos organizado sob um nome, o
nome do pacote.
Apesar de estarem sendo indicados aqui para modelar os sistemas e subsistemas, os
pacotes podem ser aplicados em qualquer fase do desenvolvimento de um software,
inclusive para organizar as próprias fases do desenvolvimento, versões do sistema,
isolar componentes de software, etc. Os pacotes se aplicam a todos os modelos da
UML, mas tem uma aplicação maior nos diagramas estruturais como os de classes e
casos de uso.
A boa prática manda usar nomes simples, curtos, escrito em letras minúsculas. Os
nomes devem estar associados aos componentes principais, ou subsistemas, que o
pacote representa. Os pacotes podem se relacionar com outros pacotes, através de uma
relação de dependência. Um subsistema pode depender de outro subsistema. Esta
relação pode ser apresentada graficamente, em um diagrama de pacotes. As
dependências são representadas por meio de setas tracejadas. As setas partem do
subsistema dependente e apontam para os subsistemas independentes.
Figura 27 - Exemplo de dependência entre subsistemas 
Retomando o exemplo do sistema de automação comercial que controla as vendas
de uma loja e gerencia o crédito e o cadastro dos clientes. Para organizar este sistema
pode-se dividí-lo em três subsistemas: vendas, crédito e cadastro; como mostra a
figura. Nela pode-se ver que o subsistema vendas depende do subsistema de crédito e
de cadastro, adicionalmente, o subsistema de crédito também depende do cadastro dos
clientes.
Os pacotes oferecem um meio simples de se organizar os modelos, que na medida
em que eles se tornam mais complexos. É comum com o crescimento do entendimento
do problema ou com a evolução do sistema em direção à fase de implementação, os
modelos se tornam demasiadamente complexos, grandes ou poluidos com informação
em excesso. O uso de pacotes pode ajudar a organizar os modelos nestes caso, além da
divisão em subsistemas já vista. Deve-se, no entanto, tomar o cuidado para não utilizar
pacotes em excesso, que uma vez pode ser um elemento que dificulta a leitura de
modelos simples.
Em uma primeira abordagem, a escala dos subsistemas permite definir os limites do
sistema e sua divisão, quando necessária, em subsistemas. Deve-se agora observar o
interior de cada subsistema, para criar um modelo que permita observar cada
pacote isoladamente, em um único diagrama. O modelo de contexto aumenta o seu nível
de detalhes, mas permite ainda uma visão global, feita com uma grande escala, com um
alto nível de abstração.
3.3. Modelo de Contexto
O modelo de contexto define a fronteira entre o que é sistema do que não é sistema.
O que é sistema pode ser modificado pelo desenvolvimento do software. O que não é
sistema, e por isso ficará fora da fronteira, não pode ser modificado pelo software, mas
interage ele. Utiliza-se os diagramas de casos de uso propostos por Jacobson (1992) e
adotada pela UML, para descrever o modelo de contexto. A técnica tem como principal
vantagem a simplicidade da representação, que permite uma interação direta com os
clientes e usuários na definição dos requisitos funcionais do sistema
Em 1987, Jacobson apresenta os Casos de Uso (Use Cases) usados como ferramenta
da metodologia Objectory. A adoção do termo Caso de Uso possui claramente a
intensão em mostrar uma visão do usuário do sistema, e de que o sistema de informação
é construído para os seus usuários. No diagrama de casos de uso o sistema é descrito
como uma caixa preta, e que possui algumas funcionalidades. Cada funcionalidade
corresponde ao que se convencionou chamar de Caso de Uso. Em 1992, Jacobson
(1992) lança um livro onde onde toda a Engenharia de Software Orientada a Objetos é
desenvolvida sob uma abordagem de Caso de Uso. O diagrama de Casos de Uso foi
incorporado desde a primeira versão da UML (Jacobson, 1998) como uma abordagem
funcional feita pelo usuário, com finalidade de nortear os demais diagramas do modelo
orientado a objetosda UML.
3.3.1. Diagrama de Casos de Uso
O objetivo do diagrama de casos de uso é descrever um modelo funcional de alto
nível do sistema em projeto. Este diagrama procura identificar os usuários e representar
o sistema segundo a sua visão. Jacobson (1992) afirma que umconjunto de descrições
de casos de uso deve especificar completamente a funcionalidade do sistema, assim os
desenvolvedores devem procurar junto aos usuários de cada subssistema formar este
conjunto de casos de uso.
Os casos de uso são utilizados em todas as fases do desenvolvimento de um sistema.
No início, durante o desenvolvimento e ao final, quando o sistema está pronto. A
aplicabilidade inicial do diagrama de casos de uso é a de auxiliar o analista na
definição dos requisitos do sistema. Os requisitos que o sistema devem atender são
decorrentes do uso que os usuários pretendem do sistema. As funcionalidades
pretendidas devem ser transformadas em objetivos que o sistema deve cumprir para
seus usuários. Esta definição de requisitos pode ser suficiente para se assumir um
contrato entre os clientes e desenvolvedores na fase inicial do projeto. Os objetivos
dos usuários serão os casos de uso do sistema, e o compromisso dos desenvolvedores é
de atendê-los.
Durante as fases de design e construção, os casos de uso são usados para ajudar a
criar outras visões, além da funcional, do sistema. A análise da descrição dos casos de
uso pode ajudar a entender os processos e a dinâmica dos problemas envolvidos no
sistema. A partir da descrição, contida nos casos de uso, pode-se extrair o que sistema
deve fazer e como ele deve atender os usuários. Os casos de uso devem ser explorados
durante o desenvolvimento para validar o sistema. A cada nova funcionalidade
implementada no sistema os casos de uso podem ser usados para validar se esta
funcionalidade está de acordo com o especificado pelos usuários.
Como os casos de uso são criados a partir da visão do usuário. Eles podem ser
aplicados na fase final de testes de integração do sistema. A partir de cada de uso é
possível definir testes, por vezes chamados de casos de teste, que são aplicados no
sistema, quando este estiver pronto. Os diagramas de casos de uso podem ser usados
para o planejamento do desenvolvimento do sistema, uma vez que é possível extrair das
funcionalidades contidas nos casos de uso uma medida da complexidade.
Apesar de grande flexibilidade, a utilização dos casos de uso deve ser limitada, e
pode ser mal utilizada se for extrapolada a abrangência da sua aplicação. É comum se
tentar traduzir a funcionalidade expressa nos casos de uso diretamente para um sistema
de software, deixando de lado os modelos orientados a objeto. Esta é uma abordagem
exclusivamente funcional, uma vez que os diagramas de casos de uso são análogos aos
diagramas de fluxos de dados (DFD) da abordagem funcional. Agindo assim, abandona-
se a orientação a objetos e volta-se ao paradigma funcional.
O diagrama de casos de uso deve isolar os elementos do sistema de software dos
elementos externos. Os elementos externos são chamados de atores, e interagem com os
casos de uso no sistema. A figura abaixo mostra um exemplo de um diagrama de casos
de uso.
Figura 28- Exemplo de Diagrama de Casos de Uso
No exemplo observa-se que um ator (ator1) pode se comunicar com mais de um
caso de uso, isto é, pode utilizar o sistema para mais de uma finalidade (casos de uso 1
e 2). Assim também, a mesma finalidade (caso de uso 2) pode ser compartilhada por
mais de um ator (atores 1 e 2).
3.3.2. Atores
Os atores representam os elementos externos ao sistema que interagem com ele.
Estar fora do sistema é não poder ser alterado pelo desenvolvimento do sistema. Isto
quer dizer que o desenvolvedor não tem sobre o ator o poder de programar a sua ação,
como ele tem sobre o computador nos casos de uso. Ao focar os atores, a modelagem
procura se concentrar em como o sistema será utilizado, e afastar o analista de como o
sistema será contruído. Ainda não deve haver na descrição dos casos de uso
compromisso assumido com a construção. A importância dos atores, no modelo de
contexto, vem do princípio de que os sistemas computacionais servem para atender as
necessidades de seus usuários. O mais importante nos primeiros passos do
desenvolvimento de um sistema é identificar quem são os atores e quais são as suas
necessidades.
 Um ator é um papel de alguém ou alguma coisa no ambiente que se relaciona com o
sistema. Alternativamente, Jacobson (1992) define ator como representando tudo que
precisa trocar informação com o sistema, ou seja, qualquer coisa que interage com o
sistema. Assim, uma mesma pessoa pode assumir mais de um papel, e ser representada
no sistema por mais de um ator. O termo ator caracteriza bem a possibilidade do
mesmo usuário, em diferentes situações, assumir personalidades diferentes para o
sistema, agindo como um ator em uma peça teatral. Em cada uma destas situações,
deve-se procurar identificar as necessidades dos atores, que se tornarão requisitos para
o sistema, na forma de casos de uso. A linha que separa os atores dos casos de uso é a
fronteira do sistema.
Deve-se notar a diferença entre atores e usuários. Os usuários do sistemas são
instâncias dos atores. Um mesmo usuário pode, em diferentes momentos do sistema,
instanciar diferentes atores, ou seja um mesmo usuário pode assumir diferentes papéis
no sistema.
Representação
. Os atores são, normalmente, representados por uma figura humana estilizada. A
UML admite também o uso de ícones e outras simbologias para representar um ator, que
podem ser representados também por um retângulo com a anotação <<ACTOR>>. A
anotação <<ACTOR>> , representa um estereótipo da UML, e permite transformar a
simbologia escolhida em um ator.
 
 Figura 29 - Formas alternativas de representar um ator.
Os atores devem ser identificados com um nome que traduz o papel deles no
sistema. Não existem regras rígidas para dar nomes aos atores, mas uma boa prática é
utilizar nomes substantivos, com o significado ligado ao domínio do
problema estudado. Deve-se evitar dar nomes muito genéricos como: Usuário,
Operador ou Sistema. O uso da palavra "Usuário", como o nome de um ator, pode ser
utilizada desde que, por exemplo, aquele ator represente todos os usuários do sistema.
Os atores são encontrados entre os usuários prováveis do sistema. Usuários que
podem ser pessoas ou até mesmo outros sistemas computacionais. Uma das técnicas é
cercar, imaginariamente, o sistema e observar quem interage com ele. Pode-se procurar
a quem a solução do problema interessa, e quem colabora para se chegar a esta
solução. Nestes personagens encontram-se os atores. É comum encontrar grupos de
personagens, que se comportam da mesma forma frente ao sistema. Estes grupos são
representados com um único ator do sistema. A mesma pessoa, usuária do sistema,
pode pertencer a mais de um grupo, e assim uma mesma pessoa pode assumir mais do
que um papel, e ser representada no modelo de contexto por mais do que um ator.
Em um processo é possível que os atores se relacionem entre si, trocando
informações, mensagens ou realizando algumas operações entre si. O analista deve
observar se esta comunicação entre atores se dá dentro ou fora do sistema, para decidir
se deve ou não representá-la. Quando a comunicação é feita dentro do sistema ela é
importante para o desenvolvedor porque deverão existir comandos e interfaces no
software para permitir que os dois atores se relacionem. No caso da comunicação fora
do sistema ela não é representada pelos casos de uso e não é importante para o
desenvolvimento do software.
Um ator representado no sistema não pode ser programado, ele fica fora do escopo
do desenvolvimento do sistema, e, provavelmente, não é alterado pelo sistema.
Observa-se, entretanto, que a introdução de um sistema de informações afeta muito além
do que as fronteiras definidas inicialmente, podendo ir para além dos usuários. No
início do desenvolvimento de um sistema um ator possui necessidades que são
expressas e consideradas como requisitos do sistema de software. Quando o software é
implementado, e as necessidade iniciais são atendidas, surgem outras necessidades nos
usuários, que foram provocadas pela introdução do sistema, ouseja, o sistema pode
também alterar os atores. Este efeito é, normalmente, desconsiderado no
desenvolvimento pela sua alta complexidade e pela incapacidade de ser modelado e
tratado com precisão. O analista experiente pode tentar prever um sistema que se
adapte à esta nova realidade e incluir estes requisitos no problema.
Exemplo
A figura abaixo mostra alternativas de representação de atores em um determinado
sistema. Considerando que a melhor alternativa é aquela que incorpora uma quantidade
maior de informação, temos que:
 
3.3.3. Caso de Uso
As necessidades dos atores são representadas nos casos de uso. Um caso de uso é 
uma seqüência de transações ocorridas no sistema, que refletem em algo de importância
para o ator que se comunica com este caso de uso. Os atores definem suas necessidades
na forma de objetivos a serem cumpridos pelo sistema, que são capturados pelos casos
de uso.
O princípio, por trás deste diagrama, é que um sistema de software é criado para
atender os seus usuários, representados no diagrama pelos atores. Os atores demandam
resultados do sistema, que se organizam em objetivos, representados nos casos de uso.
Um caso de uso se traduzirá em uma série de ações, que vão descrever como um ator
poderá atingir o seu objetivo, assim como as alternativas e as exceções que irão
impedir a conclusão com sucesso deste objetivo. Todos estes cenários de interação do
ator com o sistema devem estar inclusos na descrição dos caso de uso.
Utiliza-se um caso de uso quando se deseja representar uma funcionalidade de alto
nível no sistema, ou para representar um conjunto de funcionalidades esperadas por um
ator. Para identificar os casos de uso devemos consultar os atores, e observar as suas
necessidades, agrupando-as e associado-as aos atores. Um caso de uso é composto por
uma representação gráfica e por um descrição textual, que são descritas a seguir:
Representação Gráfica
Um caso de uso é representado, graficamente, por uma elipse em torno do seu nome,
como mostra a figura. Associado ao nome, um breve texto descreve o objetivo que o
caso de uso está representando.
Figura 30 - Representação Gráfica de um Caso de Uso
O nome do caso de uso é, em geral, uma oração verbal curta que representa, no
contexto do sistema, o objetivo pretendido. Os atores formam o sujeito da ação
expressa pela oração. Desta forma, é conveniente utilizar verbos no presente, no
infinitivo ou no gerúndio para identificar os casos de uso, como mostram os exemplos a
seguir:
Os diagramas de casos de uso podem ser lidos colocando-se o ator como sujeito e
os casos de uso como predicado, na forma:
O Gerente (pode) aprovar crédito
O Cliente (está) consultando Catálogo
O Comprador realiza a compra.
 
Figura 31 - Exemplos de Casos de Uso
Descrição Textual
Associado a cada caso de uso um texto descreve os fluxos de eventos que resultam
no objetivo pretendido pelo ator. Todo caso de uso tem, necessáriamente, um fluxo de
atividades principal, que vai levar o ator ao sucesso do seu objetivo. A seqüência
normal de atividades pode apresentar caminhos alternativos ao fluxo principal,
assim como seqüências de atividades que descrevem falhas que impedem o ator de
atingir o seu objetivo. A figura mostra, esquematicamente, estes fluxos, que devem
ser descritos em um texto que acompanha o caso de uso:
Figura 32 - Fluxos possíveis em um caso de uso
 (a) principal, (b) alternativo e (c) caminho com falha
A descrição dos casos de uso pode ser escrita em uma linguagem informal, em um
texto estruturado ou até mesmo com um pseudocódigo. O importante é que a descrição
de um caso de uso possa ser aprovada pelo cliente do sistema, e que os projetistas
possam entender o processo de negócio. Os casos de uso podem também ter pré e pós
condições, que vão condicionar a seqüência de transações que devem ocorrer. As
precondições dizem que para o ator poder executar aquele objetivo são necessárias
algumas condições anteriores, assim como a execução do objetivo leva a uma condição
posterior à execução (pós-condição).
Toma-se como exemplo o caso de uso onde um cliente consulta um catálogo de
produtos de uma suposta loja virtual. Este caso de uso, chamado de Consultar Catálogo
pode ser descrito textualmente, de forma não estruturada como:
 
Caso de Uso: Consultar Catálogo
Busca por um ou mais produtos em um catálogo de produtos. Os produtos são
organizados por tipo e família. A consulta pode ser feita selecionando-se o tipo de
produto e em seguida escolhendo uma família daquele tipo. Os produtos podem ser
ordenados por preço ou por ordem alfabética do nome. É possível procurar um
produto por parte do nome ou da descrição. A procura fornece uma lista de produtos
onde o texto procurado foi encontrado no nome ou na descrição. Se o usuário da
consulta já se identificou para o sistema, a lista dos últimos 10 produtos procurados
pode ser apresentada, facilitando a procura.
Este mesmo caso de uso também pode ser descrito de forma estruturada, como:
Nome: Consultar Catálogo
Objetivo principal: Permitir a procura de um ou mais produtos em um catálogo
de produtos organizado por tipos e famílias de produtos.
Alternativas Alternativamente a procura pode ser feita por uma palavra existente no
nome ou na descrição do produto.
Exceções Se o catálogo não oferece o produto procurado, oferecer uma lista com
os dez produtos mais procurados.Se mais de 50 produtos atendem o critério de
procura, os produtos são apresentados em grupos de 50.
Précondições : O cliente deve estar cadastrado,
Pós-condições : Após a procura os produtos encontrados passam a compor a lista
de produtos procurados, que podem seguir para o processo de compra.
A descrição estruturada é mais formal e por isso mais completa que uma descrição
não estruturada e informal. A descrição informal é suficiente na maioria dos sistemas,
principalmente para a validação do modelo de contexto por parte dos usuários. No
entanto, a descrição estruturada é mais adequada na aplicação dos Casos de Uso em um
método formal para desenvolvimento de sistemas.
Colaboração entre os Casos de Uso
Os casos de uso podem colaborar com atores e com outros casos de uso. Estas
colaborações são expressas no diagrama por meio de ligações entre os elementos que
colaboram. As ligações podem, opcionalmente, ter uma seta que não tem valor
semântico, ela apenas orienta a leitura do diagrama. As colaborações dos casos de uso
são sempre bidirecionais, o que quer dizer que pode haver troca de informação nos
dois sentidos da colaboração.
Os atores se comunicam, controlam e recebem informações dos casos de uso. Uma
colaboração entre os casos de uso e os atores indica que os objetivos do ator são
definidos pelos casos de uso. Deve-se verificar se todos os objetivos do ator estão
presentes e são bem definidos.
Um caso de uso pode colaborar com outros casos de uso para conseguir cumprir o
seu objetivo principal. Isso quer dizer que um objetivo principal pode ser decomposto
em objetivos intermediários de outros caso de uso. Esta decomposição fará com que os
casos de uso mantenham entre si uma relação de dependência, representada pela seta
tracejada. O caso de uso dependente está na origem da seta, e o independente no destino
da seta.
 Figura 33 - Colaboração entre os Casos de Uso
3.3.4. Considerações Gerais sobre o Modelo de Contexto
Algumas considerações gerais são importantes na formação do diagrama de casos
de uso, e podem auxiliar a criar um diagrama correto.
Independência entre Casos de Uso
Os casos de uso devem ser escolhidos de modo a serem independentes entre si,
apesar de poderem existir relações entre eles. Isso se deve para evitar que hava uma
confusão entre as funcionalidades especificadas. Erros na separação pode, algumas
vezes, levar à inconsistências entre os casos de uso. Um caso de uso pode especificar
um tipo de responsabilidade que é negada por outro. O modelo de contexto não tem
meios de evitar ou lidar com estas inconsistências, que serão tratadaspor outros
modelos, posteriormente.
Granularidade dos Casos de Uso
Um dúvida frequente durante a construção do modelo de contexto é o grau de
detalhes que se deve adotar ao se criar em caso de uso. Por definição, os casos de uso
reúnem um conjunto de transações que conduzem à um objetivo do ator. Assim, se por
um lado, os casos de uso devem ser mais complexos do que uma simples transação; por
outro lado os casos de uso não devem compreender um número muito grande de
transações. Um número grande de objetivos, poderiam ser decompostos em alguns
casos de uso. A situação desejada é uma situação intermediária. Espera-se que os
casos de uso escondam uma complexidade razoável, que serão exploradas,
posteriormente, no modelos conceituais e detalhados (pelos diagramas de seqüência e
colaboração). Os fluxos de informação textual conduz o leitor do diagrama a uma
estrutura funcional do sistema. Na análise conceitual, os fluxos de eventos vão conduzir
o analista aos conceitos fundamentais do sistema, que serão distribuídas entre as
classes do sistema. Não se deve confundir os casos de uso com as classes. Berard
(1996) destaca este e outros cuidados que se deve ter ao aplicar os Casos de Uso para
não comprometer a aplicação do paradigma de objetos no decorrer do projeto.
Evitar a decomposição de casos de uso
Outro erro comum, na aplicação dos casos de uso, é a tentação de se realizar uma
decomposição de objetivos dos atores, como é comum na análise estruturada. Criando-
se casos de uso intermediários como etapas de um processo, transformando-se o
diagrama de casos de uso em um fluxograma de processos. Pode-se estabelecer uma
relação direta entre um diagrama de contexto da análise estruturada e diagrama de
casos de uso, mas não se deve transformar um diagrama de casos de uso em um
fluxograma.
Na decomposição funcional há uma grande proximidade com as funções, na
abordagem de dados, a proximidade é com os dados, e na abordagem de objetos a
proximidade é com o objetos. Como os casos de uso tem uma natureza funcional, a
mudança para objetos, realizada nas fases seguintes da análise, pode provocar erros.
Por exemplo, alocar casos de uso a equipes diferentes de desenvolvedores, provoca um
desastre na modelagem orientada a objetos, mesmo que de subsistemas diferentes,
porque provavelmentem, haverá a criação de objetos iguais nas duas equipes com
funcionalidades semelhantes e que deveriam estar agrupados (Berard,1996).
Integrar o cliente na modelagem
O diagrama de casos de uso deve ser construído em conjunto entre os usuários e
demais projetistas. A notação simples facilita o entendimento e estimula a crítica ao
modelo, permitindo validá-lo já nas fases iniciais da análise. Como o diagrama de
casos de uso traduz uma visão de fora para dentro do sistema, descrevendo o que o
sistema deve fazer, é importante a aprovação do cliente e usuários para o sucesso do
projeto.
Deve-se, entretanto, evitar o excesso de formalismo na elaboraçãos dos casos de
uso. Desaconselha-se, por exemplo, o uso de recursos computacionais na elaboração
dos casos de uso quando da apresentação dele para os seus usuários, que pode afastá-
los do processo de desenvolvimento. O uso de um retroprojetor, quadro-branco, flip-
chart, papel e lápis é encorajado ao se discutir um modelo com os usuários. Estas
ferramentas são mais familiares e aproximam os usuários leigos em computação com o
desenvolvimento do sistema. O computador ou sistemas sofisticados de software
podem ser considerados barreiras à participação dos usuários nesta fase do projeto.
A validação de um sistema pelo cliente, nas fases iniciais so projeto, garante que
está se construindo o sistema correto. Isto é, as reais necessidades dos usuários estão
sendo consideradas e atendidas. Para isso é necessário revisar, iterativamente, o
modelo de contexto inúmeras vezes com os usuários. Em alguns casos, pode ser
necessário criar um protótipo da interface, para apresentar ao usuário, que assim pode
se assegurar que o sistema irá atendê-lo, pois visualiza ali a operação do sistema. A
identificação dos requisitos de interface podem ser extraídos facilmente do diagrama de
casos de uso, analisando as relações entre um ator e os casos de uso com quem ele se
comunica. É de se esperar que para cada caso de uso deva haver uma interface para
acionar o objetivo e receber as respostas.
Comprometimento com a implementação
 O ocultamento de informação (Information Hiding) é o processo de tornar certas
partes do sistema de software inacessíveis. Sugere-se que os detalhes do sistema, as
decisões de projeto difíceis ou que provavelmente vão mudar, devam ser ocultadas do
sistema. Assim, o resto do sistema tem acesso apenas as decisões bem definidas, e
inalteradas. Com a especificação descrita pelos casos de uso deve-se evitar expor
detalhes em demasia, ou impor decisões que serão tomadas no projeto ou na
implementação. Deve-se procurar evitar a tentação de especificar a estrutura interna ou
caraterísticas de implementação que condicionem, exageradamente, o componente,
limitando-o quando da sua implementação.
Casos de Uso em Testes
Um caso de uso é descrito por cenários de sucesso, alternativos e de fracasso de um
objetivo do ator no sistema. Analisando um caso de uso é possível se criar um conjunto
de dados de entrada que simule cada um destes cenários. Assim, para cada caso de uso
é possível se construir um caso de teste, que garante que o sistema, ao implementar o
caso de uso, será completamente testado. Essa é uma importante característica de um
projeto de software com casos de uso, que irão orientar todo o desenvolvimento do
software atendendo as necessidades dos usuários. Se houver dificuldade em se
estabalecer estes testes, deve-se suspeitar da clareza e da precisão deste caso de uso,
ou até mesmo da sua real necessidade.
Cuidados nas descrições textuais
Probasco (2001) destaca o cuidado que deve haver, por parte dos desenvolvedores,
na redação da descrição dos casos de uso. Em especial, ele destaca uma atenção maior
para a palavra “deve”. Como os requisitos dos casos de uso expressam a vontade dos
usuários, utilizar a palavra “deve” pode gerar obrigações que não podem ser
cumpridas, ou limitar, exageradamente, a implementação do sistema. Como prática
geral, não se recomenda o usar a palavra “deve”, sugerindo substituí-la por “sugere-
se”, “recomenda-se”, etc. O importante do caso de uso é que ele sirva como meio de
comunicação entre o cliente e os desenvolvedores.
3.4. Exemplo de Aplicação: Sistema de Vendas de Loja
Este exemplo retoma o sistema de vendas da loja descrito no capítulo anterior, para
introduzir a formalidade do modelo de contexto e dos diagramas de casos de uso.
3.4.1. Descrição de Subsistemas
Em uma loja qualquer, o sistema de vendas deve estar integrado a outros sistemas
de informação internos, importantes para o gerenciamento do empreendimento. Pode-se
representar cada sistema de informação como um subsistema da loja, caracterizado por
um pacote, como exemplifica a figura. Na figura mostra que o subsistema de vendas é
dependente do sistema de cadastro do cliente e do sistema de estoque, que poderia ser
o responsável por manter uma lista de produtos. A dependência entre estes
subsistemas fica clara em um diagrama de pacotes.
Figura 34 - Subsistemas relacionados ao sistema da loja
Neste exemplo, explora-se apenas uma pequena parte do subsistema de vendas. Da
descrição do sistema, elaborada no capítulo anterior, pode-se extrair que:
O caixa faz a venda em um terminal (POS)
O caixa le o código do produto
O caixa identifica o cliente pelo CGC
O caixa verifica o parcelamento
Vemos que o ator do sistema é o caixa, e que ele vem ao sistema com tres
objetivos, identificados nos três casos de uso da figura abaixo, a saber: Identificar
produto, Identificar cliente e Autorizar o parcelamento.
Figura 35 - Diagrama de Casos de Uso dos Processos de Venda
 
3.4.2. Descrição dos Casos de Uso
Segue uma descrição textual doscasos de uso identificados acima.
Identificar Cliente
O caixa recebe o número do CGC do cliente. Caso o cliente estiver presente no
cadastro da loja, verifica-se os dados do cliente como nome e o seu crédito. Um cliente
especial pode ter o dobro do crédito do cliente comum.
Identificar Produto
O caixa deve ler o código no produto, em um leitor de código de barras, ou deve
teclar o código. A loja é responsável por manter uma lista de seus produtos, com os
dados de nome e preço, entre outras informações sobre o produto. Com o código
identificado, o caixa recebe os dados do produto.
Autorizar parcelamento
O caixa de posse dos dados do produto e de um cliente, pode verificar se o cliente
pode fazer a compra parcelada. A venda será realizada se a dívida do cliente, na
compra parcelada, for menor do que o crédito que o cliente possui com a loja. O
sistema de vendas deve aprovar a venda ou não.
Este modelo poderia ser enviado para o cliente, irir analisar a especificação e
assegurar que o software, quando desenvolvido corresponde às suas expectativas. Esta
é a finalidade do modelo de contexto.
 
 
 
4. Modelo Conceitual
 
Este capítulo apresenta uma técnica para se desenvolver um modelo
conceitual do projeto de software. O objetivo aqui é identificar os principais
conceitos presentes em um problema e representá-los em classes, dando os primeiros
passos na direção da construção de um modelo orientado a objetos do problema.
Este objetivo é conseguido utilizando a técnica dos cartões CRC. Originalmente
criada para ensinar orientação a objetos, esta técnica é aplicada aqui como uma
forma de transformar os requisitos levantados no modelo de contexto nas classes do
modelo conceitual.
 
 
 
4.1. Introdução ao Modelo Conceitual
Este capítulo descreve o processo de criação de um modelo conceitual de um
sistema de software. Este modelo é obtido a partir dos requisitos levantados pelo
modelo de contexto. O analista deve se posicionar suficientemente próximo do sistema
para extrair dos requisitos do problema os conceitos principais, sobre os quais será
construída a solução. Esta aproximação gradativa do sistema, que esta abordagem de
modelagem recomenda, evita a sobrecarga de complexidade no modelo nas fases
iniciais do processo de desenvolvimento, facilita o entendimento do problema e auxilia
no desenvolvimento do sistema de software.
Enquanto o modelo de contexto descreve, funcionalmente, o sistema sob o ponto de
vista do usuário externo, o modelo conceitual dá as primeiras noções de como será o
interior do sistema. No modelo conceitual são esboçadas as idéias principais que
compõem o núcleo do sistema, descrevendo-o de dentro pra fora. A modelagem
conceitual se encontra entre as práticas propostas por Larman (1997) em seu livro
sobre a aplicação da UML. Neste trabalho, o modelo conceitual é definido como a
representação de conceitos ou objetos do domínio do problema. A estratégia
recomendada é de se criar um rascunho do diagrama de classes, onde a ênfase está em
descobrir os requisitos mais evidentes, antes de lançar mão de uma investigação
aprofundada. Mais tarde nos ciclos seguintes do desenvolvimento, o modelo conceitual
poderá ser refinado, incrementalmente, e estendido para considerar os demais
requisitos.
O modelo conceitual está também presente em métodos incrementais de
desenvolvimento de sistemas. As primeiras fases do processo criam uma visão da
arquitetura completa do sistema. Uma arquitetura que, nas fases seguintes, orienta a
produção de versões do sistema. Assim, cada versão chega, incrementalmente, mais
próxima da visão da arquitetura completa.
O modelo conceitual captura os conceitos do sistema em um diagrama de classes. O
diagrama de classes é a representação fundamental da modelagem orientada a objetos, e
evolui de uma visão conceitual para uma visão detalhada, com o desenvolvimento do
sistema. No modelo conceitual de classes é possível descrever os elementos principais
de um sistema, suas características individuais e como eles se relacionam.
A identificação de classes e das suas inter-relações é uma das etapas mais
complexas da análise orientada a objetos. Para sistematizar esta busca, apresenta-se a
técnica dos cartões CRC. Esta técnica é um método eficaz para se fazer a transição do
modelo de contexto para o modelo conceitual. Proposta por Beck e Cunningham (Beck,
1989), o uso dos cartões CRC facilita a aplicação do paradigma de objetos na análise
de um problema de software, e incentiva o envolvimento de usuários nas fases iniciais
da análise. No final deste capítulo, desenvolve-se o modelo conceitual do conhecido
jogo da forca, um dos casos estudados neste trabalho. Este exemplo é retomado no
capítulo 6 e tem o seu código construído na linguagem Java no apêndice.
4.2. Diagrama de Classes
Para se construir algo seguro é importante se ter uma base sólida. Uma afirmação
verdadeira tanto para uma construção civil, como, por exemplo, na construção de um
sistema de software. Para se obter um sistema de software confiável é necessário criar,
inicialmente, uma estrutura sólida e estável. Sobre esta estrutura são armazenadas as
informações do sistema, e são desenvolvidos os processos necessários para a solução
do problema em questão. A estrutura de um sistema de software é formada pelas
classes do sistema. Analogamente ao esqueleto dos animais, as classes formam uma
armação que dá a forma ao sistema. As qualidades de um sistema são garantidas por um
conjunto de conceitos fundamentais, bem definidos, capturados nas classes e que
acompanharão o sistema da concepção à implementação.
Classes são matrizes de objetos, elas identificam grupos de elementos do sistema
que compartilham as mesmas propriedades. A diferença entre classes e objetos já foi
assunto do capítulo 2, mas aqui esta diferença é revista à luz da análise de requisitos.
Os objetos são os elementos concretos envolvidos nas transações dos sistemas, criados
a partir das definições abstratas das classes. Os objetos são instâncias das classes.
Freqüentemente, a descrição de um sistema descreve um caso, uma situação em
particular onde o personagem é o objeto. Na representação, usa-se escrever os nomes
dos os objetos por letras minúsculas e das classes por letras maiúsculas.
As classes representam um conceito importante para o problema em questão.
Enquanto uma classe descreve um conceito abstrato do domínio do problema, um objeto
representa um elemento deste conceito, que é utilizado no sistema, de modo concreto.
Ao criar um objeto, com base em uma classe, ele assume valores para os atributos,
definindo um estado e herda um comportamento das classes que permite alterar este
estado. Os estados e os comportamentos são compartilhados por todos os objetos da
mesma classe, e são definidos na fase de análise. 
A UML incorporou a representação de classes utilizada na OMT de
Rumbaugh (Rumbaugh et al., 1994) com pequenas alterações na notação. As classes são
identificadas por retângulos divididos horizontalmente em tres porções, como mostra a
figura. No terço superior encontra-se o nome da classe, no terço médio a lista de
atributos e no terço inferior a lista de operações que esta classe pode realizar. Apesar
desta ser a forma básica de representação, existem formas alternativas que variam de
acordo com o interesse de representação e a precisão desejadas.
 
Figura 36 - Representação típica de uma classe
A figura abaixo mostra algumas alternativas de representação da classe Loja do
problema do capítulo 2. Na figura a classe Loja possui desde uma representação
simplificada até uma representação bem detalhada, onde os atributos e as operações
são descritos com grande precisão e adornados por símbolos que irão definir a sua
visibilidade, valor inicial e tipologia. Para efeito do modelo conceitual iremos adotar a
representação (a ) ou (b), deixando a notação (c) para o modelo detalhado, que é o
assunto do capítulo seguinte.
 (a) (b) (c)
Figura37 - Formas alternativas de se representar uma classe
Os atributos das classes formam uma estrutura que permite o armazenamento de
informação. Podemos ter objetos encapsulados nos atributos das classes, com a sua
própria estrutura de atributos, e a sua própria capacidade de armazenamento de
informações.
As operações são as mensagens que a classe pode receber, e que definem as
funcionalidades que aquela classe está apta a realizar. Os objetos relacionados com a
classe podem oferecer a ela funcionalidade adicional na forma de mensagens que são
trocadas. Uma classe isolada é, essencialmente, um depósito de informações nos seus
atributos e oferece ao sistema um conjunto de funcionalidades definidas pelas suas
operações. Para fazer uso destas potencialidades as classes precisam se relacionar.
No exemplo da loja, do capítulo 2, foram identificados os conceitos de Produto,
Cliente, ClienteVIP e Loja. Cada um com suas propriedades como o Nome do
Cliente, o Código do Produto, etc. O trompete que possui o código 107 é um objeto da
classe Produto. Charlie Parker é o nome de um objeto da classe Cliente, Charlie
Mingus é o nome de outro objeto da classe ClienteVIP. Como é um ClienteVIP
possuirá um comportamento de crédito diferente do Cliente, que permite parcelar as
compras de maior valor. O exemplo mostra que os conceitos, atributos e
comportamentos são definidos juntamente com as classes, mas só se tornam reais
quando as classes se tornam objetos durante o processamento do software. Vale
observar ainda, que a classe Loja, na figura possui na sua definição uma lista de
objetos da classe Cliente (listaClientes) e uma lista de objetos da classe Produto
(listaProduto). Este exemplo mostra como os conceitos podem se relacionar para criar
conceitos mais complexos.
 
4.2.1. Relacionamento entre as classes
Sistemas orientados a objetos são formados por conjuntos de classes. Uma classe
não pode atender isoladamente todas as necessidades do problema, e por isso ela se
integra às outras, para juntas apresentarem uma solução ao problema. Em conjunto, as
classes trocam mensagens para realizar os objetivos do sistema. O relacionamento entre
as classes serve de caminho para esta troca de mensagens, permitindo que as classes se
“conheçam”, e criando um caminho que possibilita a comunicação.
As classes podem se relacionar de modos que variam de acordo com as afinidades
existentes entre as classes. Os relacionamentos podem ser fracos, indicando que as
classes não possuem uma grande afinidade, ou fortes atestando uma grande
interdependência entre elas. Seguindo esta escala, podemos classificar os
relacionamentos como:
Dependência (mais fraco)
Associação
Agregação
Herança (mais forte)
 
4.2.2. Dependência
O relacionamento mais fraco é a dependência. Representada por uma seta tracejada
ligando as classes, a dependência parte da classe dependente e aponta para a classe
independente. Na figura abaixo, a classe A depende da classe B, o que quer dizer que,
de alguma forma, não especificada pela relação, os atributos ou as operações da classe
A dependem da classe B. A dependência não indica como ocorre esta dependência,
mas serve para indicar que estas classes devem participar juntas do sistema.
Figura 38 - Exemplo de dependência: A depende de B
 
No exemplo da loja do capítulo 2, podemos dizer que a classe Loja depende das
classes Produto e Cliente. Esta dependência é representada pelas setas que ligam estas
classes na figura abaixo. A dependência pode evoluir, em uma fase posterior da
modelagem, para outro tipo de relacionamento que defina melhor a afinidade entre as
classes.
Figura 39 - Exemplo de dependência entre as classes.
A dependência é um relacionamento comum entre os pacotes. Ela representa o fato
de que existe algum tipo de relacionamento entre as classes que compõem os pacotes e,
conseqüentemente, os pacotes estão também relacionados. Como o relacionamento
entre os pacotes não está claramente determinado porque depende das classes que eles
contém, usa-se representá-lo pela dependência.
Figura 40 - Exemplo entre dependência entre os pacotes
4.2.3. Associação
As associações aparecem quando há um nível maiorde envolvimento, e mais bem
definido do que na dependência, entre as classes. Na associação as classes estão
ligadas semanticamente umas às outra. Ou seja, as classes mantém-se independentes,
mas guardam uma algum tipo de significado na sua relação. Esta relação já permite a
troca de mensagens entre as classes na ajuda para o cumprimento de suas
responsabilidades. Na figura abaixo a classe R está associada à classe S. A classe R
pode chamar as operações de S por intemédio do objeto varS que é um objeto da classe
S, e que representa a associação. A representação da associação é uma linha que
interliga as classes. Esta linha pode possuir uma seta indicando a direção da
associação. Outros adornos das associações serão vistos mais à frente no texto.
Figura 41 - Exemplo de associação entre as classes
Deve-se observar que uma associação significa que existe um objeto do tipo da
classe associada na classe de origem. Assim o objeto varS, que é do tipo S, está
presente na classe R através da associação. Estando presente, R pode se comunicar
com S através de varS.
4.2.4. Agregação
Alguns tipos de associação podem exigir um aumento no grau de envolvimento entre
as classes o que cria a agregação. A agregação é equivalente à associação mas indica
que as classes possuem uma dependência existencial, isto é, uma classe só existe em
conjunto com as suas agregadas. A classe todo é composta pela(s) classe(s) parte. Na
figura abaixo a classe X é composta pela classe Y, o que quer dizer que a classe X
possui um objeto da classe Y, identificado por varY, que também é o nome da relação.
A agregação é representada por uma seta unindo as classes com um losango indicando a
classe todo.
 
Figura 42 - Exemplo de agregação
No exemplo da loja apresentado no capítulo 2 a classe POS possui um objeto da
classe Produto chamado de oProduto e um objeto da classe Cliente chamado
oCliente. Estes objeto representam o produto que será vendido e o cliente interessado
em comprá-lo. O POS os utiliza para o processamento das ações de venda. Estes
objetos foram criados e transmitidos ao POS pela classe Loja, mas fazem parte da
classe POS e por isso são representados como uma agregação onde o todo é o POS e
as partes são oProduto e oCliente. Supondo, por hipótese, que o POS venha a ser
desligado, os objetos da venda que não foi ainda concluída serão perdidos. Assim
também a lista de clientes e a lista de produtos fazem parte da Loja. Supondo que a loja
seja vendida, o novo dono recebe também a lista de clientes e a lista de produtos, eles
são indissociáveis. No exemplo, as listas de clientes e de produtos são fortemente
dependentes da Loja. Sendo este o fator determinante na decisão na modelagem deste
relacionamento como uma agregação.
Figura 43 - Exemplo de Associação entre Classes
Pode-se considerar a agregação como um caso especial da associação, onde há um
vínculo maior entre as classes. Este vínculo pode crescer a ponto de uma classe
depender existencialmente da outra. O que significa dizer que se a classe todo deixar de
existir, as classes partes deixam também de fazer sentido para o sistema. Na
associação, as classes se mantem independentes, isto é, elas podem participar de outras
associações no projeto onde não haja esta depedência e podem ser instanciadas
isoladamente. 
4.2.5. Herança
Um tipo de relacionamento importante para o desenvolvimento de sistemas
orientados a objeto é a herança. O conceito de herança também foi apresentado no
capítulo 2 e se caracteriza por criar uma hierarquia entre as classes do sistema. Nesta
hierarquia, algumas classes, chamadas de superclasses, servem de matriz para a criação
de outras classes, as subclasses, que especializam as superclasses originais.
Constrói-se uma hierarquia de generalização-especializaçãoindo de superclasses
mais gerais para subclasses mais específicas. Ao se especificarem, as subclasses
aproveitam tudo o que já foi definido pelas superclasses pela herança. As subclasses
herdam atributos, operações e relacionamentos da classe mãe, mas podem modificar o
material herdado, sobrescrevendo os atributos e operações ou criando novos atributos
ou operações.
A herança é representada por uma linha unindo as classes com um triângulo
indicando a superclasse. No exemplo da loja do capítulo 2 a classe Cliente é
superclasse para a classe ClienteVIP, como mostra a figura.
Figura 44- Classes Cliente e ClienteVIP com operações e atributos
A classe ClienteVIP herda da classe Cliente todos os atributos e todas as
operações como a setCGC, getNome entre outras. Entretanto, a classe ClienteVIP
modifica a classe Cliente alterando a operação getCredito. Conforme as regras no
negócio o crédito do ClienteVIP possui o dobro do crédito do Cliente. A figura mostra
as classe com as operações sobrescritas e a tabela mostra a diferença entre a
implementação das duas operações.
A implementação das operações getCredito() apresentadas acima foram foram
escritas na linguagem Java, e retornam um valor inteiro referente ao crédito do cliente,
armazenado no atributo credito. A referência à super.getCredito() na implementação da
classe ClienteVIP indica que será usada a operação getCredito() da
superclasse Cliente, que é multiplicado por dois, como manda a regra de negócio.
 
Operação getCredito do
Cliente
Operação getCredito do
ClienteVIP[4]
public int getCredito()
{
 return(credito);
}
public int getCredito ()
{
 return
(2*super.getCredito());
}
A herança é uma forma eficiente de distribuição de funcionalidades. As subclasses
dispõem de todas as funcionalidades que as superclasses oferecem. Assim a criação
de um modelo orientado a objetos é um processo de classificação, busca-se criar uma
hierarquia de classes que compartilhem as operações umas das outras.
No exemplo, é importante notar que uma classe ClienteVIP é também uma classe
Cliente, e pode ser usada sempre que uma classe cliente puder ser aplicada. Por
exemplo, a lista de clientes comporta as classes Cliente e ClienteVIP. A definição das
classes foi feita quando do carregamento das classes ao iniciar o sistema.
4.3. A técnica dos cartões CRC
Uma das maiores dificuldades enfrentadas por quem está iniciando na técnica da
orientação a objetos é encontrar as classes. É desejado sempre manter uma boa
correspondência entre o modelo conceitual e o domínio do problema, e também uma
grande estabilidade dos conceitos expressos pelas classes. No entanto, as classes são
conceitos abstratos e as vezes de difícil compreensão por parte da equipe de projeto,
ainda mais por parte de clientes que por alguma razão devem estar envolvidos nesta
fase do projeto de software. Pode-se partir do modelo de contexto, já validado, que
delimita o sistema sob o ponto de vista funcional, para tentar extrair deste modelo os
conceitos fundamentais do sistema capturados pelas classes, mas o trabalho ainda assim
não é dos mais simples.
A proposta da técnica dos cartões CRC é tornar o conceito abstrato das classes em
algo concreto e manipulável pelos analistas, tornar a identificação das classes um
processo interativo com a participação efetiva dos usuários. A idéia, proposta por
Beck e Cunnigham (1989), utiliza cartões de papel, muito utilizados em bibliotecas,
para representar as classes e organizar um trabalho em equipe para identificar e
descrever as classes de um sistema.
A modelagem CRC é uma técnica muito efetiva para identificar e validar os
requisitos dos usuários. Ele pode ir de mão em mão como os use case e os protótipos,
e conduz diretamente ao modelo de classes. O objetivo do desenvolvimento de
aplicações é resolver problemas de negócio, e não satizfazer a curiosidade
intelectual dos desenvolvedores que só querem brincar com novos brinquedos.
Trabalhe com os seus usuários, e não contra eles (Scott Ambler, 1998)
 
Figura 45- Exemplo de Cartão CRC
 
4.3.1. Histórico do cartão CRC
Os cartões CRC foram introduzidos por Kent Beck e Ward Cunningham em 1989 na
OOPSLA[5]. A técnica atraiu a atenção da comunidade por ser uma técnica de fácil
aplicação para um problema difícil, que é o de descobrir e definir classes. No livro
Rebecca Wirfs-Brock (1991) detalhou o processo dos cartões que se tornou conhecido
como a técnica de projeto “por responsabilidades”. Nancy Wilkinson (1995) publicou
sobre suas experiências com CRC na AT&T. Bellin (1997) oferece uma visão
abrangente da técnica e da sua aplicação. Mais recentemente Kent Beck (1999) refere-
se novamente à tecnica dos cartões CRC nas fases de modelagem da aplicação do seu
método XP (eXtreme Programming) de desenvolvimento rápido.
A palavra CRC[6] é uma abreviação para :Classe, Responsabilidade e Colaboração,
conceitos básicos da modelagem orientada a objetos. Os cartões de CRC são cartões de
índice muito utilizados em arquivos e bibliotecas, que são utilizados para registrar as
classes sugeridas, as coisas que elas fazem, e as relações com as outras classes.
Enquanto se escreve o nome da classe, pode-se pensar no que aquela classe deve saber
de si mesma (responsabilidade de conhecimento) e o que ela deve saber fazer
(responsabilidade de comportamento), pode-se ainda ver como a classe que se está
definindo se relaciona com as outras classes no sistema. Pode-se ver como a idéia de
encapsulamento e polimorfismo são reforçadas, ao se mover uma responsabilidade de
uma classe para outra e criar uma colaboração.
Os cartões foram criados para dar uma resposta à necessidade de documentar as
decisões do projeto colaborativo. Projetar com cartões tende a progredir a modelagem
do conhecido em direção ao desconhecido, em oposição à abordagem top-down de
decomposição usada na análise funcional. Os cartões de CRC representam
expícitamente múltiplos objetos ao mesmo tempo. Entretanto, ao contrário de
simplesmente acompanhar os detalhes da colaboração na forma de envio de mensagens,
os cartões CRC colocam o projetista no foco da motivação para colaboração
representando, potenciamente, muitas mensagens com frases em linguagem natural.
(Beck e Cunningham, 1989)
A natureza visual dos cartões de CRC é um importante catalisador para a solução do
problema. Ao mover um cartão sobre a mesa pode-se obter novas idéias da equipe de
projeto. Talvez mais importante que as tarefas básicas, os cartões ajudam na solução
dos problemas porque favorecem o trabalho em equipe.
4.3.2. Vantagens do trabalho em equipe
Necessitamos de uma ferramenta que nos ajude a resolver problemas. Um
resolvedor de problemas trabalha com alternativas, se uma delas é escolhida é porque
um número maior de associações lógicas levaram a esta escolha. Quando um grupo de
pessoas estão tentando resolver um problema, eles estão engajados em um processo que
leva a uma associação lógica. As ferramentas que suportam e facilitam este tipo de
solução de problemas são valiosas. A ferramenta é projetada para ser um catalizador
de novas idéias, a equipe deve ser ao mesmo tempo paciente e aberta a novas idéias. Se
a técnica for usada somente como um meio para anotar as idéias velhas, a chance de um
insight, de uma nova idéia está drasticamente reduzida. Quanto mais se entende como
trabalhar em equipe, mais chance de se ter de um sucesso na solução.
Estudos mostram que um grupo terá mais chance de sucesso na solução de um
problema se este grupo for treinado na lógica de solução do problema antes de ser
apresentado ao problema. As pessoas que estão concientes sobre a sua estratégia de
solução de problemas vão melhores do que aquelas que dependem de uma resposta
insconsciente ou da sorte. Isso significa que o grande poder do uso dos cartões CRC
está na equipe de desenvolvedores que não somente sabe o que eles deve fazer, mas
tambem sabem como resolver problemas complexos. Por isso, recomenda-se uma
abordagem de aplicação da técnica doscartões CRC que envolvem duas estatégias para
facilitar a solução de problemas: brainstorm e interpretação. (role play).
4.3.3. Objetivos dos cartões CRC
A técnica dos cartões CRC tem como principal objetivo o de facilitar o trabalho de
indentificação das classes de um sistema e das suas inter relações principais. Ao
mesmo tempo, a técnica serve como meio para o aprendizado da prática da modelagem
orientada a objetos e para o ensino dos conceitos envolvidos. Sendo uma técnica de
fácil utilização, ela incentiva o envolvimento dos usuários no processo de análise e
projeto dos sistemas.
Os fundamentos da técnica dos cartões CRC são os mesmos fundamentos da
orientação a objetos, e serão revisados aqui. Considera-se que os sistemas sejam
formados por objetos, categorizados em classes. As classes encapsulam atributos e
operações que caracterizam responsabilidades que os objetos devem executar para o
sistema. A análise orientada a objetos deve identificar estas classes e distribuir entre
elas as responsabilidades identificadas no levantamento de requisitos do sistema. Para
cumprir integralmente as suas responsabilidades, as classes podem contar com a ajuda
de outras classes.
A técnica dos cartões CRC procura responder às perguntas:
Quais são os componentes (Classes) do sistema ?
O que cada um deles deve fazer (Responsabilidades) ?
Como eles trabalham em conjunto (Colaboração) ?
As respostas à estas perguntas são registradas em um cartão como na figura:
Figura 46 - Estrutura de um cartão CRC
Uma classe de um sistema orientado a objetos cumpre parte das
responsabilidades do sistema, e confia em outras classes para ajudá-la a completar sua
missão no sistema. Cada classe é representada por uma cartão CRC, com o nome da
classe ocupando a linha de topo do cartão. Parte-se de requisitos do sistema,
previamente levantados, que são transformados em responsabilidades nas classes. As
responsabilidades são listadas à esquerda do cartão, e eventuais colaborações de
outras classes para aquela responsabilidade à direita.
Ao mesmo tempo que é um modo eficaz para se anotar informação sobre classes, os
cartões CRC criam um motivo para as pessoas envolvidas com o problema se
agruparem para trocar idéias. É uma técnica infomal que reduz o conflito e amplia a
socialização no desenvolvimento de software. Um dos elementos fundamentais para o
sucesso de projeto de software é o trabalho em equipe e o aprendizado ativo. Ao
contrário de ler um relatório de outra pessoa, uma equipe de CRC está sempre fazendo
algo que contribui para o modelo do sistema, isto é, eles estão sempre aprendendo
alguma coisa. (Bellin, 1997)
4.3.4. Organização para aplicação da técnica
Baseado em Bellin (1997) propõe-se uma organização para aplicação da técnica,
apresentada aqui para ser aplicada após a modelagem de contexto em um processo de
desenvolvimento de um sistema. O método é organizado nas seguintes etapas:
1. Formação da equipe de trabalho,
2. Uso de brainstorm para descrição dos requisitos do sistema,
3. Identificar classes candidatas,
4. Analisar os requisitos
a. Identificar e Distribuir as responsabilidades,
b. Caracterizar os colaboradores, e
c. Simular a dinâmica do cenário, validando o modelo.
5. Tradução dos cartões em modelo conceitual de classes
 
Figura 47 - Esquema da aplicação da técnica de CRC
4.3.5. Formação da equipe de trabalho
Uma das principais vantagens do uso dos cartões CRC é a integração dos usuários
no processo de modelagem do software. Para explorarmos esta possibilidade é
necessário criar uma equipe de trabalho composta de analistas e usuários. Uma boa
proporção é a de um analista ou desenvolvedor para cada usuário especialistas no
problema em estudo. É importante manter pequena a equipe pequena, entre 5 a 6
pessoas, o que leva a se compor a equipe com 2 a 3 analistas e 2 a 3 usuários. Um
analista deve fazer o papel de facilitador e atuar como coordenador dos trabalhos,
cuidar da agenda e da infra-estrutura para apoiar a reunião de trabalho.
Entre os analistas deve haver pelo menos um especialista em modelagem orientada a
objetos, que deve orientar os questionamentos e tomar as decisões relativas à
representação das classes. Alguem deve, durante a reunião, assumir o papel de
secretário da reunião e fazer os registros necessários.
O quadro abaixo pode ajudar na formação das equipes de modelagem.
 
Reunião CRC
Projeto:_______________
Local:_________________
Data:____/ ____/ _____
Usuário
1
Usuário
2
Usuário
3
Usuário
4
Analista
1
Analista
2
Analista
3
Especialista do Problema
Especialista em Objetos
Coordenação
Facilitador
Secretário
Agenda
Material de Apoio
Coffe break
Outros
As reuniões devem ter uma agenda definida com antecedência, e devem ser
precedidas sempre com um breve revisão da figura do cartão e da técnica que se está
aplicando, esta introdução visa garantir que todos tenham um entendimento, ao menos
superficial, sobre o método. Os cartões devem ser sempre escritos utilizando a
terminologia do usuário. Para explicar termos técnicos e pouco comuns pode-se criar
um glossário de termos que será útil para os desenvolvedores terem uma melhor
compreensão do significado dos cartões.
Durante as reuniões deve-se manter baixo o nível tecnológico, isto é, deve-se evitar
o uso de computadores e programas de modelagem. Com eles corre-se o risco de
aumentar a distância entre os usuários, que não tem familiaridade com estes meios, e os
analistas. Entretanto, o uso de protótipos e rascunhos de telas e relatórios podem ajudar
a mostrar para os usuários as possibilidades de implementação dos cartões. Na maioria
dos casos uma única reunião não será suficiente, o que dá a oportunidade para a
preparação do material nos espaços de tempo entre os encontros. Se não houverem
reuniões produtivas o desenvolvimento pode tornar-se demasiadamente lento. Portanto,
para ter uma reunião mais dinâmica e produtiva:
Organize os cartões e os protótipos entre uma reunião e outra,
Inicie a reunião revisando o que foi obtido na reunião anterior,
Encerre a reunião resumindo o que foi discutido até aquele ponto, 
Ao final, agende uma nova reunião, se necessário.
Divulgue os resultados da reunião o mais rápido possível.
4.3.6. Brainstorm para especificação do sistema
O brainstorm é uma estratégia utilizada para levantar os requisitos de projeto em
um trabaho em equipe, que tem sido usada em várias equipes de trabalho, desde
equipes de publicidade até grupos de teatro. Quando uma equipe de analistas se propõe
a trabalhar em um sistema, a troca de idéias de um modo rápido e desinibido, como
deve ser no brainstorm, pode levar a um resultado melhor do que o trabalho individual.
(Bellin; Simone, 1997)
O modelo de contexto oferece uma descrição dos objetivos dos casos de uso para
dar a partida para a modelagem conceitual. Mesmo quando não existe material para dar
início à modelagem pode-se utilizar do brainstorm com a equipe de projeto para
detalhar a descrição funcional do sistema. O brainstorm é uma técnica útil até mesmo
para a elaboração do próprio modelo de contexto.
Uma reunião para modelagem do sistema se inicia com uma descrição deste sistema.
Esta descrição pode partir da leitura do modelo de contexto, ou na inexistência deste,
do material disponível sobre o problema. Na reunião de trabalho a participação de
todos deve ser estimulada. O objetivo desta etapa do trabalho é levantar as
funcionalidades que o sistema deve possuir para atender os seus usuários. A
experiência dos especialistas é importante pois é deles o conhecimento das
necessidades reais a serem atendidas. É importante um papel de questionamento, por
parte dos analistas, para obter um modelo completo e preciso. A palavra, em uma
reunião de análise, deve ser dada a todos. Pode-se registrar tudo em um gravador, mas
como a transcrição deste material é difícil, é preferível registrar a reunião, diretamente,
em papel.
No decorrer do brainstormse contrói uma descrição do sistema na forma de uma
lista organizada de requisitos. O produto final da etapa do brainstorm é esta descrição
refinada pela análise, discussão e ponderação da equipe de projeto. O papel do
facilitador e do secretário são essenciais na elaboração da lista de requisitos, quando
alguns dos requisitos listados podem ser retirados, assim como novos requisitos podem
ser incluídos.
4.3.7. Identificar as classes candidatas
De posse da lista de requisitos obtidas pelo brainstorm, e da descrição dos casos
de uso do modelo de contexto é possível iniciar a procura pelas classes. As classes
definem um nível de abstração do problema. Como regra geral, as classes aparecem
como sujeitos nas ações listadas nos requisitos. Analisando, por exemplo, os requisitos
abaixo:
O cliente pede empréstimo; 
O pedido possui um prazo previsto para entrega.
 
identificam-se : cliente e pedido como conceitos importantes e candidatos à se
tornarem um cartão e portanto uma classe.
Essa não é a única fonte de classes. As classes podem estar nos documentos e
relatórios do sistema, nos papéis dos personagens envolvidos nas ações, assim como
em qualquer outro elemento importante que guarde alguma informação, ou que tenha
alguma ação no problema estudado.
Uma grande barreira na modelagem é a tendência em se manter preso aos mesmos
modos de ver o mundo. O analista habituado a uma abordagem funcional ou de dados
tem a tendência a continuar pensando em termos de bancos de dados e funções, e será
mais difícil ver as classes, e se utilizar das vantagens da orientação a objetos. Analisar
um conjunto qualquer de letras para identificar as palavras que podem ser formadas, é
mais fácil, as vezes, criar uma palavra nova, se as letras não formarem uma palavra
evidente. Pode-se ficar olhando as letras e não ver as palavras. Assim, para ter
sucesso no encontrar e dar nomes às classes, usando os cartões CRC, deve-se treinar o
olhar.
Deve-se ter um cuidado especial ao dar nomes para as classes. Os nomes devem ser
significativos e bem específicos, extraídos do contexto do problema. Uma boa prática é
evitar nomes genéricos demais como: sistema, usuário, controlador e operador. A
menos não ser, é claro, que estes nomes tenham um significado próprio no domínio do
problema estudado. O nome da classe e de um objeto criam um vocabulário para se
discutir o projeto. Beck e Cunnigham observam que o projeto de objetos tem mais em
comum com uma linguagem de projeto do que com a programação procedural. É
imperativo que se encontre um conjunto significativo de palavras para descrever o
objeto, um conjunto que seja consistente e representativo do ambiente de projeto.
(Beck, 89)
Os exemplos abaixo mostram como criar palavras mais representativas unindo
expressões dos diversos domínios de projeto,
Ambulatório, Enfermaria, ProntuárioMédico
 PassagemAérea, Balcão, Bagagem, Avião
FichaDePresença, RelogioDePonto
Nem sempre identificar objetos é simples e intuitivo. Particularmente em grandes
aplicações classes mais genéricas podem gerar classes mais específicas cuja seleção
adequada é um dos segredos do sucesso da boa modelagem. O uso de técnias como o
CRC podem ajudar a testar e revisar diferentes diagramas de classe durante as fases de
projeto. Nenhuma técnica, entretanto, substitui a investigação, as entrevistas e a
experiência em campo.
4.3.8. Analisar os resquisitos
Identificado um conjunto de classes candidatas, passa-se a avaliar os cenários
descritos nos requisitos. Cada cenário representa uma responsabilidade que o sistema
deve assumir, que devem ser distribuídas entre as classes, na forma de atributos e
operações. No cumprimento de uma função uma classe pode chamar outras para ajudá-
la, caracterizando assim uma colaboração entre elas.
A dinâmica desta técnica é a seguinte: escolher um cenário, imaginar e simular a
lógica do processo, distribuir as responsabilidades determinando o cartão que deve
cumprir esta responsabilidade, atualizar o cartão sempre que necessário, colaborar com
outras classes se for preciso.
4.3.9. Distribuir as responsabilidade
A responsabilidade de uma classe é uma função que o sistema exige que a classe
cumpra. Tais funções são decorrentes dos objetivos listados pelos usuários (atores),
nos requisitos do modelo de contexto.A responsabilidade é algo que uma classe sabe ou
faz. O que a classe sabe está expresso nos seus atributos, e o que a classe sabe fazer
são funções que a classe oferece ao sistema.
Responsabilidades expressão ações que identificam problemas a serem resolvidos.
As soluções existirão no interior da implementação destas ações. Uma
responsabilidade serve para levar à discussão das potenciais soluções. Quanto mais se
puder exprimir com essas frases, mais poderoso e consiso será o projeto. Aqui também
encontrar as palavras certas é um valioso uso de tempo no projeto (Beck, 1989). Em
geral, as responsabilidades são expressas por uma série de frases verbais curtas, cada
uma contendo um verbo de ação e algum objeto, como mostam os exemplos abaixo:
Fazer Pedidos
Definir o preço
ConsultarViagens
Calcular salario
Se um requisito pedir por uma responsabilidade ainda não coberta por nenhuma das
classes, pode-se adicionar a responsabilidade em uma das classes existentes ou,
excepcionalmente, criar uma nova classe para receber esta responsabilidade. Anota-se
a responsabilidade em uma linha do cartão, como já mostrado nas figuras. O número
limitado de linhas do cartão é proposital, porque se uma das classes se torma muito
complexa, durante este processo, copia-se a informação deste cartão em um outro
cartão procurando meios mais concisos de representar o que o objeto deve fazer. Se
ainda assim a classe continuar complexa, identifica-se uma nova classe para assumir as
responsabilidades, se não existir pode-se criar uma nova classe.
4.3.10. Caracterizar os colaboradores
Uma classe é incapaz de cumprir sozinha todas as responsabilidades de um sistema.
No cumprimento de uma responsabilidade que lhe foi atribuída, ela pode solicitar a
colaboração de outras classes. Isso quer dizer que em algum ponto do cumprimento da
sua função, a classe invoca uma outra responsabilidade da classe colaboradora. Este
fato é indicado no cartão se escrevendo o nome da outra classe ao lado da
responsabilidade.
A existência da colaboração é própria da natureza dos objetos, e do fato que nenhum
objeto é uma ilha isolada, mas faz parte de um sistema. Os objetos se relacionam uns
aos outros e criam as redes de colaboração. Colaboradores são os objetos para os
quais se envia mensagens para satisfazer uma determinada responsabilidade. Um objeto
pode colaborar com vários outros, e não possuir nenhum colaborador. Assim como
alguns objetos podem exigir muitos colaboradores e não colaborar com nenhum outro
objeto.
Supondo que exista uma classe Pedido, que armazenda os dados de um pedido de
compras, em resposta a um requisito do tipo:
... o preço do pedido deve ser estimado com base na lista de produtos ...
Representa-se na modelagem de um cenário foi atribuída a esta classe a
responsabilidade EstimarPreco da classe pedido, que calcula o preço estimado do
pedido com base no preço de cada produto, individualmente. Para isso, a classe Pedido
pede a colaboração da classe Produto, que possui a responsabilidade CalcularPreco,
que calcula o preço do produto com base na quantidade a ser adquirida e no preço
unitário, também presente na classe Produto. Estas relações são representadas nos
cartões CRC como mostra a figura:
Figura 48 - Exemplo de colaboração entre cartões CRC
 
Ao final da análise dos cenários, tem-se cartões ricos em responsabilidades e
colaborações. Cada cartão representa um elemento importante do sistema e a união
destes cartões representa, conceitualmente, o sistema a ser constuído. Pode-se ainda,
validar o sistema simulando a dinâmica de cada cenário, para saber se a distribuição de
funcionalidades e as colaborações são adequadase suficientes.
4.3.11. Simular a dinâmica do cenário 
Na simulação do sistema, cada participante da reunião, desenvolvedor ou cliente,
assume o papel de alguns cartões enquanto se executa o cenário. Semelhantemente a um
teatro, os projetistas assumem o papel das classes e respondem aos estímulos externos
como aquela classe responderia.
Uma boa estatégia para dar início à simulação é arranjar os cartões adequadamente
sobre a mesa. Esta visão espacial dos cartões é muito valiosa, pois ela ajuda a
identificar um projeto ainda incompleto ou ainda pouco entendido. A relação espacial
permite destacar famílias de classes, e grupos de classes que devem atuar em conjunto,
ou até mesmo a necessidade de uma colaboração maior entre duas ou mais classes.
A possibilidade que os cartões CRC oferecem de manipular as classes, antes
abstratas, e agora concretizadas nos cartões, é muito importante para o analista e,
especialmente, para os usuários. Pode-se olhar os cartões envolvidos em um cenário e
tentar ver o que eles tem em comum. Pode-se tentar rearranjar estruturas atuais em uma
nova estrutura. Os cartões CRC não irão fazer este trabalho para o analista, mas ao
focar as classes, usando a linguagem das classes eles podem ajudar a descobrir o que é
crítico para o sucesso de um sistema orientado a objetos.
Beck e Cunningham (1989) reforçam ainda a importância em não se criar objetos
para atender necessidades futuras do sistema, mas somente para atender as
necessidades do presente, expressas nos requisitos dos cenários. Isto garante que o
projeto contém apenas a quantidade de informação que o projetista apreendeu, e evita
uma complexidade prematura. Pode-se organizar o trabalho em equipe para evitar que
isto ocorra. Seleciona-se um projetista para sugerir novos cenários destinados,
especificamente, a localizar falhas, fraquezas e omissões do sistema proposto.
4.3.12. Traduzindo os cartões em classes UML
Ao final da aplicação da técnica CRC o analista tem nas mãos um conjunto de
cartões que representa conceitualmente o sistema. O destino dos cartões depende do
método adotado. Dando seqüência à abordagem de modelagem proposta aqui, os
cartões devem ser traduzidos em classes na notação da UML. O diagrama de classes, ao
final desta tradução é o modelo conceitual do sistema. Este processo é uma tradução
porque apenas a linguagem está sendo alterada, não é acrescida nenhuma nova
informação na representação do novo modelo.
A tradução segue as seguintes regras:
1. Para cada cartão cria-se uma classe,
2. O nome do cartão é o nome da classe,
3. As classes podem ter superclasses que são representadas no modelo.
4. As responsabilidades atribuídas a cada cartão são traduzidas em atributos
ou operações:
a. As responsabilidades que estão associadas ao armazenamento de uma
informação da classe são traduzidas em atributos, e
b. As responsabilidades que estão associadas a ações que a classe deve
executar para o sistema, são traduzidas em operações.
5. Havendo colaborações entre duas classes é uma indicação que pode haver
algum tipo de relacionamento entre as classes. O tipo de relacionamento irá
depender, a critério do projetista, da forma como serão implementadas as
colaborações.
· 
4.3.13. Vantagens da técnica dos cartões CRC
Uma das maiores vantagens da aplicação da técnica dos cartões CRC em projetos
de software é que com um pequeno investimento em treinamento, tem-se os especilistas
de uma área fazendo a análise e descrevendo o software e usando efetivamente o
paradigma de objetos. Esta descrição não é meramente um relato mas sim um modelo
conceitual consistente do sistema.
Uns poucos minutos de introdução é suficiente para preparar a audiência para
uma apresentação baseada em cartões. Os cartões podem ser feitos antecipadamente
ou escritos na hora. Esta última forma permite que a complexidade do projeto seja
revelada aos poucos. Os cartões estão sendo usados como meio para contar a
história do processamento. Os cartões permitem contar esta história sem o recurso
da linguagem de programação, sua sintaxe ou idioma.(Beck,89)
Resumindo, a técnica dos cartões CRC:
É um método eficiente para localizar objetos,
Favorecem ao entendimento do método orientado a objetos,
É uma ferramenta de análise e projeto usada nas fases iniciais,
Que pode ser apresentada a usuários,
Incentiva a integração com os usuários e especialistas na análise,
É simples e direta e não assusta os usuários
É barato e portável,
Pode ir de mão em mão como um protótipo e
Leva diretamente a um diagrama conceitual de classes.
 
 
4.4. Estudo de Caso: Jogo da Forca
Para exemplificar a aplicação da técnica dos cartões CRC desenvolve-se aqui o
modelo conceitual do jogo da forca. Este jogo tem a vantagem se ser bem conhecido
por todos, o que permite que qualquer um possa ser considerado um especialista do
assunto, propor e analisar as suas funcionalidades.
Segue uma breve descrição de um jogo da forca computadorizado, que serve como
um exemplo do que o analista receberia como uma primeira tentativa do cliente em
descrever seu negócio:
No jogo da forca em computador, o jogador é desafiado a descobrir as letras que
formam uma palavra secreta, escolhida automaticamente pelo computador. A cada letra
errada, sugerida pelo jogador, ele perde uma parte do corpo: cabeça, tronco e
membros, desenhada no boneco na forca. Ao se desenhar todas as partes deste boneco,
o jogador perde o jogo enforcado. Por outro lado, ao acertar todas as letras e descobrir
a palavra secreta, o jogador vence o jogo. Deseja-se desenvolver o modelo
conceitual orientado a objetos deste jogo para se construir um programa de
computador que seja executado na internet. A figura abaixo ilustra esta descrição:
Figura 49 - Esquema típico do jogo da forca.
O desenvolvimento do modelo conceitual do jogo da forca é dividido na fase de
brainstorm, na seleção de classes, e distribuição de responsabilidades entre o conjunto
de cartões. O modelo conceitual do jogo da forca, representado pelo diagrama de
classes, é obtido traduzindo-se os cartões em classes na notação da UML.
4.4.1. Modelo de Contexto
O modelo de contexto objetiva organizar em um modelo a descrição
informal apresentada anteriormente. Neste exemplo, apenas o jogador é um ator, que
possui como grande objetivo o de jogar a forca. O jogo da forca é representado por um
sistema, que interage com este ator, como mostra a figura:
Figura 50 - Representação do sistema de forca com uso de um pacote
Diagrama de Casos de Uso
O modelo de contexto do jogo da forca é representado pelo diagrama de casos de
uso e pela descrição textual de cada caso de uso. Para aumentar o detalhamento do
modelo, divide-se o objetio de jogar a forca contra o computador em dois objetivos no
sistema: iniciar um novo jogo e chutar letras para adivinhar a palavra secreta. Optou-se
por representar a lista de palavras como um ator, porque ela pode ser considerada
como um elemento imutável, externo ao sistema. Esta situação é representada pelo
diagrama:
 
Figura 51 - Diagrama de Casos de Usodo Jogo da Forca
Ator: Jogador
representa os jogadores (usuários) do sistema de jogo da forca.
Ator: Lista de Palavras
representa a lista de palavras armazenadas para alimentar o jogo. É um ator
passivo, imutável, que só fornece informações.
Casos de Uso: Novo Jogo
Objetivo principal
Um novo jogo da forca em computador,exige que se selecione uma palavra secreta
escolhida automaticamente de uma lista de palavras já existente.
Cenário de exceção
A lista de palavras não existe ou não pode ser encontrada, impedindo a
continuidade do jogo.
Caso de Uso: Chutar Letras
Objetivo principal:
O jogador chuta letras para tentar acertar a palavra secreta.
Cenário alternativo 1
A cada letra errada, ele perde uma parte do corpo do boneco. Ao completar todas
as partes do corpo do boneco o jogador perde.
Cenário alternativo 2
A cada letra certa a palavra vai se desenhandona tela. Ao descobrir todas as
letras e descobrir a palavra secreta, o jogador vence o jogo.
 
4.4.2. Modelo Conceitual
O desenvolvimento do modelo conceitual do jogo da forca segue a proposta dos
cartões CRC se divide na fase de brainstorm, na seleção de classes, e distribuição de
responsabilidades entre o conjunto de cartões CRC. Como resultado da aplicação desta
técnica, tem-se um modelo conceitual do jogo, representado pelo diagrama de classes,
que é obtido da tradução dos cartões em classes representadas pela UML.
Brainstorm
A obtenção de uma listagem das funcionalidades previstas para o jogo da forca vem
de um estudo das diversas ações executadas durante uma partida. Pode-se considerar
que o jogo da forca é uma disputa entre um jogador e uma palavra selecionada pelo seu
oponente, neste caso, o computador. Na lista de funcionalidades abaixo o computador é
representado pela classe Forca. As ações que se seguem reproduzem um jogo típico,
entre a forca e o jogador.
 O jogo da forca possui uma lista de palavras secretas armazenda,
 O jogador inicia um novo jogo,
 A forca escolhe uma palavra da lista,
 Uma Forca vazia é desenhada,
 O jogador chuta uma letra da palavra,
 O jogador deve saber as letras que já foram chutadas,
 Se a palavra possuir a letra estiver a letra é desenhada,
 Se a palavra não possuir a letra, uma parte do boneco é desenhada,
 Se a letra é a crescentada na lista de letras erradas se não estiver na
palavra,
 Quando a palavra estiver completa o jogador ganhou,
 Quando o boneco estiver completo o computador ganhou
Candidatos a classes
Uma leitura atenta das funcionalidades acima mostra que as ações são comandadas
pelos seguintes elementos:
Forca
Jogador
Palavra
Boneco
E que por isso são candidatos a classes deste sistema. Estas escolhas se
confirmarão com a distribuição das responsabilidades, realizada a seguir.
Distribuição das Responsabildiades
Cria-se um cartão para cada classe e passa-se a analisar as funcionalidades
identificadas, uma a uma:
O jogo da forca possui uma lista de palavras secretas armazenda,
Esta funcionalidade identifica que o jogo da forca possui, internamente, uma lista
de palavras que usa para desafiar o jogador. Escolhe-se a classe Palavra para ter como
responsabilidade guardar esta lista de palavras:
 O jogador inicia um novo jogo,
 A Forca escolhe uma palavra da lista
Uma Forca vazia é desenhada
A responsabilidade de iniciar um novo jogo, que é solicitada pelo jogador humano,
é atribuída à Forca, que faz a interface com o usuário e controla o início do jogo.
Iniciado o jogo, a forca seleciona, automaticamente, uma palavra da lista, e desenha a
forca vazia e o número de letras da palavra onde o jogo será desenvolvido. A palavra é
desenhada com espaços indicando as letras. Para desenhar a palavra e o boneco a
Forca usa métodos apropriados das classes Palavra e Boneco. Este métodos são
dependentes da tecnologia empregada para a interface.
O jogador chuta uma letra da palavra
A classe Forca faz a interface com o usuário recebendo a letra sugerida pelo usuário
que irá processá-la. A classe jogador tem a responsabilidade de avaliar a letra chutada
e para isso usa a classe Palavra para ajudá-la, já que só a classe Palavra conhece os
detalhes da palavra escolhida.
 
 
Figura 52 - Exemplo do início da definição do cartão Forca
A figura acima mostra o cartão da Forca até este momento do estudo. A seguir dá-se
prosseguimento ao processo de distribuição das responsabilidades:
O jogador deve saber as letras que já foram chutadas
A responsabilidade de chutar uma letra é atribuída ao Jogador, que também guarda
as letras já chutadas.
Se a palavra possuir a letra estiver a letra é desenhada
Aqui temos duas responsabilidades: a de verificar se a letra está na palavra e a
desenhar a letra, que podem ser atribuídas à palavra, já que esta possui conhecimento
das suas próprias letras.
Se a palavra não possuir a letra, uma parte do boneco é desenhada
Nesta responsabilidade vemos que quando a palavra verifica que a letra não está na
palavra ela precisa da ajuda do boneco, porque será desenhada uma parte do boneco.
Assim atribui-se uma colaboração do boneco na palavra e a responsabilidade de
desenhar uma parte para o boneco. As partes do boneco devem ser guardadas na
própria classe boneco, que deve sabe qual a parte (Cabeça, tronco ou membros que irá
desenhar em seguida)
 
 Se a letra é a crescentada na lista de letras erradas se não estiver na
palavra
A lista de palavras erradas é mantida pelo Jogador
Quando a palavra estiver completa o jogador ganhou
Quando o boneco estiver completo o computador ganhou
Aqui vemos que a classe palavra deve ter uma responsabilidade para saber se ela
está completa, assim como o boneco, que deve saber se ele está completo. Associadas
à estas responsabilidades temos a funcionalidade do jogador em ganhar ou perder,
respectivamente. Representam-se as responsabilidades de ganhar e perder no cartão da
classe Jogador, com a ajuda das classes Palavra e Boneco.
 
4.4.3. Cartões CRC
Abaixo estão os cartões CRC resultantes da distribuição de responsabilidades.
Optou-se por manter o nome das responsabilidades próximo da descrição da
funcionalidade levantada na fase de brainstorm. Posteriormente, o nome das
responsabilidades serão traduzidos em nomes de operações e atributos das classes e
podem se alterar.
 
 
 
4.4.4. Tradução dos Cartões em Classes
Para construir o modelo conceitual, utilizando a notação da UML, deve-se traduzir
cada cartão em uma classe, onde o nome do cartão será o nome da classe. Assim, para
o cartão Boneco cria-se a classe Boneco, como mostrado na figura abaixo. As
responsabilidades descritas no cartão são traduzidas em atributos e operação. Observa-
se que a responsabilidade que corresponde a guardar as partes do boneco é um atributo
(um dado) armazenado pela classe, assim cria-se o atributo parte na classe Boneco. As
outras duas responsabilidades correspondem a ações que a classe boneco tem que
executar: Verificar se o boneco está completo e Desenhar uma parte do boneco. Para
estas duas responsabilidades criam-se as operações na classe Boneco:
bonecoCompleto e desenha, respectivamente. A figura abaixo compara o cartão da
classe Boneco com a classe representada na UML. 
Analogamente, são traduzidas as classes Forca, Jogador e Palavra. Nesta são
identificadas as responsabilidades que se transformam em atributos e as que se tornam
operações. Ao dar os nomes para as operações e atributos procura-se seguir as
restrições das linguagens de programação evitando acentuação nas palavras, caracteres
especiais e espaços em branco na formação dos nomes. A tabela que se segue mostra a
correspondência entre a responsabilidade descrita no cartão e os atributos e operações
nas classes:
 
O diagrama de classes deve refletir a comunicação entre os objetos. Deve-se
observar que de posse do diagrama de classes e da especificação das classes, descrita
no verso dos cartões, é possível se construir o sistema. Como este é um sistema
simples, o modelo conceitual é quase auto-suficiente. No entanto o programador deverá
ainda tomar uma série de decisões de projeto na fase de implementação. O
programador deve decidir sobre uma série de objetos auxiliares, em como será
implementada a interface e como serão implementadas as comunicações entre as
classes. O modelo detalhado, estudado no próximo capítulo, será utilizado para definir
mais precisamente os detalhes da implementação dos sistemas. No capítulo 6 retoma-se
o jogo da forca, lá se desenvolve o modelo detalhado que conduz à implementação.
 
Figura 53 – Diagrama de Classes Conceitual do Jogo da Forca
 
 
 
 
 
5. O Modelo Detalhado
 
Este capítulo descreve técnicas para construção dos modelos orientados a
objetos. Nele são descritos, em detalhe,os seguintes diagramas da UML: classes,
seqüência, colaboração, estados, atividades, componentes e distribuição. Estes
diagramas são apresentadoscomo formas de descrever os detalhes da estrutura, da
dinâmica interna e da construção de um sistema em componentes de software.
5.1. Introdução aos modelos detalhados da UML
O desenvolvimento de sistemas de software é apoiado em visões que evoluem com
o entendimento do problema e com a aproximação da fase de construção. Este capítulo
leva o modelo do sistema ao seu nível mais alto de detalhes. Apresenta-se aqui como
criar, a partir do modelo de contexto e do modelo conceitual das classes, uma visão
mais rica em detalhes e integrada do sistema de software com os diagramas da UML.
A OMG[7] (2001) define a UML como “Uma linguagem padronizada para
especificar, visualizar, construir e documentar todos os artefatos de um sistema de
software.” É uma proposta para unificar, em torno de uma notação padronizada, as
diversas representações gráficas dos sistemas de software. A ampla aceitação da UML
pela comunidade de desenvolvedores, e pela própria indústria de software, é uma
prova da sua força e uma avaliação da sua importância.Segue um breve histórico da
evolução da notação, que é útil para compreeender o seu estágio atual de evolução.
5.1.1. Histórico da UML
Atualmente, qualquer projeto de software que decida pela orientação a objetos
como paradigma de desenvolvimento, deverá ser representado pela UML assim
encontrará apoio em um grande número de ferramentas CASE disponíveis no mercado.
A adoção de uma notação padronizada permite, entre outras vantagens, a separação
entre a análise, o design e a construção. O contingente de pessoal técnico treinado é
cada dia mais numeroso, e a capacidade de se especificar, detalhar, medir, construir e
gerenciar um projeto de software por meio dos diagramas e modelos da UML é cada
vez maior.
Mas nem sempre foi assim, nos anos 80, apesar da tecnologia a orientação a objetos
já ser bem conhecida, uma diversidade de metodologias e notações procuravam
representar os sistemas de software orientados a objetos de diferentes formas. Ao se
iniciar um novo projeto de software era preciso selecionar um método e, quase sempre
treinar uma equipe para utilizar aquela notação e poder desenvolver os modelos. A
falta de um padrão criava um problema adicional para a difusão da tecnologia de
orientação a objetos. Dentre as muitas metodologias existentes, datacaram-se o OOSE
de Jacobson (1992), o OMT de Rumbaugh (1994) e o método de Booch (1994).
Em 1993, Booch já estudava uma aproximação com o trabalho de Rumbaugh e
juntos, na empresa Rational, iniciam o esforço de unificação das duas metodologias. No
final de 1995, introduziram o conceito do UM -Unified Method - que se tornou em
seguida, após a entrada de Jacobson na equipe, na UML - Unified Modeling Language
- com a separação entre a linguagem de modelagem e o processo de desenvolvimento.
Os esforços de Booch, Rumbaugh, e Jacobson resultaram, em 1996, na emissão da
versão UML 0.9 quando os autores convidaram a comunidade em geral para opinar. A
lista de tecnologia de objetos patrocinada pela Rational, a OTUG – Object Technology
User ś Group - foi um ambiente de aprendizado colaborativo e um grande motivador da
ampla adoção atual da UML. Os subsídios da discussão pública pela internet criaram
as revisões UML 1.0, e a 1.1 que, finalmente, foi submetida e aprovada pela OMG em
1997. A UML torna-se assim a linguagem oficial para modelar sistemas orientados a
objetos, e passa a ser gerenciada pela OMG, que a incorporou na sua sistemática de
padronização e revisões.
A UML é essencialmente uma linguagem de modelagem, definida por uma meta
linguagem, isto é, a partir da UML podem ser geradas outras linguages coerentes com o
objetivo original de descrever um sistema orientado a objetos. A notação da UML é
padronizada, e deve ser assim para poder descrever com precisão cada parte do
software, de forma única e de um modo onde qualquer um, que conheça a UML, possa
ler o mesmo software. Por outro lado, o software é uma tecnologia em evolução, uma
notação que resistisse à esta evolução, estaria fadada ao insucesso. A dificuldade em
conciliar uma notação precisa, rigorosa e padronizada com uma notação que possa
evoluir com a tecnologia foram os maiores desafios enfrentados pela equipe de
desenvolvimento desta linguagem.
A UML é o resultado de um processo de convergência dos principais métodos para
desenvolvimento de sistemas orientados a objeto existentes na primeira metade da
década de 90. Cada método deu a sua contribuição para a formação da UML, sendo que
o resultado é mais preciso e mais homogêneo que as linguagens anteriores. Ela
consegue descrever os sistemas de forma mais abrangente, levando a modelagem mais
próxima da implementação. Possui elementos de expansão que permitem acomodar
novos sistemas, assim como novos elementos na modelagem.
Os objetivos inicias da UML, descritos pela OMG (2001), são:
 Fornecer aos desenvolvedores uma linguagem de modelagem visual,
pronta para o uso no desenvolvimento e comunicação de modelos ricos em
significados.
Oferecer mecanismos de extensibilidade e especialização para ampliar os
conceitos principais.
Dar suporte à especificações de projeto independentes da linguagens de
programação e do processo de desenvolvimento.
Prover uma base formal para o entendimento de uma linguagem de
modelagem
Encorajar o crescimento do mercado de ferramentas de software
orientadas a objeto.
Dar suporte aos conceitos de desenvolvimento de alto nível como
componentes, colaboração, frameworks e padrões.
Integrar as boas práticas de projeto.
A UML especifica uma linguagem de modelagem que conseguiu o consenso da
comunidade de especialistas em orientação a objetos nos conceitos chave da
modelagem. Com a UML se é capaz de atender os mais variados problemas de
modelagem atuais, de uma forma direta e econômica. Alguns problemas futuros
esperados, especialmente os relacionados com a tecnologia de componentes,
computação distribuída, frameworks e executabilidade já são abordados pela notação.
Com a UML, é possível a troca de modelos entre uma variedade de ferramentas, além
da criação de repositórios para armazenagem e troca de modelos.
A notação da UML é uma notação gráfica, onde a descrição de um software é feita
com símbolos gráficos padronizados que se relacionam formando diagramas. Cada
diagrama apresenta uma visão parcial do sistema de software, e a união dos diagramas
deve representar um único sistema de software. Os diagramas são descritos por nomes
e termos padronizados, que compõem um glossário próprio de termos que também faz
parte da UML.
5.1.2. Os diagramas da UML
Os modelos detalhados descrevem mais precisamente os fenômenos observados no
problema, assim como pemitem, encaminhar o sistema à sua implementação em uma
linguagem de programação. Algumas metodologias preferem distinguir os modelos
desenvolvidos nas diversas fases, como modelo de análise, modelo de projeto, modelo
de implementação e assim por diante. Aqui eles serão chamados apenas de modelos
detalhados, independentemente da sua finalidade.
O diagrama de classes, desenvolvido como modelo conceitual do sistema, é
insuficiente para descrever todos os detalhes do projeto. Os cartões CRC mostram que
para se ter um sistema é importante definir como as classes irão colaborar. Entretanto, a
colaboração, ainda é pouco explorada neste modelo, e precisa ser detalhada para
considerar outros fenômenos presentes no sistema, descrever mais precisamente a troca
de mensagens entre as classes, assim como para acrescentar elementos importantes da
implementação.
O diagrama de classes traduz uma visão estática, sem movimento, equivalente à uma
foto do sistema, e por isso não permite avaliar caractersísticas dinâmicas do
comportamento interno e externo da classe. Assim, é necessário desenvolver outras
visões da dinâmica do problema, para descrevê-lo com precisão. As visões dinâmicas
e estáticas do problema devem se integrar, e se complementar, para representar um
sistema passível de ser contruído.
O modelo detalhadode objetos, descrito neste capítulo, é formado pela reunião
destes diversos diagramas, que permitem observar o problema sob ângulos
particulares, e que exploram características importantes do problema estudado. As
visões utilizadas no modelo detalhado de objetos, são listadas a seguir e podem ser
organizadas como mostra a figura:
Figura 54 - Exemplo de navegação entre os diagramas da UML
 
A visão da estrutura de um modelo detalhado é dado pelo diagrama de classes. As
classes, identificadas no modelo conceitual, formam a base sobre a qual são erguidos
os componentes do sistema. As classes mostram apenas uma visão estática do sistema.
A visão dinâmica complementar é oferecida por um conjunto de diagramas de
interação entre as classes e pelo diagrama de estados. A interação entre as classes de
um sistema é mostrada pelos diagramas de seqüência e diagrama de colaboração, que
representam as mensagens trocadas entre as classes. Os diagramas de estado mostram
o ciclo de vida de uma classe, representando a sua dinâmica interna. Para serem
construídas, as classes podem ser agrupadas em componentes de software que são então
distribuídos pelos servidores. Estas situações são descritas pelos diagramas de
componentes e de distribuição.
O modelo de contexto define o comportamento externo do sistema, que é distribuído,
na modelagem conceitual, para as classes do sistema. Estas classes participam de
processos que podem ser modelados pelos diagramas de seqüência, atividades ou de
colaboração. Internamente, as classes tem seus ciclos de vida modelados pelo
diagrama de estados. Assim, o comportamento interno do sistema implementado nas
classes por suas operações, forma a base das mensagens trocadas entre as classes,
assim como implementam as transições de estado em uma classe. A coerência entre as
classes e suas operações garantem a coerência do modelo e do sistema como um todo.
 
Figura 55 - O analista e o modelo conceitual
 
Nos modelos de contexto e no modelo conceitual o analista se coloca em uma
posição de alguma distância com relação ao sistema, para não perder a visão do todo.
Já nos modelos detalhados, o analista deve se aproximar muito mais do sistema e das
suas partes para ver todos os detalhes. Estes detalhes são separados em características
estruturais, que são representadas nos diagramas de classes, características dinâmicas
que podem ser representadas nos diagramas de interação e de estado, ou características
de implementação que são representadas nos diagramas de componentes ou de
distribuição.
5.2. Diagrama de classes
O diagrama de classes, já introduzido no modelo conceitual, deve agora ser
detalhado para poder descrever com precisão o sistema a ser construído. Os sistemas
orientados a objetos organizam-se ao redor de classes de objetos, que representam
tanto os elementos do domínio do problema, incorporados ao modelo, como os
elementos propostos para a implementação da solução. O diagrama de classes
representa a planta baixa do sistema, estabelecendo uma relação entre os elementos do
problema e o código que os implementa. Para implementar um diagrama de classes é
necessário que a linguagem de programação dê pleno suporte à orientação a objetos,
como a linguagem de programação Java, que será utilizada como exemplo neste estudo.
As classes formam uma unidade que encapsula atributos e operações. Uma classe
define um conceito importante para o problema e pode se relacionar com as outras. Mas
são os objetos, instâncias das classes, que interagem nos programas, disparam
mensagens, podem até ser transmitidos em uma mensagem pela rede ou mesmo
armazendos em bancos de dados. A identificação das classes do sistema, sua
constituição e relacionamentos é a essência da modelagem orientada a objetos, e já foi
desenvolvida, em grande parte, com a modelagem conceitual no capítulo anterior. Este
capítulo detalha o diagrama de classes e todos as suas nuanças e o relaciona com os
diagramas dinâmicos e de implementação, criando uma visão detalhada do sistema de
software.
Uma classe é representada por um retângulo dividido em 3 partes onde se representa
o nome, seus atributos e suas operações. Estas partes são apresentadas nos terços do
retângulo com maior ou menor quantidade de detalhes, em função do grau de
abstração desejado ou da fase de detalhamento do modelo, como mostram os exemplos
da figura:
 
 Figura 56 - Exemplos de representação de classes
5.2.1. Nomes
Dar nomes aos componentes de um modelo, como já foi dito, é umas atividades mais
importantes da modelagem. Em um diagrama de classes devem ser escolhidos nomes
para as classes, atributos, operações e também para as relações. A escolha de um nome
adequado pode facilitar muito o entendimento do problema, enquanto uma escolha
incorreta de um nome pode tornar o modelo incompreensível. Os nomes devem ter
significado para o domínio do problema em questão, descrevendo elementos
importantes do sistema e aproximando o modelo do problema real.
As classes devem ser nomeadas com expressões substantivas breves, iniciadas por
uma letra maiúscula para que representem um nome próprio do vocabulário do
problema em estudo. O nome da classe deve ser único no âmbito do subsistema que a
contém. O nome da classe deve ser escolhido de modo a ter um significado relacionado
com a sua responsabilidade do sistema. Assim, Funcionario, Livro, CartaoDePonto e
ProntuarioMedico são nomes adequados para classes.[8]
Os atributos são nomeados da mesma forma que as classes. Com a diferença que os
atributos são iniciados por letras minúsculas e representam propriedades das classes.
São bons nomes para as classes outros substantivos associados às classes, frases
adjetivas curtas ou adjetivos substantivados que podem qualificar as classes, por
exemplo: cor, nome, baixo, tamanho, tempoDeEspera, dataDeAniversario, menorIndice
e maiorValor.
As operações indicam ações que a classe pode executar. As operações devem ser
nomeadas com nomes relativos às responsabilidades que a classe assume para o
sistema. Verbos ou frases verbais curtas são bons exemplos de operações. As
operações assim como os atributos são iniciadas por letras minúsculas, como por
exemplo: calcularValor, fazerPedido, vender, investir e comprar. Analogamente aos
atributos, a classe ou o objeto que é criado a partir dela, será o sujeito das operações
Com exceção da herança, todos os relacionamentos entre as classes de um sistema
podem ser nomeados. Os detalhes da representação de cada tipo de relacionamento são
apresentados juntamente com os adornos disponíveis para um relacionamento.
5.2.2. Visibilidade
Uma das características das classes é a capacidade de envolver em uma cápsula
atributos e operações e poder, a seu critério, ocultar estas informações de outras
classes. Para controlar quais atributos e operações de uma classe podem ser vistos fora
dela deve-se estabecer a visibilidade de cada um destes elementos. No diagrama de
classes a visibilidade que pode ser: pública, privada ou protegida, é indicada por um
símbolo na frente do nome do atributo ou da operação, como mostra a tabela.
Como uma boa prática de projeto, uma classe só deve oferecer ao sistema suas
operações públicas. Assim, oas outras classes só podem invocar as mensagens
relacionadas às operações públicas e apenas estas operações podem ser herdadas. As
operações privadas e os atributos servem para atender as necessidades internas da
classe, são visíveis por toda a classe mas não são visíveis externamente.
 
Esta boa prática de projeto evita que outras classes tenha acesso direto, e
descontrolado, aos valores dos atributos da classe. Se uma classe oferece atributos
públicos ela permite que seu estado seja alterado sem que ela possa tomar uma ação a
esse respeito. Dando acesso aos atributos unicamente por intermédio de operações de
acesso, a classe pode controlar o que ocorre quando um atributo seu se modifica
alterando, por exemplo, o seu estado.
Para dar acesso aos atributos privados sãocriadas as chamadas de operações de
acesso. Os nomes destas operações de acesso devem ser padronizados para facilitar a
sua construção por ferramentas automatizadas, e para dar um acesso padronizado por
outras classes. A tabela abaixo exemplifica as operações padrão de acesso em uma
classe de Produto mostrada na figura:
Figura 57 - Exemplo de operações de acesso
A classe Produto, do exemplo, possui os atributos privados: nome do tipo texto
(String), qtd do tipo inteiro (int) e outro chamado disponível do tipo boolean (falso ou
verdadeiro). A tabela descreve algumas operações
 
Como o atributo disponível é um atributo booleano usa-se a operação isDisponível
no lugar do getDisponível como forma padronizada de acesso. Supondo que a
disponibilidade do produto depende da quantidade do produto, podemos definir o valor
do atributo se ele está disponível ou não com base na quantidade atribuída ao Produto.
Assim o pseudocódigo do método setQtd pode ser:
metodo setQtd( pQtd:int)
 qtd <- pQtd
 se (qtd > 0)
 entao disponivel <- verdadeito
 senao disponivel <- falso
 fim do se
fim do setQtd
Assim, se os atributos qdt ou disponível forem públicos, é possível modificar os
seus valores direta e independentemente, e ter-se a quantidade zero (qtd=0) e valor
disponível ainda verdadeiro (diponivel="true"), criando uma condição inconsistente
para o produto. O parâmetro disponível é alterado alterando-se a quantidade, por esta
razão, não faz sentido ter-se a operação setDisponivel. Confirma-se assim a boa prática
de adotar usar métodos de acesso públicos e atributos privados. Uma exceção a esta
regra são as constantes globais, que por serem constantes serão lidas e não podem ser
modificadas, não necessitando de um método de acesso. Outra operação muito útil é a
operação que gera uma seqüência de caracteres para testar a classe e apresentado o seu
conteúdo impresso, por exemplo. Cria-se assim a operação toString() que retorna um
texto que descreve o objeto.
5.2.3. Instanciamento de Classes em Objetos
Uma classe pode ser instanciada em um objeto, como mostra a figura. Com os
objetos pode-se construir um diagrama de objetos, relacionando os objetos como se
relacionam as classes que os formam.
 
Figura 58 - Exemplo de um objeto
Para instanciar o produto lampada, por exemplo, deve-se criar um objeto com base
na classe EquipEletrico, que é traduzido em código por métodos chamados de
construtores:
lampada= new EquipEletrico(110, 5.00)
Neste exemplo, escrito em Java, o método EquipEletrico(tensao, valor) é um
método constutor da classe EquipEletrico, e é um executado em associação ao comando
new para criar o objeto livro com base na classe.
 
5.2.4. Classes concretas, abstratas e interfaces
As classes são instanciadas em objetos, dos quais se pode invocar as operações
públicas na forma de mensagens. No entanto, nem todas as classes permitem a sua
instanciação direta em objetos, as classes que permitem a sua instanciação em objetos
são chamadas classes concretas. Em muitos casos, pode ser necessária a criação de
classes que apenas descrevem conceitos abstratos e que não são transformados em
objetos diretamente, as chamadas de classes abstratas. Estas classes devem ser
herdadas por outras classes concretas, que irão implementar os conceitos abstratos
criando uma classe concreta que pode ser instanciada.
As classes abstratas são muito úteis nas primeiras etapas da modelagem, na fase da
modelagem conceitual e na criação de famílias de classes reutilizáveis. As classes
abstratas não podem ser instanciadas porque alguns de seus métodos são abstratos, isto
é, existe ainda algo na classe abstrata que não foi definido. Um método abstrato é um
método do qual se conhece apenas a sua chamada, a sua assinatura, e que ainda não foi
construído. Isto é, uma classe abstrata tem pelo menos um dos métodos da classe apenas
declarado, e ainda não existe sua implementação concreta para ele. Nas primeiras fases
da modelagem de um sistema é possível que alguns métodos de uma classe ainda não
tenham sido completamente definidos o que a caracterizaria como abstrata.
A assinatura de uma operação ou método é o nome da operação e seu conjunto de
parâmetros. Um método abstrato não possui o corpo do método onde se encontra o
algoritmo que o implementa. Uma classe abstrata pode possuir métodos concretos, mas
deve ter pelo menos um método abstrato. Para uma classe abstrada se tornar concreta
ela deve ser herdada por outra que irá sobrescrever os métodos abstratos com métodos
concretos.
A UML representa uma classe abstrata com linhas pontilhadas. No exemplo a seguir,
tem-se a classe abstrata PessoaJuridica representando o conceito de pessoa jurídica,
que é implementado pelas classes concretas de empresa cliente (EmpresaCliente) e de
empresa fornecedora (EmpresaFornecedora). O método criarEmpresa é um método
abstrato de deve ser implementado pelas classes filhas para que estas sejam concretas.
Figura 59 - Exemplo de classe abstrata
Um tipo de classe abstrata muito útil na modelagem é a interface. Uma interface é
uma classe formada apenas por métodos abstratos. Ela serve para se definir uma forma
de comunicação entre as classes de um modelo, porque descreve apenas um conjunto de
mensagens que as classes que a implementam devem obedecer. Ela define um padrão de
comunicação, e se posiciona entre classes, por isso é chamada de interface.
No exemplo abaixo temos a definição de uma Obra em uma biblioteca, que é a
definição abstrata de um conceito que serve para se comunicar com o sistema da
biblioteca. A herança de uma interface é chamada de implementação porque a classe
concreta devem implementar todos os métodos da classe de interface. Esta herança é
representada também por uma linha pontilhada porque não é uma herança verdadeira,
uma vez que não há métodos concretos para serem herdados. A “herança” em uma
interface é uma implementação. O uso de interfaces é bastante difundido na criação de
classes reutilizáveis e no desenvolvimento de componentes de software portáveis.
Figura 60 - Exemplo de Interface e Implementação
5.2.5. Adorno dos relacionamentos
Os relacionamentos podem receber elementos gráficos para descrever, com maior
precisão, a ligação existente entre duas classes. A base para o relacionamento entre
duas classes é a associação que representa uma união conceitual entre as duas classes.
Na associação pode-se incluir uma seta para aumentar a navegabilidade da associação,
um losango para indicar uma agregação e uma multiplicidade nas extremidades.
Uma seta na associação mostra a navegação do relacionamento, ou seja, a direção
do relacionamento identificando quem é a classe dependente (origem da seta) e quem é
a classe independente (ponta da seta). Um losango em uma das extremidades da seta
transforma uma relação em uma composição, istop é, transforma a associação em um
relacionamento de agragação todo-parte, onde o losando identifica a classe que é o
todo. Uma associação pode ter um nome indicando o tipo de relacionamento que existe
entre as classes. O nome mostra qual é o conceito que une as classes. Estes adornos
podem ser observados no exemplo abaixo, onde uma empresa possui uma série de
produtos que são as suas vendas.
Figura 61 - Exemplo de adornos em relacionamento
O adorno mais importante em um relacionamento é a multiplicidade da relação. Ela
descreve quantos objetos participam desta relação e é indicada por um símbolo nas
extremidades da relação. O exemplo da figura mostra que uma empresa realiza vendas
de muitos (*) produtos, nesta relação a navegação indica que é a empresa quem vende
os produtos. A tabela abaixo mostra os símbolos utilizados na representação.
 
Em um sistema esta relação vai indicar que cada um dos objetos que forem
instanciados a partir da classe Empresa poderão ter um vínculo com vários objetos da
classe Produto. O nome deste vínculo é vendas. Na fase de implementação este
relacionamento pode, por exemplo, ser traduzidoem um vetor de produtos criado na
classe Empresa. A composição indica ainda a existência dos produtos destas vendas
(partes) está condicionada à existência da classe Empresa, o todo na relação.
Os vínculos entre as classe formam os caminhos pelos quais são enviadas as
mensagens que criam a dinâmica de um sistema orientado a objetos. Supondo-se, no
exemplo, que os objetos da classe Produto tenham um método público getPreco(), que
informa o preço de cada produto, é possivel aos objetos da classe Empresa perguntar o
preço de um produto do vetor de vendas com a mensagem:
 
vendas[i].getPreco();
 
que informaria o preço do produto de índice i do vetor. A modelagem da troca de
mensagens entre os objetos é modelado pelos diagramas de interação, que são
estudados a seguir.
5.3. Diagramas de Interação
As mensagens formam a base da dinâmica de um sistema orientado a objetos. A
partir da modelagem conceitual procurou-se identificar e representar as
responsabilidades das classes na forma de mensagens que a classe seria capaz de
responder. Os diagramas de interação objetivam descrever, de maneira mais detalhada,
a troca de mensagens que ocorre entre os objetos de um sistema.
Para poder compreender claramente o conceito de mensagens é importante rever
alguns termos que serão utilizados amplamente nesta seção e nas seguintes. Um sistema
é constituído por um conjunto de classes, que dividem entre si uma série de
funcionalidades implementadas em métodos e atributos. A integração destas
funcionalidades garante o cumprimento da totalidade dos objetivos previstos para o
sistema orientado a objetos que foram levantados das descrições dos casos de uso no
modelo de contexto. No modelo de contexto obseva-se também que são os atores a real
origem das mensagens, uma vez que as classes respondem a estímulos vindos dos
objetivos dos atores. Na modelagem conceitual ficou claro que uma classe isoalada é
incapaz de atender à totalidade de funcionalidades existentes em um sistem, e para isso
depende das funcionalidades das outras classes do sistema. Para utilizar uma
funcionalidade do objeto de uma classe envia-se uma mensagem para ele, que é
implementada em uma operação pública do objeto de destino. Assim, a operação de um
sistema orientado a objetos se traduz em uma intensa troca de mensagens entre os
objetos, estimulados por eventos externos vindos dos atores do sistema.
Os objetos que participam da interação formam um contexto, que é a reunião dos
objetos e dos vínculos que unem os participantes da interação. A figura, que representa
uma interação, esquematiza os conceitos de vínculo, mensagem e contexto e suas
relações :
Figura 62 - Componentes de uma interação
A colaboração entre objetos, para atingir um determinado objetivo, é realizada pela
requisição de um serviço que um objeto necessita de outro objeto, que está capacitado a
prestar este serviço. Uma mensagem geralmente é iniciada por um ator em um objteo.
Este estímulo pode dar origem à outra mensagem, e a esta por sua vez a outra,
seqüencialmente, até que o objetivo inicial seja cumprido. A modelagem dinâmica das
interações entre as classes é feita na UML por um conjunto de dois diagramas chamados
de diagramas de interação:
Diagramas de Seqüência
Diagrama de Colaboração
O diagrama de seqüência descreve a organização das mensagens trocadas entre
objetos no tempo em um cenário de uso do sistema. É sabido que a colaboração entre
os objetos se dá entre objetos que se relacionam, e principalmente, por meio destes
relacionamentos. O diagrama de seqüência não mostra este relacionamento. Para
descrever a troca de mensagens que ocorre nos relacionamentos entre os objetos usa-se
o diagrama de colaboração. Na modelagem das interações o olhar do modelador deve
estar suficientemente distante das classes para não perceber os detalhes dos objetos,
mas próximo o bastante para perceber as mensagens entre eles. O colaboração e a
seqüência de mensagens representam a mesma informação sobre o sistema, sendo
possível traçar um diagrama a partir do outro.
5.3.1. Mensagens
As mensagens são instâncias do comportamento dinâmico externado pelos objetos.
Elas surgem, quase naturalmente, ao se analisar um caso de uso ou, ao se projetar a
distribuição de responsabilidades de um problema entre os objetos de um sistema.
Quando um objeto, o emissor, envia uma mensagem para outro objeto, o destinatário,
ele está solicitando que o destinatário execute uma operação da sua coleção.
Estabelece-se, a priori, que o objeto que recebe a mensagem é capaz de atender esta
solicitação, devendo possuir uma operação pública preparada para isto.
São igualmente consideradas como mensagens os estímulos externos recebidos pelo
sistema. Um usuário, ao solicitar uma ação de um sistema, nada mais está fazendo do
que emitir uma mensagem a um objeto deste sistema. Uma mensagem tem a mesma
estrutura de uma operação e é, essencialmente, uma instância desta operação. Como as
operações, uma mensagem possui um nome, parâmetros e um valor de retorno. O
retorno é a resposta da mensagem e está implícito na maioria das mensagens. Se um
objeto faz uma pergunta é porque, provavelmente, espera uma resposta. No entanto,
podem existir mensagens assínronas, que não aguardam a resposta, e mensagens como a
emissão de sinais, que não tem um retorno implícito. A tabela mostra os diversos tipos
de mensagens:
 
5.3.2. Diagrama de Seqüência
Os diagramas de seqüência descrevem o comportamento dos objetos do sistema,
que se relacionam pela troca de mensagens em interações seqüencializadas no tempo.
Cada diagrama mostra um cenário, isto é, um conjunto de mensagens, ordenadas no
tempo, com um determinado objetivo. Assim, para a elaborar um diagrama de
seqüência é importante que os objetivos do sistema já tenham sido levantados pela
modelagem de contexto, e que se encontrem descritos nos cenários dos casos de uso.
Por exemplo, o caso de uso Emitir fatura, abaixo, pode ser um objetivo do gerente
de contas de uma empresa, ao automatizar o seu sistema de vendas:
Figura 63 - Exemplo de um Caso de Uso
A descrição do caso de uso Emitir Fatura, neste sistema poderia ser: 
A fatura é emitida com a soma dos preços dos itens do pedido e endereçada ao
cliente.
Na visão de uma troca de mensagens entre os objetos: fatura, pedido, item e cliente,
a descrição deste caso de uso fica:
A pedido do Gerente de Contas, a fatura inicia a sua emissão perguntando ao
pedido quais são os itens e segue enviando uma mensagem aos itens da fatura,
perguntando qual o seu preço unitário, uma informação que é própria de cada item.
A seguir, a fatura pergunta ao cliente qual o seu endereço e, finalmente, retorna ao
gerente para a aprovação.
Este processo é representado pelo diagrama de seqüência abaixo
 
Figura 64 - Exemplo de Diagrama de Seqüência
Enquanto o diagrama de casos de uso mostra a visão funcional, o de classes
apresenta uma visão estática da estrutura das operações, já o diagrama de seqüência
oferece uma visão dinâmica, onde a presença da variável tempo pode ser facilmente
observada. O tempo corre de cima para baixo no diagrama de seqüência, o que quer
dizer que os eventos inferiores ocorrem após os eventos superiores no diagrama. As
linhas verticais representam os objetos e as horizontais as mensagens trocadas entre
eles. O diagrama de seqüência é o diagrama ideal para especificações de sistemas de 
tempo real, pois o tempo aparece de forma explícita e as mensagens podem ter tempos e
intervalos bem definidos.
Algumas recomendações são úteis para se elaborar um diagrama de seqüência mais
claro e preciso. É comum, por exemplo, que ao lado das mensagens se tenha uma
descrição textual do processo, com notas explicativas. É também comum que um ator
inicie o diagrama, porque como o diagrama se propõe a descrever a seqüência de
mensagens que leva a um objetivo, é de se esperar que a primeira mensagem seja
aquela que solicita este objetivo ao sistema, normalmente, partindo de um ator.
Não é semprenecessário representar no diagrama de seqüência a resposta às
mensagens, porque elas existem implicitamente. Entretanto, muitas vezes trata-se de
mensagens assíncronas e o retorno só virá após outras mensagens terem sido
executadas. Dai, é importante identificar quando isso ocorre usando, explicitamente, a
mensagem de retorno. As mensagens de retorno são representadas no diagrama com
setas tracejadas, ao contrário das outras mensagens que são linhas contínuas.
Uma outra caracaterística do diagrama de seqüência é a capacidade de representar a
linha da vida dos objetos que mantem o foco da ação a cada momento. Esta anotação é
feita tornando a linha vertical que representa objeto mais espessa, quando este está em
foco no processamento. O foco ocorre entre o recebimento de uma mensagem e o
respectivo retorno. Fora de foco o objeto poderia estar fora da memória do
processador, porque não participa, naquele momento do processamento.
A figura que se segue mostra um diagrama com o foco de controle dos objetos para
exemplificar este recurso. O gerente solicita a emissão de uma fatura que mantém-se em
foco enquanto solicita aos pedido a lista de Itens e para cada item da lista o seu preco,
e finalmente o endereço ao cliente da fatura. Terminada esta tarefa a fatura retorna ao
gerente que a aprova.
Figura 65 - Exemplo do diagrama de seqüência do sistema da loja
5.3.3. Diagrama de Colaboração
Analogamente aos diagramas de seqüência, os diagramas de colaboração
representam as interações entre objetos na forma de troca de mensagens. A diferença
entre os dois diagramas é que o diagrama de seqüência não mostra a estrutura de
vínculos entre os objetos que dão apoio à comunicação, enquanto o diagrama de
colaboração mostra os vínculos entre as classes, pelos quais fluem as mensagens. Outra
diferença está no fato que no diagrama de colaboração o eixo dos tempos não é
apresentado explicitamente. Estas pequenas diferenças não impedem que se faça uma
transformação direta do diagrama de seqüência no diagrama de colaboração. A figura
abaixo mostra o diagrama de colaboração referente ao processo de emissão de fatura,
descrito no item anterior.
Os nomes das mensagens, assim como no diagrama de seqüência devem ser bem
escolhidos para refletir as operações presentes na classe de destino. Uma seta (à)
associada à mensagem facilita a leitura e indica a sua direção. As mensagens, no
diagrama de colaboração, podem ser numeradas, o que dá ao diagrama uma orden na
seqüência das mensagens no tempo, refletindo a ordenação apresentada no diagrama de
seqüência. O diagrama de colaboração pode ser utilizado como uma opção ao diagrama
de seqüência.
Figura 66 - Exemplo de diagrama de colaboração
A existência de um vínculo entre os objetos do diagrama de colaboração indica uma
possibilidade de um relacionamento, mas, necessariamente, não o representa. Os
vínculos servem de meio para que as mensagens fluam e para a navegabilidade no
diagrama. Havendo um vínculo as classes podem colaborar, porque há um caminho por
onde a mensagem pode ser enviada.Os vínculos entre os objetos podem ser dos tipos:
Concluindo, os diagramas de interação representam a visão da dinâmica presente
entre as classes de um sistema. Eles se caracterizam por descrever uma troca intensa de
mensagens, seqüencializadas no tempo, relativas a um objetivo do sistema. Enquanto no
diagrama de seqüência o eixo dos tempos está presente, não está representada a
estrutura das classes. Já no diagrama de colaboração encontra-se a estrutura, mas não
se encontra o eixo dos tempos. Ao final da elaboração dos diagramas de interação, tem-
se representada nas mensagens, as operações necessárias às classes para cumprir todos
as responsabilidades do sistema. As operações são descobertas porque as mensagens
são instâncias das operações.
Tendo modelado todos os cenários previstos no modelo de contexto para um
sistema, as classes devem ter recebido todos as operações necessárias para responder
às mensagens trocadas no desenvolvimento dos cenários. Resta agora verificar se
internamente as classes possuem a dinâmica e coerência necessária, papel este
desempenhado pelo diagrama de estados.
 
5.4. Diagrama de Estados
A descrição da dinâmica interna de uma classe é feita pelo diagrama de estados, ele
reflete o ciclo de vida dos objetos da classe, desde o momento em que este objeto é
criado até o seu término quando ele não é mais utilizado pelo sistema, passando por
todas as situações em que o objeto poderia se encontrar. Cada classe do sistema é
modelada por uma máquina de estados finita, onde o olhar do modelador deve se
posicionar bem próximo aos mecanismos internos da classe, dentro até dos limites da
própria classe. A proximidade deve ser o suficiente para poder observar, isoladamente,
cada detalhe interno dos estados e das suas transições.
O diagrama de estados representa a dinâmica interna de uma classe como sendo
formada por estados e eventos. Estados caracterizam condições, situações, onde o
objeto daquela classe pode ser encontrado. Eventos são ações que provocam a
mudança nestas condições. O estado é uma atividade da classe de caráter lento (estado
de ação), e às vezes até estático (estado de espera). Por ter este caráter lento, pode ser
interrompido por um evento. O evento, por sua vez, retrata uma atividade rápida e que
não pode ser interrompida, uma vez iniciado irá levar, necessáriamente, ao novo
estado. Sempre ocorre um evento entre dois estados, assim como um estado possui pelo
menos um evento associado.
Figura 67 - Estrutura de uma transição de estados
 
5.4.1. Evento
Um evento na dinâmica de uma classe está associado às mensagens que a classe
recebe, e consequentemente, às suas operações internas. São as operações das classes
que permitem a mudança das suas características internas, ou seja, são as operações
que provocam as alterações no estado.
A simbologia adotada pela UML para dar nome a um evento é:
evento[condição]/ação
onde :
 
A condição de disparo é uma expressão booleana que quando verdadeira permite o
disparo do evento. A expressão é avaliada apenas na ocorrência do evento e permite
que um mesmo evento provoque diferentes mudanças de estado, conforme as diferentes
condições de disparo a ele associadas. No exemplo que se segue analisa-se o evento
retirarMaterial da classe itemEstoque, que simula um possível sistema para controle de
estoque de materiais.
Figura 68 - Diagrama de Classes do Exemplo
Supondo que o itemEstoque esteja na sua condição de estoqueNormal, isto é, a
quantidade de itens (qtd) está acima do estoque mínimo (estoqueMinimo), a ocorrência
do evento retirarMaterial pode provocar a mudança para a condição estoque baixo, se
qtd, variável que controla a quantidade de material, ficar inferior ao estoqueMínimo.
Caso contrário o itemEstoque ainda é mantido no estado de estoqueNormal.
Pode-se associar ações com o disparo de eventos, estas ações são mensagens
enviadas pela classe onde ocorre o evento para outras classes que irão provocar novas
mudanças de estados. Esta reação em cadeia que ocorre nas classes é a operação típica
de um sistema orientado a objetos. No exemplo, na ocorrência da mudança de estado de
estoqueNormal para o estoqueBaixo é diparada uma ação, na forma da mensagem emitir
para o objeto comprador da classe Compras, passando como parâmetro a variável
qtdReposicao, que indica a quantidade que deve ser reposta sempre que o estoque fica
abaixo do mínimo. A figura mostra o diagrama de estado que descreve estes processos:
Figura 69 - Exemplo de um diagrama de estado
5.4.2. Estados
Um estado é uma situação em que um objeto pode se encontrar no decorrer da seu
ciclo de vida. Esta situação pode ser caracterizada por um conjunto de valores dos
atributos, isto é, analisando os valores dos atributos deve ser possível dizer qual é o
estado da classe. Existem diferentes tipos de estado, que possuem diferentes
representações segundo a UML. A tabela abaixo mostra estasrepresentações que são
descritas a seguir:
 
O estado inicial e estado final representam a situação da classe antes do início e
após o término do seu ciclo de vida. O evento que parte de um estado inicial é um
evento de criação (Construtor) de uma classe, assim como o evento que leva a um
estado final é um evento de extinção da classe (Destrutor).
O estado de espera e o estado de ação são estados em que a classe podem se
encontrar e diferem pela ação que a classes pode estar executando nesta.
O estado de decisão é um estado que é utilizado para definir uma transição com
base em uma condição. A diferença entre um estado de decisão e uma condição de
disparo associada a um evento é, que no estado de decisão, a condição é avaliada antes
da ocorrência de um evento, e se executa uma transição em decorrência apenas desta
decisão. Na condição de disparo a condição é avaliada apenas quando da ocorrência
do evento, e apenas condiciona uma transição, não provoca a transição.
O estado de sincronismo permite a paralelização ou o sincronismo de eventos. É
um estado auxiliar na construção de diagramas de estado porque permite que um mesmo
evento seja paralelizado em outros eventos, que sob novas condições de disparo, pode
provocar outras mudanças de estado e ações. De outro lado o estado de sincronismo
pode sincronizar dois ou mais eventos. Os eventos chegam ao estado de sincronismo de
forma assíncrona, e provocam um outro evento agora síncrono. No exemplo que se
segue , o eventoSaída só ocorre quando ocorrerem os eventos eventoA e eventoB:
 
Figura 70 - Exemplo de estados de sincronismo
5.4.3. Superestados
Os superestados representam o agrupamento de estados e eventos associados a
eles. O agrupamento, além de facilitar o entendimento do diagrama, identifica grupos de
eventos que possuem um comportamento em comum. Um evento que parte ou age sobre
um superestado, representa um evento que parte ou chega a cada um dos estados do seu
interior em particular.
A integração de superestados, estados de sicronismo e decisão permite a criação de
transições complexas e permite representar um sem número de máquinas de estado. Um
superestado facilita o entendimento do diagrama de estados porque permite estruturar o
diagrama em diagramas menores.
Figura 71 - Exemplo de superestado
5.4.4. Eventos e operações, estados e atributos
Enquanto os eventos estão associados às operações que uma classe pode executar,
os estados estão associados aos valores que os atributos assumem. Um estado de uma
classe pode ser preservado, e até armazenado, pela definição, e armazenamento, dos
valores dos atributos, assim como a mudança de um valor em um atributo pode
provocar a mudança de um estado da classe. 
É comum, em muitos casos, definir um atributo chamado estado, com a
responsabilidade de indicar o estado atual da classe. Esta prática deve assegurar,
entretanto, que a mudança do valor deste atributo acompanha fielmente a mudança de
estados da classe. A inobservância deste acompanhamento pode provocar situações
incoerente, onde o atributo estado indica um estado e a classe está efetivamente em
outro, com conseqüências imprevisíveis para a operação do sistema. Uma outra
possibilidade de implementação é criar uma operação getEstado, que devolve o estado
da classe consultando uma série de outras operações e atributos.
Os eventos, internamente às classes, assim como as mensagens, externamente às
classes, são considerados instâncias das operações, isto é, uma operação pode ser
utilizada em diversos eventos e mensagens, simplesmente alterando os parêmetros ou a
condição de disparo. Co já foi visto anteriormente, uma boa prática de projeto é evitar
que as classes alterem diretamente atributos de outras classes. Esta providência evita
que a classe perca o controle do seu estado. Fazendo com que toda mudança de atributo
seja feita por uma operação é possível se controlar os estados, as mensagens que
devem ser enviadas e os próprios atributos.
5.4.5. Diagrama de estado de uma interface
Uma aplicação importante dos diagramas de estado pode ser encontrada na
descrição da operação das GUI[9] interfaces gráficas dos programas. Uma interface
gráfica é, em geral uma classe da camada de apresentação do sistema que deve receber
os eventos do usuário externo. Em princípio, o usuário é livre para interagir com a
interface acionando qualquer tipo de evento, a qualquer instante. Esta liberdade pode,
se não for devidamente controlada, gerar situações perigosas para a integridade de uma
aplicação. Operações delicadas como as de excluir um dado, criar um registro ou
transmitir uma informação, devem ser cercadas de condições que as restringam. Criar
um diagrama de estados da interface ajuda a definir os eventos e estados possíveis na
interface e limita as condições de risco.
O exemplo que se segue é uma interface simples, que permite a edição do campos
Parâmetro e Valor. A interface tem, em resumo dois estados: o estado onde se edita os
campos, e um estado onde estes campos são gravados. O diagrama de estado da
interface mostra as possíveis transições de estado presentes nesta interface: a limpeza,
a gravação e a saída da interface. Os eventos gravar, limpar e sair estão associados aos
botões da interface, e aos eventos que o usuário provoca ao clicá-los.
 
Figura 72 - Modelagem dos estados da interface 
(a) exemplo da interface e (b) diagrama de estados correspondente
Analisando este diagrama pode-se incorporar restrições como a de impedir a
gravação se os campos não forem preenchidos, alterando o evento gravar com uma
condição de disparo expressa pelo pseudocódigo 
gravar[(parametro<>nulo) e (valor<>nulo)]
que limita a gravação quando um dos campos estiver nulo.
 
5.5. Diagrama de Atividades
A dinâmica de um sistema pode ser representada internamente à uma classe pelo
diagrama de estados, e externamente, entre as classes pelo diagrama de seqüência. A
UML oferece ainda, no diagrama de atividades, uma outra alternativa que combina as
mensagens externas e internas às classes. O diagrama de atividades mostra uma
seqüência de estados e evento, muito semelhante à de um fluxograma, e se aplica na
descrição de um processo que transcende a uma classe, e envolvendo estados de outras
classes.
O diagrama de atividades é uma alternativa para representar um processo descrito
por um caso de uso. Para isso o diagrama de atividades dispõe dos mesmos elementos
dos diagramas de estado: eventos e estados, mas que não se restringem a um único
objeto.
Como exemplo de uso do diagrama de atividades pode-se desenvolver o diagrama
de atividades da operação de vendas do sistema da loja, apresentado no capítulo 2.
Neste exemplo o caixa deve entrar com o código do produto , o CGC do cliente e o
número de parcelas para verificar se a venda está aprovada ou não. O diagrama de
atividades abaixo mostra a seqüência de comandos que executam estas operações:
 
Figura 73 - Exemplo de um diagrama de atividades
 
5.5.1. Trilhas de Responsabilidades
O diagrama de atividades pode ser organizado para agrupar os estados relativos a
um objeto em uma mesma vertical. Assim, cria-se para cada objeto as chamadas raias
de responsabilidade (swimlanes). A idéia é agupar os estados relativos aos objeto de
uma classe em verticais. Desta forma o diagrama de atividades permite mostrar a
responsabilidade de objeto e criar uma relação entre o diagrama de atividades com o
diagrama de classes.
É interessante observar que associando os estados de um objeto em uma vertica, os
eventos que partem desta vertical para outra vertica são equivalentes às mensagens em
um diagrama de seqüência. 
Em nosso exemplo, pode-se agrupar os estados mostrados na execução da operação
de verificação de vendas no objetos do POS, Loja, cliente e produto. Deve-se observar,
comparando a próxima figura com a figura anterior, que os estados são os mesmos, mas
a organização permite identificar, claramente, a responsabilidade de cada objetono
processo.
 
Figura 74 - Exemplo das atiividades com as trilhas de responsabilidade
5.6. Diagramas de Implementação
Os diagramas de implementação ajudam os analistas no projeto da implementação
do sistema. Nesta fase são definidos os componentes de software e a sua distribuição
entre os processadores e servidores. Para a elaboração dos diagramas de
implementação, o projetista deve se posicionar a uma distância tal do sistema, de modo
a deixar de lado os detalhes construtivos da classes e observar apenas o conjunto do
componente e os servidores. 
 
Figura 75 - O analista vê as classes e componentes de longe
A representação da implementação na UML é realizada com dois diagramas:
Diagramas de Componentes
Diagramas de Distribuição
que serão detalhados a seguir.
 
5.6.1. Diagrama de Componentes
Componentes são unidades que armazenam software. A idéia é agrupar em uma
unidade uma parcela do código do software para facilitar a integração para formação
do sistema. Os componentes podem ser associados aos arquivos onde os códigos
podem residir. Os códigos fonte ou códigos executáveis podem ser agrupados em
componentes. O critério para criação de um componente pode ser as necessidades da
linguagem de programação, ou o compilador, mas também pode-se criar componentes
de software para atender os requisitos de distribuição do projeto e de reutilização.
Um dos critérios usado para projetar um componente é otimizar a performance do
sistema . O componente de software é a unidade que é utilizada para se distribuir o
processamento do sistema. O uso de diferentes processadores pode aumentar a
performance total, uma vez que é possível utilizar, mais adequadamente, o poder de
processamento distribuído em uma rede de computadores. O projeto de distribuição das
classes em componentes objetiva transferir para os componentes as relações presentes
nas classe de modo a balancear a comunicação presente nas classes e transferida para
os componentes. Um balanceamento adequado das comunicações entre os componetes
promove o balanceamento da comunicação entre os processadores na rede, e com isso é
possível maximizar o desempenho total do sistema.
Outro critério para se projetar os componentes é a reutilização. Os componentes
são unidades que podem ser armazenadas e reaproveitadas em vários projetos. Este
reaproveitamento pode ser maximizado no projeto de componentes, isolando os
elementos de um componente de modo a que seja mantido o encapsulamento e uma
interface pública padronizada. O sistema é integrado pela união de componentes nos
processadores.
Um componente é representado, na UML, pelo símbolo apresentado na figura. A
figura representa o encapulamento pelo retângulo com uma interface pública,
identificad pelos símbolos na borda do retângulo:
 
Figura 76 - Notação de um componente
Um componente é formado por um conjunto de classes relacionadas. A intensão é
isolar o grupo de classes que possam ser reutilizadas. Assim, o componente se
comporta como no caso do encapsulamento de um objeto. O componente depende das
classes que o forma. Esta dependência pode ser mostrada em um diagrama. A notação
indica a composição de um componente em dependência das classes que o compõe,
como mostra a figura:
Figura 77 - Um componente e as classes que o compõe
Definidos os componentes, pode-se criar um diagrama de componentes descrevendo
como eles dependem entre si. A dependência também é a principal relação entre os
componentes, como mostrado a seguir:
 
Figura 78 - Exemplo de um Diagrama de Componentes
O diagrama de componentes representa a configuração do software, isto é, como as
diversas partes do sistema se relaciona. Cada parte, identificada por um componente, é
ligada às demais formando o sistema. Com o diagrama de componentes o integrador é
capaz de criar uma versão do sistema de software. Para concluir a implementação é
necessário ainda a distribuição dos componentes pelos servidores, que é o assunto dos
diagramas de distribuição, apresentados a seguir:
 
5.6.2. Diagramas de Distribuição
Os diagramas de distribuição descrevem a configuração do hardware, e a integração
dele com o sofware. Os equipamentos são representados por nós que podem estar
associados tanto aos processadores como aos servidores reais ou virtuais disponíveis
para a aplicação. Os nós se relacionam entre si formando uma rede de processamento
de dados. As ligações entre os nós representam as associações físicas e lógicas
existentes entre os equipamentos e servidores.
A UML representa de um nó é a representação de um cubo, que caracteriza um
equipamento processador, e seu tipo.
 
Figura 79 - Exemplo da Notação de um nó
Os nós recebem os componentes de software, em um diagrama que descreve a
configuração do sistema, mostrando a dependência do com aos componetes que a ele
são destinados.
 
Figura 80 - Composição de um servidor com seus componentes
O diagramas de distribuição representam a ponte que liga o software e o
hardware que irá processá-lo. Assim, deve-se decidir quais os processadores serão
utilizados, e como distribuir os componentes de software entre eles. Os
relacionamentos presentes em um diagrama de distribuição formam as redes de
processamento de dados.
Figura 81 - Exemplo de um Diagrama de Distribuição
 
5.7. Integração entre os Diagramas
Os diagramas da UML não existem isoladamente, eles fornecem visões
complementares de um mesmo sistema e por este motivo devem ser coerentes entre si.
Os diagramas dos modelos orientados a objetos são baseados nos mesmos princípios
fundamentais, ou seja: classes, heranças, mensagens, estados e eventos. Estes
fundamentos garantem que os diagramas se integrem completamente, mostrando uma
visão própria do mesmo sistema.
A base que define a estrutura do sistema são as classes, que formam a base para
todo o modelo. A implementação do sistema em código executável, parte da criação
das classes. A partir delas são criados os objetos que participam dos diagramas de
seqüências e colaboração. Os diagramas de estado e atividades partem dos estados das
mesmas classes, que formam, também, as bases para criar os componentes nos
diagramas de implementação.
Na estrutura das classes são as mensagens, implementadas nas operações, que
permitem a integração entre as diversas visões dos diagramas. Como as mensagens
são baseadas nas operações das classes, elas permitem que se integre o diagrama de
classes com os diagramas de interação. Como são as operações que controlam os
atributos e permitem às classes alterar os seus estados, temos a integração entre o
diagrama de classes e o diagrama de estados também através das operações.
Para exemplificar a integração que as mensagens proporcionam entre os diagramas,
apresenta-se a seguir a integração que existe entre os diagramas de classes e os
diagramas de seqüência, e a integração entre o diagrama de estado e as operações de
uma classe.
5.7.1. Integração entre os diagramas de classes e seqüência
Os diagramas de seqüência mostram uma troca de mensagens entre objetos de uma
classe. Cada mensagem se refere a um serviço que a classe do objeto de destino pode
oferecer. Assim, para poder oferecer este serviço deve existir uma operação na classe
do objeto de destino para implementar esta mensagem, como mostra o exemplo da
figura: 
 
Figura 82 - Relação entre mensagens e operações nas classes
Na integração entre os diagramas deve-se garantir que as mensagens presentes nos
diagrams de seqüência, correspondam às operações nas classes de destino. No exemplo
existe uma mensagem sendo trocada entre as classes de origem e destino, o que indica
que existe uma operação correspondente na classe de destino.
Em um processo de desenvolvimento pode-se detalhar os processos descritos nos
casos de uso em diagramas de seqüência. Neste processo a modelagem da interação
serve para complementar a distribuição de responsabilidade entre as classes, porque
toda vez que se determina uma mensagem para umaclasse, se está distribuindo as
operações pelas classes. A criação dos diagramas de seqüência serve para povoar as
classes do sistema de operações.
5.7.2. Integração entre os diagramas de classes e estados
O diagrama de estados representa a dinâmica interna de uma classe. Ele expõe como
a classe reage aos estímulos externos que recebe. Estes estímulos, eventos no
diagramas de estados, devem ser operações internas da classe que são acionadas pelas
classes externas. Podem ser operações públicas ou privadas. As operações públicas
permitem que eventos externos estimulem as classes. As operações privadas podem ser
utilizadas para implementar eventos internos, estados de ação, condições e outras
situções onde é necessário ocultar do mundo exterior uma operação. O exemplo do item
de estoque, apresentado no item 5.4.1, é um bom exemplo desta integração.
 
 
 
 
 
 
 
 
 
 
6. Estudo de Casos
Este capítulo reapresenta os exemplos desenvolvidos nos capítulos anteriores
aplicando, de modo prático, os conceitos da modelagem orientada a objetos.
Objetiva-se a revisão dos diagramas e modelos propostos aplicados em exemplos
simples que são levados à implementação em protótipos executáveis.
 
 
6.1. Introdução
Este livro propõe um conjunto de modelos que descrevem sistemas orientados a
objeto. Em conjunto com a introdução de cada modelo foram apresentados diversos
estudos de casos, que serviram de exemplo para a aplicação prática das técnicas e das
notações propostas no texto. Este capítulo retoma cada um destes exemplos,
apresentando os modelos detalhados que levam estes exemplos à sua implementação na
linguagem Java de programação. As implementações destes exemplos foram
desenvolvidas com uma finalidade didática e não o desenvolvimento comercial dos
sistemas, ou mesmo resolver integralmente os problemas propostos. Para tornar os
sistemas mais simples, não se pretende apresentar a integração com bancos de dados,
nem interfaces gráficas sofisticadas que seriam exigências naturais em sistemas deste
tipo.
Os sistemas desenvolvidos são:
Os diagramas da UML apresentados neste livro foram obtidos com a ajuda de uma
ferramenta CASE, e os códigos dos programas foram escritos na linguagem Java com
uma IDE apropriada. Os exemplos desenvolvidos para este livro encontram-se
disponíveis para serem executados on-line, pela internet como descreve o apêndice,
onde também se encontram os códigos destas aplicações.
6.1.1. Estrutura de camadas dos sistema
Os sistemas computacionais podem ser divididos em 3 camadas: apresentação,
negócio e persistência. Em geral, a modelagem conceitual indica a vocação da classe.
Usando a notação da UML , podemos organizar as camadas em pacotes de classes:
Figura 83 - Estrutura de camadas de um sistema,
 (a) notação da UML para as camadas de um sistema
A implementação de um modelo orientados a objetos depende de uma estratégia
para definir as camadas de apresentação e camada de persistência. A camada de
negócios está, em geral, descrita pelo modelo. Mas as camadas de apresentação e de
persistência precisam ser projetadas. A UML pode ser utilzada para definir alguns
elementos presentes na interface, como os exemplos desenvolvidos aqui puderam
mostrar. Entretanto, a UML sozinha não é suficiente para modelar um sistema
completamente, outros diagramas podem ser utilizados para descrever as interfaces e o
modelo de dados (Ambler, 2001).
 
6.2. Estudo de Caso: Sistema de Vendas de Loja
Os capítulos 2 e 3 apresentam o exemplo de um sistema de apoio às vendas de uma
loja. Este sistema informa ao caixa se um produto pode ser vendido à crédito para um
cliente, em função do preço do produto e do crédito do cliente, obedecendo as regras
de negócio da loja. Este exemplo hipotético é usado para mostrar os fundamentos da
orientação a objetos, como a comunicação entre classes por meio de troca de
mensagens e o polimorfismo. No capítulo 2 são desenvolvidas as regras de negócio e
modelado o sistema sem o formalismo da UML, que é introduzido no capítulo 3
juntamente com o diagrama de casos de uso e o modelo de contexto. Neste capítulo são
apresentados os modelos conceitual e detalhado da implementação deste sistema.
6.2.1. Modelo Conceitual
O modelo conceitual do sistema de vendas da loja resulta da análise dos casos de
uso e dos processos ali descritos. Desta análise identificam-se os principais
personagens do sistema, mostrados na figura abaixo, que é uma representação formal
das classes e dos seus relacionamentos:
As classes identificadas no sistema de vendas da loja são:
POS que representa a interface entre o usuário (Caixa) e o sistema, étipicamente uma classe de apresentação
Produto representam os produtos comercializados pela loja, uma classe denegócio
Cliente representam os clientes cadastrados pela loja, uma classe de negócio
Loja representa a loja, com um lista de produtos e clientes, uma classe denegocio
BDLoja auxilia loja para armazenar a lista de clientes e produtos, exemplo deuma classe de persistência.
 
No POS o caixa pode se comunicar com a loja que identifica para o caixa o Produto
que o cliente deseja comprar. Com base no preço do produto e no crédito do cliente, o
sistema pode autorizar a venda parcelada. A loja possui as informações de crédito e do
preço armazenadas em um banco de dados, representado pela classe BDLoja, que é
acionada pela LOJA ao ser criada construindo a lista de produtos (listaP) e a lista de
clientes (listaC).
Figura 84 - Modelo conceitual do sistema da loja
 
6.2.2. Modelo Detalhado
O modelo detalhado do sistema de vendas da loja é conseguido pela análise
detalhada da dinâmica dos processos que estão envolvidos nas vendas. A análise se
realiza com os diagramas de interação, que permitem distribuir, ou verificar a
distribuição, das funcionalidades do sistema pelas classes. Terminada a modelagem, as
classes possuem todas as operações necessárias para atender os objetivos do sistema.
Diagramas de Interação
A partir do modelo conceitual é possível simular os processos dinâmicos
envolvidos no sistema, para distribuir as operações pelas classes. O diagrama de
seqüência descreve a série de mensagens que são trocadas entre os objetos do sistema
em um determinado cenário. Seguem-se os cenários de inicialização da Loja e de
autorização das vendas.:
Figura 85 - Seqüência de autorização de vendas da loja
O cenário de inicialização da Loja é descrito no diagrama de seqüência da figura
acima. Nele, a classe POS, representando o caixa da loja, cria uma instância da Loja,
buscando na classe BDLoja, que representa o banco de dados as informações da loja
para criar a lista de clientes e a lista de produtos. Estas listas são criadas a partir dos
dados de clientes e produtos armazenados na classe BDLoja, e das respostas aos
métodos getListaC e getListaP desta mesma classe. Ao final deste cenário, a loja está
pronta para iniciar as operações de venda solicitadas pela rede de POS.
O cenário mais importante no sistema da loja é o cenário de vendas, que envolve os
casos de uso: Identificar Cliente, Identificar Produto e Autorizar o Parcelamento. Estes
casos de uso podem ser representados por um único diagrama de seqüência que mostra
a autorização do parcelamento de uma venda. Nele, o caixa solicita à Loja, pelo POS,
os dados do cliente, informando o número do seu CGC. A loja busca este nome na lista
de clientes e retorna ao POS. De posse do cliente, o POS recupera o nome do cliente e
exibe na interface. O POS solicita agora os dados do produto para a loja, com base no
código deste produto, por meio da mensagem getProduto(codigo) emitida do POS para
aLoja. A loja busca na lista de clientes e retorna ao POS, que recupera a descrição do
produto. Identificado o cliente e o produto, o POS informa o número de parcelas
desejadas e pergunta para o produto se a venda está aprovada. O Produto faz as
considerações com base nas regras de negócio da loja, envolvendoo crédito do cliente
e o preço do produto, para aprovar, ou não, a venda.
Figura 86 - Diagrama de Seqüência da autorização da venda
Diagrama de Classes Detalhado
O diagrama de classes, no modelo detalhado, integra os diagramas de interação dos
processos e serve de base para a construção do software. As classes podem ser
traduzidas, diretamente no código correspondente, adotando uma linguagem de
programação orientada a objetos. A montagem do diagrama de classes, além da
distribuição das funcionalidades, estabelece o relacionamento existente entre as
classes. O relacionamento segue, aproximadamente, o que foi proposto pelo modelo
conceitual, mas com alterações que permitam a implementação.
Neste ponto do detalhamento são inseridas operações de acesso para todos os
atributos privados da classe. Usando-se o prefixo get seguido do nome do atributo para
as operações de recuperação dos dados , e o prefixo set para as operações de
atribuição.
A Loja é composta de uma lista de objetos da classe Cliente chamada listaC e de
uma lista de objetos da classe produto chamada listaP. Também compõe a classe Loja a
classe BDLoja que é uma classe auxiliar, criada para recuperar os dados destas listas
arquivados de um modo persistente, a cada execução do sistema. A Loja, como mostra
a figura, usa uma composição para representar a associação com as listas e com a
classe auxiliar, para representar uma forte dependência entre estas classes.
Analisando as regras do negócio estabelecidas pela Loja no caso de uso Identificar
Cliente, criou-se uma nova classe chamada ClienteVIP. No diagrama de classes esta
relação é representada por uma herança da classe ClienteVIP da classe mãe Cliente. A
classe filha possui uma condição de crédito diferenciada, implementada na operação
getCredito, que retorna o dobro do crédito atribuído para esta classe. A operação
getCredito da classe Cliente é sobreposta pela classe ClienteVIP em um exemplo de
polimorfismo.
Figura 87 - Diagrama de classes de negócio do sistema
Projeto da Interface
As classes de negócio são projetadas pela análise do processo de negócio, e os
diagramas da UML servem bem para este fim. No entanto, as classes de apresentação
necessitam de um projeto diferenciado. Neste tipo de classe a característica mais
importante é manter o controle do processo de comunicação entre o usuário e o sistema.
A classe de apresentação deve apresentar as informações que o usuário precisa e os
meios para ele agir sobre o sistema. No exemplo da loja, o usuário precisa informar o
código do produto e o CGC do cliente para recuperar da loja o cadastro do produto e
do cliente. Para conseguir a aprovação da venda, depois de identificado o produto e o
cliente, o usuário precisa informar o número de parcelas.
A interface, descrita a seguir, apresenta os campos de texto para a entrada do
código, do CGC e do número de parcelas e os botões (PRODUTO, CLIENTE e
PARCELAS) para que o usuário possa acionar o sistema e processar os dados de
entrada. Para que o usuário verifique que a operação foi um sucesso, ele dispõe de
campos de saída com a descrição do produto, nome do cliente e, finalmente, se a venda
foi aprovada ou não.
 
Figura 88 - Interface POS do sistema de vendas da loja
Adicionalmente, foi inserido um boão Limpar para limpar os campos de dados de
entrada e facilitar uma nova entrada.
Figura 89 - Diagrama de Estado da Interface POS
Uma forma de modelar o controle da comunicação é representar os possíveis
eventos que ocorrem na interface na máquina de estado de um diagrama de eventos.
Cada estado do diagrama representa uma situação em qua a classe se encontra, e cada
evento representa uma ação, promovida pelo usuário, para mudar o estado. A figura do
diagrama de estado da interface POS mostra que ela é criada em um estado de
espera dos dados permanente. O usuário pode realizar 3 eventos neste estado,
correspondente aos 3 botões disponíveis na interface. Cada botão depende que uma
informação seja fornecida, para provocar a mudança de estado, que passa para um
estado de ação onde a classe de negócio é chamada e volta para o estado de espera.
Comparando-se o diagrama de estados acima, como a interface proposta é possível
analisar se a interface serve bem à finalidade desejada de acionar o sistema, ao mesmo
tempo que se analisa as sua precisão por meio do diagrama.
Figura 90 - Diagrama de classes detalhado do sistema da loja
A interface POS pode ser incluída no modelo de classes, agregando à ela, além da
classe Loja, um objeto da classe Produto: oProduto e um objeto da classe Cliente:
oCliente que representam, respectivamente, o produto e o cliente presentes na transação
de venda. A integração da classe POS com as classes de negócio permite a criação de
um diagrama de classe completo do sistema, representado na figura.
Expansão do sistema
Para demonstrar a vantagens de manutenção e expansão dos sistemas orientados a
objeto, pode-se propor uma expansão no sistema da loja, implantando uma nova regra
de negócios ao sistema. Pode-se partir de uma necessidade do departamento de
marketing desta loja, que decidiu colocar um produto em oferta. A regra para esta
situação é a seguinte:
Colocar um produto, da lista de produtos da loja, em oferta quer dizer que ele
pode ser vendido em até 3 parcela fixas, independentemente do crédito do seu
comprador.
Analisando o modelo de objeto do sistema, observa-se que esta regra irá implicar
que a verificação da aprovação do parcelamento da venda será diferente se o produto
for um produto normal ou for uma oferta. Assim pode-se criar uma nova classe de
produtos, que herda as características da classe produto e é chamada de Oferta, como
mostra o diagrama
Figura 91 - Detalhe do diagrama da classe Oferta
Na classe Oferta a aprovação da venda é reformulada para acomodar esta nova
regra. Na classe Oferta também são criadas uma operação construtor Oferta() e uma
operação de saída toString() reformulada.
A nova operação de aprovação isAprovado() possui os mesmos parâmetros de
entrada da operação anterior, de modo que ela substitui integralmente a operação
anterior quando a classe é uma Oferta. Assim, quando se chama a operação de
aprovação em um objeto da classe Oferta a sua forma alterada é acionada.
A nova operação, descrita a seguir, mostra que caso o número de parcelas de venda
(n) for maior do que 3, em um produto em oferta, a regra que está valendo é a de um
produto comum e para isso se aciona o método super.isAprovado da classe
mãe (super). No caso de um produto em oferta, se com um número de parcelas (n) for
menor ou igual a 3, a operação aprova a venda. Assim a nova operação de aprovação
de venda, escrita na linguagem Java, fica:
 public boolean isAprovado(int n, Cliente c){
 int preco = super.getPreco();
 int divida = preco - (preco/n);
 if (n<=3) {
 return (true);
 } else {
 return( super.isAprovado(n,c));
 }
 }
 
Para testar esta nova regra do sistema, vamos colocar o produto 104 em oferta:
 
 104 Piano de Cauda R$ 5.000,00
 
Isto é feito alterando a criação deste produto na classe de acesso ao banco de
dados: BDLoja, como a Oferta á também um Produto, devido à herança, ela pode ser
armazenada na lista de Produtos (listaP), pelo comando:
 
 listaP[4] = new Oferta(104,"Piano de Cauda",5000);
se o produto não esivesse em oferta, o cliente de código 5000, que possui um
crédito de R$ 300,00 não poderia adquirí-lo em 3 parcelas, porque o saldo da compra
certamente seria superior ao seu crédito:
 
5000 Miles Davis R$ 300,00 
 
Mas com a oferta o sistema de vendas autoriza o parcelamento, como mostra a
interface com o exemplo desta operação :
Figura 92 - Exemplo da interface do sistema com venda de oferta
6.3. Estudo de Caso: Jogo da Forca
Este sistema descreve uma aplicação completa, com uma interface gráfica, apoiada
nas classes de negócio identificadas na modelagem conceitual desenvolvida no item
4.4. Utiliza-seeste exemplo para demonstrar a importância da separação das camadas
de negócio, de apresentação e da camada de persistência em um projeto de software e
as possibilidades da modelagem nestes casos. O sistema é detalhado em duas
implementações, uma implementação básica, onde é gerada uma aplicação local para
testes das classes de negócio, e uma implementação “web” onde a aplicação é
expandida para operar no ambiente da internet.
No exemplo desenvolvido no capítulo 4, foram identificadas as classes de negócio:
 
6.3.1. Modelo Detalhado da Implementação Básica
Para detalhar a implementação básica do jogo da forca, a qual será usada para testar
as classes de negócio antes de se implementar o jogo em rede, é necessário fazer o
design da interface desta implementação com o usuário. Na implementação básica do
jogo da forca não se utiliza recursos gráficos. O boneco é representado por uma figura
simples desenhada com caracteres em uma matriz de 3 x 3 como mostra o esquema
abaixo:
 
Também nesta implementação, as letras da palavra secreta que ainda não foram
identificadas são marcadas com traços do tipo : “_”. Por exemplo, se a palavra secreta
escolhida foi namorado, e já foram arriscadas as letras “a”,”m” e “r”, a palavra
descoberta fica sendo apresentada ao jogador como : _ a m _ r a _ _ , onde as letras
ainda não descobertas são substituídas pelo traço.
Diagramas de Seqüência
Os diagramas de seqüência são úteis na definição detalhada das classes e na
definição de como se realiza a comunicação entre elas. Tomando os casos de uso:
Novo Jogo e Chutar Letra, pode-se analisar a seqüência de eventos que é executada nos
cenários principais destes casos de uso, identificando as operações necessárias para se
completar cada processo, e que deve estar presentes nas classes.
Figura 93 - Diagrama de Seqüência do caso de uso: Novo Jogo
A cada vez que o usuário solicita à Forca que crie um novo jogo, ela constrói uma
instância das classes Palavra e Boneco para iniciar o jogo. As operações Jogador(),
Palavra() e Boneco() são os chamados métodos contrutores, que instanciam as classes
na criação dos objetos. Solicita então que a classe Palavra escolha uma palavra
secreta, que ela vai buscar na lista de palavras. A Forca então cria uma instância do
Jogador e prepara a interface do jogo, desenhando o boneco e a palavra secreta com
traços, para o jogador tentar descobrir as letras.
Figura 94 - Diagrama de Seqüência do Caso de Uso: Chutar Letras
O usuário do jogo sugere uma letra que é capturada pela Forca e passada para a
classe Jogador, por meio da mensagem chutaLetra() enviada pela Forca. O jogador 
então acrescenta a letra na lista de letras já chutadas (addLetrasChutadas). O Jogador,
pergunta para a classe Palavra se a letra está na palavra (letraNaPalavra). A Palavra é
incumbida de verificar de a letra está na palavra e, se estiver, acrescenta a letra nas
posições corretas da palavra secreta. Caso a letra não esteja na palavra, a classe
Palavra solicita ao objeto boneco que acrescente mais uma parte ao desenho
(addParte). É importante verificar, ao se construir um diagrama de seqüência que todas
as mensagens trocadas entre as classes tenham uma operação correspondente na o
objeto de destino.
A Forca ao final de cada letra chutada, deve desenhar as letras chutadas
(getLetrasChutadas) a palavra (palavra.desenha) e o boneco (boneco.desenha), para
apresentar ao usuário que irá continuar o jogo. Antes porém, a Forca pergunta para o
jogador se ele perdeu, e o jogador pergunta para a palavra se ela está completa
(isCompleta). Neste momento, a Forca pergunta para o jogador se ele ganhou, e ele
pergunta para a palavra se ela está completa (isCompleta), finalizando o processo, que
é repetido a cada letra chutada.
Diagrama de Classes Detalhado
O jogo da forca pode ser considerado um pacote, onde se encontram as classes de
negócio, e que é utilizada pelo usuário externo para jogar com o computador. Este
sistema é representado pela figura abaixo:
Figura 95 - Representação do jogo como um sistema
Os diagramas de seqüência ajudam a completar o diagrama de classes com as
operações e as suas assinaturas, garantindo que as classes tenham todas as operações
necessárias para executar os processos do sistema, definidos nos cenários dos casos de
uso. O resultado, na implementação básica do Jogo da Forca é mostrado no diagrama
de classes detalhado a seguir.
O diagrama de classes detalhado serve para iniciar o desenvolvimento do sistema,
porque cada classe será traduzida em um programa Java. Deve-se detalhar cada
operação e atributo definindo o seu tipo, valor inicial, tipo de retorno e parâmetros dos
atributos. 
Deve haver uma relação biunívoca entre o código e o diagrama. Isto quer dizer que
o diagrama e o código, no nível das definições das classes, se equivalem. Chama-se de
engenharia de produção a geração de código, em linguagem de programação, a partir do
diagrama. Chama-se de engenharia reversa a produção do diagrama a partir do código
em linguagem de programação. Estas conversões são facilitadas pelo uso de uma
ferramenta CASE para automação do projeto de software.
Figura 96 - Diagrama de classes da implementação Básica
 
Código Java da classe Boneco
Para exemplificar a equivalência entre o código e o modelo, pode-se analisar o
código de uma das classes do diagrama de classes. Este é o código, na linguagem Java,
que é equivalente à classe Boneco:
 
public class Boneco 
{
 private int parte = 0;
 private char[][] Dforca;
 private void limpaForca () {
 }
 public void addParte () {
 }
 public String desenha () {
 }
 public boolean isCompleto () {
 }
 public Boneco () {
 }
} 
A modelagem dinâmica ajuda o projetista a definir como devem ser construídos os
métodos, e a detalhar a troca de mensagem entre as classes. Os diagramas de estado
exibem as relações entre as mensagens que a classe recebe e emite, e os seus processos
internos. Mostra-se o ciclo de vida das classes do sistema, que se integram para formar
o ciclo de vida do sistema como um todo.
Diagramas de Estado do Jogador
O jogador possui 3 estados bem definidos: ChutandoLetras, Ganhou ou Perdeu. O
jogador é criado no estado ChutandoLetras. O evento que altera os estados é o evento
chutaLetra, que recebe uma letra entrada pelo usuário para teste. Quando ocorre o
evento chutaLetra, o jogador continua no estado Chutandoletras, mas manda uma
mensagem para ele mesmo adicionar esta letra na lista de letrass chutadas
(addLetraChutada). Se a palavra estiver completa o jogador ganhou, se o boneco
estiver completo ele perdeu, estas situações são estados verificados com os métodos
ganhar() e perder(), respectivamente;
 
Figura 97 - Diagrama de estados da classe Jogador
Ao enviar a a mensagem perguntando se a letra está na palavra, o jogador faz com
que a palavra tome uma decisão: se a letraNaPalavra for verdadeira ela insere a letra
na palavra secreta. Se a letraNaPalavra for falsa ele manda o boneco acrescentar uma
parte.
É possível se detalhar um estado, em atividades ainda mais internas. Por exemplo, o
estado de chutandoLetras é um estado de ação e pode ser expandido em um outro
diagrama de estados, como mostra a figura que se segue:
Figura 98 - Diagrama do superestado Chutando Letras
Neste diagrama observa-se que a entrada do evento chutaLetra aciona a ação interna
de adicionar letras na operação addLetrasChutadas e com base na definição se a letra
está na palavra, obtida pela mensagem letraNaPalavra enviada para a classe palavra,
toma-se a decisão de adicionar uma parte ao boneco, enviando a mensagem addParte ao
boneco, ou não. Terminadas estas ações internas, a classe Jogador permanece
esperando um novo evento chutaLetra, e pode enviar os sinais de ganhar ou perder. Este
diagrama de estado é equivalente ao código java reproduzido a seguir:
 
 public char chutaLetra (char letra,
 Palavra palavra,
 Boneco boneco){addLetrasChutadas(letra);
 if (!palavra.letraNaPalavra(letra))
 boneco.addParte();
 }
 return(letra);
 }
Diagrama de Estado da classe Boneco
A classe Boneco possui 3 estados bem definidos: um estado inicial, onde nada do
boneco foi desenhado na forca, um estado onde as partes do boneco estão sendo
desenhadas uma a uma, e finalmente outro estado, quando o boneco está completo, e o
Jogador perdeu o jogo. O atributo que controla este estado é o número de partes do
Boneco que já foram desenhadas, representado pela variável parte. O evento que
coloca o Boneco no estado inicial é o evento de construir o objeto ou o evento
limpaForca. A troca de estados é feita pelo método addParte, que adiciona uma parte
do boneco cada vez que é acionada. Estando o Boneco com mais de 6 partes ele é
considerado completo, o diagrama abaixo mostra estas transições em um diagrama de
estado:
Figura 99 - Diagrama de estados da classe Boneco.
Detalhamento da classe Forca
A classe forca implementa o método principal (main) acionado quando da execução
do programa. Ao ser inicializada a Forca ela envia uma mensagem para a classe
palavra escolher uma palavra secreta. A partir dai, entra em um ciclo que termina
quando o jogador ganhar ou perder. A cada volta do ciclo executa o desenho do boneco
e da palavra secreta, mostrando ao jogador o que já foi descoberto, assim como as
letras que já foram testadas. Cada letra chutada é passada para a classe Jogador que irá
processá-la, verificando se o jogador ganhou ou perdeu, retornando ao início do ciclo.
Este processo pode ser representado pelo diagrama de atividades que se segue:
Figura 100 - Diagramas de atividades do programa Forca
 
o extrato de programa Java abaixo apresenta uma possível tradução deste diagrama,
onde se utiliza a classe JOptionPane do pacote javax.swing para implementar a
interface com o usuário, que é toda na forma de um texto.
 
public static void main(String arg[]){
 char letra; 
 String tela="";
 palavra.escolheSecreta();
 do {
 //
 // constroi o desenho da forca e da palava 
 tela = boneco.desenha()+"n"
 +palavra.desenha()+"n"
 +jogador.getLetrasChutadas();
 //
 // captura uma letra entrada pelo usuario
 letra =JOptionPane.showInputDialog(tela).toCharArray()[0];
 //
 // Envia mensagem ao jogador para entrar com letra no jogo
 jogador.chutaLetra(letra, palavra, boneco); 
 }while(!(jogador.ganhar(palavra)||jogador.perder(boneco)));
 
 if (jogador.ganhar(palavra))
 {tela = tela + "n Parabens! ganhou!"; };
 if (jogador.perder(boneco))
 {tela = tela + "n Que pena, perdeu!";};
 JOptionPane.showMessageDialog(null,tela,
 "Jogo da Forca",JOptionPane.INFORMATION_MESSAGE);
 
 System.exit(0);
 }
Executando-se o comando para executar o sistema:
 
C:Java Forca
Obtém-se uma interface para o jogo, com um pedido para chutar uma letra, de modo
semelhante à interface mostrada na figura:
 
Figura 101 - Interface para jogar a forca
 
6.3.2. Modelo Detalhado da Implementação WEB
Os modelos orientados a objeto tem como uma das grandes vantagens a
características de reusabilidade e a facilidade de expansão e manutenção. Este exemplo
demonstra a reusabilidade do código orientado a objeto, criando uma versão para a
internet do jogo da forca reaproveitando grande parte do código da versão básica. A
nova versão web do jogo inclui duas novidades:
1. Um interface gráfica baseada na tecnologia de Java Applet, e
2. Uma classe que permite ler as listas de palavra pela internet.
Estas modificações servem para avaliar a facilidade em se dar manutenção em
sistemas desenvolvidos sob a orientação a objetos, e a grande reutilização resultante do
encapsulamento das classes. O novo sistema chama-se de forcaWEBDB, como mostra
o diagrama abaixo, onde se observa a dependência de um sistema e outro.
Figura 102 - Diagrama do sistema ForcaWEBDB e suas dependências
Para criar uma versão gráfica da forca é necessário criar uma nova classe Forca,
agora chamada de ForcaWEBDB, que implementa um Applet para ser processada pela
internet.
Implementar um acesso remoto à lista de palavras
A primeira modificação na implementação básica para levar o jogo para a internet
é alterar a classe Palavra. Optou-se por criar uma nova classe, chamada de PalavraDB
para implementar a camada de persistência da classe Palavra, onde o sufixo DB lembra
DataBase. Como foi visto é comum isolar em camadas as funções de persistência, que
são mais sujeitas a alterações.
A idéia é re-escrever o método da classe Palavra que faz acesso à lista de palavras.
O método que escolhe a palavra secreta lê a lista de palavras de um arquivo texto e
seleciona, aleatoriamente, uma palavra. Esta leitura é feita pela classe PalavraDB que
recebe como parâmetro de entrada o endereço de localização do arquivo na internet.
Este endereço é parâmetro de entrada da Applet, o que permite que o jogo possa
receber diferentes listas de palavras, implementando diferentes níveis de dificuldade,
ou jogos temáticos como palavras ligadas a animais, países, plantas, etc...
O diagrama abaixo mostra a dependência que foi então criada entre a classe Palavra
e a classe PalavraDB, implementada na operação escolheSecreta().
Figura 103 - Exemplo de implementação da camada de persistência 
Criar uma interface gráfica
O que muda na classe que representa o boneco na implementação básica, para o
boneco da implementação para internet é apenas a sua aprentação gráfica, as
propriedades de gerenciar o número de partes desenhadas, e verificar se está completo
deve ser o mesmo. Todo código desenvolvido para a implementação básica deve ser
reutilizado na nova implementação.
Figura 104 - Criação de uma classe de Boneco para web
Assim, para reutilizar o código existente pode-se utilizar da capacitade de herança
das classes e criar uma nova classe, chamada de BonecoWeb, que é filha da classe
Boneco. Esta nova classe iá substituir a classe boneco na implementação da
forcaWEBDB, sobrescrevendo o método desenha() que desenha o boneco na forca.
Exemplo da interface resultante
A nova implementação da classe Forca utiliza as mesmas classes Jogador e Boneco
da implementação anterior, acrescida das classes BonecoWEB e PalavraDB, com uma
pequena alteração na classe Palavra. O resultado final é um novo diagrama de classes,
esquematizado a seguir, que implementa o novo Jogo da Forca com uma nova interface.
Nesta nova implementação as classe ForcaWEBDB e BonecoWEB formam a
camada de apresentação, a camada de negócios continua formada pelas classes
Jogador, Palavra e Boneco, e a camada de persistência é implementada pela classe
PalavraDB:
Figura 105 – Classes da implementação web e divisão de camadas
Nesta nova implementação é possível se representar com um diagrama de
componentes a versão final do jogo, que para ser jogado na internet requer que um
servidor receba uma página no formato html (index.html) com o código da Applet
(ForcaWEBDB.class) e que é transferida para o processador do cliente pela internet.
Os componentes que implementam o jogo são representados no diagrama abaixo:
Figura 106 - Diagrama de componentes do jogo da forca
No diagrama de componentes estão relacionados os arquivos que fazem parte do
jogo e suas dependências. Os arquivos possuem extensões que caracterizam os tipos de
componentes. Neste diagrama identificamos a página html, as classes java e o arquivo
texto da lista de palavras.
Estes componentes são recebidos por um servidor web (webserver) que permite que
clientes remotos, munidos de um navegador (browser) possam executá-los e jogar a
forca. Esta distribuição de componentes é mostrada no diagrama de
distribuição abaixo:
Figura 107 - Diagrama de distribuição do jogo da forca
O servidor web, em nosso caso, foi implementado no endereço do em um website
que se encontra descrito no apêndice. Neste endereço tem-seacesso à página
index.html que implementa, a interface abaixo:
 
Figura 108 - Exemplo de interface para o Jogo da Forca na web
 
 
 
6.4. Estudo de Caso: Modelo de um item de estoque
No item 5.4 foi apresentado um exemplo de aplicação do diagrama de estado na
gestão de um item de estoque. Este exemplo é desenvolvido aqui nos seus modelos de
contexto, conceitual e detalhado, para também exemplificar uma aplicação da
modelagem orientada a objetos.
6.4.1. Modelo de Contexto
O sistema em estudo representa um sistema de controle de estoque, comum em
almoxerifados de empresas de médio e grande porte. Tais sistemas controlam a
quantidade de material em estoque com base nos parâmetros de uso e reposição destes
materiais. O número de algoritmos e de técnicas para se gerenciar estoque é grande e
não faz parte do escopo deste trabalho analisá-los. Como exemplo, toma-se uma regra
simples, que é descrita em um modelo de objetos e implementada um um progama de
computador, no sistema itemDeEstoque.
Figura 109 - Sistema ItemDeEstoque e Diagrama de Casos de Uso
 
O diagrama descreve as funções do Almoxerife, responsável pelo gerenciamento
dos itens de estoque e de compras responsável pela aquisição dos itens no mercado,
para repor o estoque. Resumidamente, temos os casos de uso: Retrira Itens do Estoque
e Repoe Itens do Estoque, considerados em nosso exemplo como objetivos do ator
Almorexife no sistema de itemDeEstoque.:
Retira Itens do Estoque
O Almoxerife atende requisições de retirada de material do estoque. Se a retirada
deixar o estoque abaixo do estoque mínimo, o almoxerife cancela as próximas retiradas
e envia uma mensagem para o setor de compras para repor o material. Após a
reposição do material, as retiradas podem ser realizadas novamente.
Repõe Itens do Estoque
O Almorexerife recebe o material do setor de compras e aumenta a quantidade de
itens no estoque. Toda a reposição é feita na quantidade de reposição, que é definida
para cada item.
6.4.2. Modelo Conceitual
Conceitualmente, existem 3 classes importantes neste sistema:
 
O diagrama de classes a seguir, representa conceitualmente o sistema
itemDeEstoque proposto. Nele a classe ItemEstoque possui os seguintes atributos e
operações:
 
Figura 110 - Diagrama de classes do modelo conceitual
6.4.3. Modelo Detalhado
Para levar este modelo conceitual a uma implementação deve-se detalhar os
processos internos da classe ItemEstoque e os eventos de retirar e repor material. Para
isso lança-se mão do diagrama de estados desta classe.
A classe itemEstoque possui dois estados claramente definidos, um estado de
estoque normal e outro estado quando o estoque está baixo. O estado é definido
comparando a quantidade armazenada com um valor do estoque mínimo. Se a
quantidade for menor que o estoque mínimo o estoque está baixo. Estuda-se agora o que
os eventos de retirarMaterial e reporMaterial produzem quando a classe está em cada
um destes estados.
Figura 111 - Diagrams de estados da classe itemEstoque
A mudança do estoque normal para o estoque baixo ocorre quando há um evento de
retirada do estoque e a quantidade final é inferior ao estoque mínimo, neste caso, o
comprador deve ser acionado para comprar o item. Não são autorizadas retiradas
quando o estoque está baixo, e uma mensagem é enviada ao comprador. A reposição do
material coloca o estoque novamente em uma condição normal. É importante observar
que a quantidade de reposição deve ser superior ao estoque mínimo, para garantir que a
reposição irá sempre voltar o estoque ao normal.
Analisando diagrama acima é possível escrever um código para os eventos
retirarMaterial e reporMaterial. Cada evento será uma operação na classe ItemEstoque,
e será capaz de atender as diferentes mudanças de estado que cada evento produz no
diagrama. Os eventos produzem diferentes mudanças de estado em função do estado
original e das condições de disparo, que serão as condicionantes (if) no código da
operação.
No exemplo, existem 3 eventos envolvidos com a retirada de material que podem
ser transcritos no código, como mostra a operação retirarMaterial da classe
ItemEstoque, reproduzida abaixo. A operação isBaixo() caracateriza o estado da classe
quando o evento ocorre, e divide o processamento em dois eventos: um quando o
estado é baixo (isbaixo==true) e outro quando não está baixo o estoque. No caso do
estoque não ser baixo há ainda duas opções, que são observadas no diagrama como
condições de disparo e reproduzidas no código: se a quantidade existente é maior que a
quantidade retirada (qtd>n) e se após a retirada o estoque ficou baixo
(qtd<estoqueMinimo):
 
 public boolean retirarMaterial(int n)
 {
 boolean ok="false;"
 if (isBaixo()) 
 {
 comprador.setMensagens("Estoque Baixo");
 } else 
 {
 if (qtd>=n) {
 qtd = qtd - n;
 ok = true;
 }
 if (qtd<estoqueMinimo) {
 comprador.comprar(this);
 }
 }
 return(ok);
 }
 
de modo análogo pode-se traduzir o evento reporMaterial, que só é processado
quando o estado original for de estoque baixo, caso contrário retorna falso na operação
reporMaterial:
 
 public boolean reporMaterial (int n)
 {
 boolean ok = false;
 if (isBaixo())
 { 
 qtd = qtd + getQtdReposicao();
 comprador.setMensagens("material reposto");
 ok = true;
 }
 return(ok);
 }
 
Estas operações resumem o ciclo de vida da classe ItemEstoque, que necessita
ainda das operações de acesso para proteger os atributos. O resultado final está na
classe mostrada abaixo, que pode ser utilizada em aplicações típicas de gerenciamento
de estoques:
Figura 112 - Diagrama de classes do sistema itemDeEstoque
Para verificar a operação correta desta estrutura foi desenvolvido uma aplicação
que executa o “gerenciamento” de um item de estoque para teste. A classe Almoxerife,
que é o cliente da classe ItemEstoque, é implementada com um interface que permite:
 Retirar uma quantidade de material (botão: Retirar)
 Repor o estoque do item (botão: Repor)
 Acompanhar a situação da quantidade e do estado do item. (Área de texto e
mensagens)
 Verificar as mensagens de são enviadas para o setor de compras. (Caixa de
texto com a mensagem do comprador)
A figura abaixo mostra esta interface, que está genrenciando um item com os
seguintes atributos:
 
codigo = 101010
descrição = Tonner de copiadora
qtd = 100
estoqueMínimo = 50
qtdReposicao = 70
 
Figura 113 - Interface de teste do itemDeEsqtoque
Ao se retirar uma quantidade maior (55) que leva ao estoque mínimo temos que o
estoque passa a ser baixo e o comprador recebe a mensagem de comprar uma
quantidade de 70 para repor o estoque, como mostra a figura.
Figura 114 - Exemplo da comunicação ItemEstoque/Compras
Pressionando-se o botão re repor o estoque é acrescido de 70 unidades e se
normaliza.
 
 
 
 
 
 
 
 
 
 
7. Conclusões
O livro desenvolve técnicas para representar problemas de software por intermédio
de modelos orientados a objeto, seguindo a notação da UML. A abordadem proposta
permite um aumento gradual no nível de detalhes da representação. Este aumento é
causa e conseqüência do entendimento do problema que aumenta com a análise e
construção do software. O objetivo final do modelo de software é a apreensão da
complexidade do problema para que seja possível a construção de uma solução. Este
caminho vai depender de uma representação completa, precisa, coerente e com um
nível de detalhes suficientemente grande, que possibilite a sua tradução em códigos, a
serem integrados nos sistemas de software.
Nos capítulos anteriores foi aprosentada a modelagem orientada a objetos em 3
tipos de modelos: o modelo de contexto, o modelo conceitual e o modelo detalhado.
Cada modelo possui uma escala e um ponto de vista próprio, e se utiliza de um conjunto
de técnicas e de diagramas daUML para representá-lo. A tabela abaixo resume esta
combinação:
O desenvolvimento do trabalho mostra que não apenas as classes são importantes
em um sistema orientado a objetos, e destaca o importante papel desempenhado pelas
mensagens para descrever a dinâmica do sistema. De modo muito parecido com uma
conversa entre as classes, o processamento de um sistema orientado a objetos é um
suceder de eventos organizados para atender os objetivos do sistema.
O leitor não encontrará claramente no livro a organização de um método para
desenvolvimento de software, porque não é esta a sua finalidade. Mas há sim, na forma
de apresentação dos assuntos, um caminho natural que pode ser seguido para o
entendimento de um problema, e que pode ser percorrido pelo analista como um
método. Os melhores exemplos deste caminho natural são os estudos de caso, que se
utilizam da mesma seqüência de passos para desenvolver um sistema.
Cada problema exigirá, no entanto, mais de um modelo do que de outro. A
finalidade para qual se está modelando condiciona a importância que se deve dar aos
modelos. Um analista de negócio, por exemplo, que está envolvido nas primeiras etapas
da concepção de um sistema, irá dedicar mais tempo aos modelos de contexto, e talvez
um pouco menos ao modelo conceitual e não produzirá nenhum modelo detalhado. O
engenheiro de software que procura garantir uma performance adequada para um
sistema, irá se dedidar, exclusivamente, aos modelos detalhados e aos diagramas de
implementação. O programador responsável pelos códigos poderá receber um modelo
de contexto e um modelo conceitual já prontos e deverá, por sua vez, produzir muitos
modelos detalhados para poder criar os componentes do sistema.
As técnicas de modelagem orientada a objetos não terminam aqui. É uma disciplina
viva da engenharia de software e passa, constantemente, por atualizações, correções e
extensões para diversas áreas de aplicação. A OMG é o foro adequado para propor
mudanças e discutir as evoluções da UML. Recomenda-se a visita freqüente no seu
website para se manter atualizado com a UML
Apenas a atualização teórica não é bastante, a prática da modelagem é necessária
para a apreensão dos conceitos. Assim como ao aprender uma língua estrangeira é
preciso falar, ao aprender uma linguagem de modelagem é preciso modelar. Somente a
prática pode dar ao modelista a habilidade necessária para obter a qualidade e
precisão na representação. Neste trabalho ao apresentar cada modelo pode-se observar
como é possível aplicar os recursos de representação em exemplos práticos, tirados de
casos simples, propostos e estudados ao longo de todo texto. Cabe agora ao leitor,
aceitar o desafio de aplicar estas técnicas, e os diagramas da UML, para representar os
seus próprios sistemas de software, e comprovar as qualidades da modelagem
orientada a objetos.
 
 
 
 
 
 
 
 
 
7.1. Referências Bibliograficas
AMBLER, SCOTT; CRC Modeling: Bridging the Communication Gap Between
Developers and Users. November 29, 1998.
AMBLER, SCOTT; Be Realistic About the UML. 2001./ da internet/
Beck, K. e; Cunningham, W. A laboratory for teaching object-oriented thinking.
OOPSLA´89 Conference Proceedings, 1989.
Beck, Kent Extreme Programming explained: embrace change. Addison Wesley
Longman, 1999.
Bellin, D.; Simone, S. The CRC Card Book. Addison-Wesley Pub Co; ISBN:
0201895358; Series on Object-Oriented Software Engineering. 1997.
BERARD, E. V. Be Careful with “Use Cases”, 1996. /da internet:
http://www.toa.com/pub/use_cases.htm /
BOOCH, G. Object-Oriented Analysis and Design with Application.
Benjamin/Cummings, 1994.
ECK, DAVID. The Most Complex Machine: A Survey of Computers and Computing.
A K Peters Ltd; ISBN: 1568810547; 1995.
FOWLER, M.; SCOTT, K. UML Destiled. Object Technology Series. Addison-
Wesley, ISBN 0201325632; 1997
HARMON, P.; WATSON, M. Understanding UML The Developer's Guide. San
Francisco, Morgan Kaufmann, 1997.
JACOBSON, I.; RUMBAUGH, J.; BOOCH, G; The Unified Modeling Language
Users Guide. Addison-Wesley Pub Co; . Object Technology Series; ISBN:
0201571684; 1998.
JACOBSON, IVAR et al. Object-Oriented Software Engineering: A Use Case
Driven Approach. Addison-Wesley Pub Co; ISBN: 0201544350; 1992
Larman, Craig. Applying UML and patterns: an introdution to object-oriented
analysis and design. Prentice Hall PTR, 1997.
http://www.toa.com/pub/use_cases.htm
OMG, Ed. OMG Unified Modeling Language Specification. Version1.4, September,
Object Management Group. 2001./ da internet em http://www.omg.org/
ORFALI, R.; HARKEY, D. Client/Server Programming with Java and CORBA. 2nd
Ed. John Wiley & Sons Ed. 1998.
PARNAS, D.L.; On the Criteria to be used in decomposing System into Modules.
Communications of the ACM, Vol.5, No.12, December 1972, pp 1053-1058
Pfleeger, Shari Lawrence. Albert Einstein and Empirical Software Engineering.
IEEE Computer. V.32 n.10 Oct. 1999
PRESSMAN, R. S. Engenharia de Software. 3a Ed. São Paulo: Makron. 1995.
Probasco, Leslee. Dear Dr. Use Case: What About "Shall" Wording in a Use Case?.
Rational Software Canada, 2001. /da internet: http://www.therationaledge.com /
RUMBAUGH, et al. Modelagem e Projetos Baseados em Objetos. Rio de Janeiro:
Campus, 1994.
SEBESTA, ROBERT W. Concepts of Programming Languages. 3rd ed. New York:
Addison-Wesley, 1996.
Wilkinson, Nancy. Using CRC Cards. SIGS Books & Multimedia, ISBN:
0133746798, 1995.
Wirfs-Brock, Rebecca. Designing Object-Oriented Software Prentice Hall PTR;
ISBN: 0136298257; 1991.
 
http://www.therationaledge.com/
7.2. Endereços da Internet
Seguem-se alguns endereços na internet onde se pode encontrar informações sobre
orientação a objetos:
www.omg.org 
website da Object Managment Group, entidade que reúne empresas e interessados
na normatização da tecnologia e das aplicações orientadas a objeto. Lá se encontra a
documentação oficial da UML em www.omg.org/uml/ , as últimas versões, o estado das
discussões das novas versões, referências, e outras normas como CORBA e XML.
www.cetus-links.org
website que organiza até a data que escrevia este, mais de 18000 links para
websites sobre orientação a objetos. É uma referência obrigatória na busca de qualquer
assunto ligados à tecnologia de objetos, UML, componentes, engenharia de software e
seus mais diversos padrões e tópicos relacionados. O website é bem cuidado e os links
são freqüentemente atualizados. Em www.cetus-links.org/oo_ooa_ood_tools.html pode
ser encontrada uma lista das ferramentas CASE disponíveis, com vários programas em
demonstração que podem ser copiados para avaliação.
www.c2.com
website da empresa de Ward Cunningham onde se pode encontrar alguns artigos
importantes sobre Objetos, inclusive o artigo original de introdução aos cartões CRC.
Curiosamente, pode-se encontrar em http://c2.com/doc/crc/draw.html a imagem dos
primeiros cartões que Cunningham e Beck utilizaram para apresentar a sua técnica.
www.mundooo.com.br
website brasileiro com um portal bem atualizado e organizado sobre orientação a
objetos, possui diversos artigos e notícias de diversas origens, organizadas por assunto.
Possui um bom material também sobre Java. Dispõe de um fórum muito útil para
discussão de assuntos relacionados a objetos, e que traduz bem a simplicidade e
praticidade da técnica.
www.od.com.br
website de um dos mais importantes eventos sobre orientação a objetos que ocorre
no Brasil. Trata do estado da arte da tecnologia e de importantes aplicações das
http://www.omg.org/
http://www.omg.org/uml/
http://www.cetus-links.org/
http://www.cetus-links.org/oo_ooa_ood_tools.html
http://www.c2.com/
http://c2.com/doc/crc/draw.html
http://www.mundooo.com.br/
http://www.od.com.br/
técnicas em empresas nacionais.
www.objetos6000.com.br
website de outro importante evento patrocinado pela SUCESU-SP
(www.sucesusp.com.br) e que reúne 3 tecnologias ligadas à orientação a objetos:
UML, CORBA e Java.
www.rational.com
website da empresa Rational, onde originalmente foi criada a UML e hoje é uma
empresaque desenvolve soluções para apoio ao desenvolvimento de software usando
extensamente a UML, como na ferramenta CASE Rational Rose.
www.microgold.com
website da empresa Microgold que produz o software de CASE WithCLASS que
utilizei para produzir os modelos apresentados neste livro.
www.uml.com.br ou www.umlbrasil.com.br
um dos portais nacionais sobre a UML com link para outros portais, artigos,
tutoriais e outras informações sobre UML e orientação a objetos.
http://java.sun.com . 
website oficial da linguagem Java, no domínio da empresa Sun, onde todas as
informações sobre a linguagem, os compliladores e máquina virtual podem ser
encontrados. Pode-se encontrar também tutoriais e exemplos de sistemas
desenvolvidos nesta linguagem.
www.voxxel.com.br/deboni
Meu website pessoal que mantenho dentro do portal da empresa Voxxel Consultoria
de Sistemas. Nele mantenho alguns artigos sobre o UML, Objetos, Java, novidades e
material complementar a este livro.
 
http://www.objetos6000.com.br/
http://www.sucesusp.com.br/
http://www.rational.com/
http://www.microgold.com/
http://www.uml.com.br/
http://www.umlbrasil.com.br/
http://java.sun.com/
http://www.voxxel.com.br/deboni
Glossário
A 
Abstração 
(abstraction) As características essenciais de uma entidade que a
distinguem de outra entidade. Uma abstração define os limites da
entidade relativos à perspectiva do espectador.
Ação
(action) Uma mensagem enviada quando da ocorrência do evento,
permite a integração entre o diagrama de estado e os diagramas de
interação.
Adorno (adornment) Elementos gráficos que aumentam a precisão dadescrição de um diagrama.
Agregação 
(aggregation) Forma especial de associação que especifica uma
relação de todo-parte entre o agregado (todo) e seus componentes
(parte). 
Análise (analisys) fase do desenvolvimento do sistema onde se identifica osobjetivos e se procura entender o problema a ser resolvido.
Analista de
sistemas
(system analiyst) profissional responsável por realizar a análise de
um sistema.
Arquitetura
(architecture) organização proposta para resolver um problema,
inclui a configuração de software e hardware, e como eles se
organizam.
(signature) conjunto composto do nome, o valor de retorno e dos
Assinatura parâmetros da operação de uma classe, não inclui a sua
implementação.
Associação
(association) tipo de relacionamento entre classes onde há um certo
nível de envolvimento entre elas, cada classe se mantém
independente, mas guardam algum tipo de significado na ligação.
Ator
(actor) representa os elementos externos ao sistema, que interagem
com ele Como um usuário que desempenha um papel no sistema,
estando fora do sistema, e não podem ser alterados pelo
desenvolvedor do sistema.
Atributo (atribute) parte da estrutura que permite o armazenamento deinformação em uma classe, possui um tipo e um nome.
B 
Booleano (boolean) Tipo de enumeração que assume os valores de falso ouverdadeiro.
Brainstorm (brainstorm) estratégia utilizada para levantar os requisitos de umprojeto em uma reunião de trabalho.
C 
Camada 
(layer) conjunto de classes que compartilham o mesmo nível de
abstração ou finalidade, um layer pode ser representado por um
pacote.
Cardinalidade (cardinality) número de elementos de um conjunto.
(CRC cards) Técnica proposta por Beck e Cunnigham (1989), que
Cartões CRC utiliza cartões de papel para representar as classes e organizar um
trabalho em equipe que identifica e descreve conceitualmente as
classes de um sistema.
CASE
Engenharia de Software Apoiada por Computador, do inglês:
Computer-Aided Software Engineering. Corresponde a programas
de computador que dão suporte às atividades de engenharia de
software, principalmente as atividades de modelagem
Caso de Uso
(Use Case) seqüência de transações ocorridas no sistema, que
refletem em algo de importância para o ator que se comunica com
ele.
Cenário (scenary) instância de um caso de uso, pode ser otimista,alternativo ou de exceção.
Ciclo de
desenvolvimento
(development cicle) série de atividades que gera um software a
partir dos requisitos de um problema Possui 4 atividades
principais: análise, design, construção de componentes e
integração.
Ciclo de teste
(test cicle) série de atividades que verifica se o software fornecido
pelo ciclo de desenvolvimento está de acordo com os requisitos de
projeto.
Ciclo de vida
(life cicle) série de atividades entre a criação e destruição de uma
classe, software ou de outro componente de um sistema, ou até
mesmo do próprio sistema.
Classe
(class) molde para a criação de objetos, identifica um conjunto de
objetos que compartilha a mesma estrutura de dados e as mesmas
operações. É a base para a contrução de um software orientado a
objetos.
Classe abstrata
(abstract class) apenas descreve conceitos abstratos e que não
serão transformados em objetos diretamente. Uma classe
abstrata possui pelo menos uma operação abstrata, definida apenas
pela sua assinatura.
Classe concreta. (concrete class) classe que permite a sua instanciação em objetos,não possui nenhuma operação abstratas.
Classificação (classification) processo de identificação das classes de umsistema em uma hierarquia de tipos.
Cliente
(client) 1.contratante do desenvolvimento do software, interessado
pelo resultado que o software irá dar ao seu negócio. 2.classe ou
componente de software que solicita um serviço a outra classe ou
componente.
Código (code) programa de computador escrito em uma linguagem deprogramação.
Código
executável
(executable code) programa de computador em linguagem de
máquina, executável em um processador.
Código fonte
(source code) programa de computador em uma linguagem de
programação de alto nível, passível de ser compreendida por um
programador.
Colaboração (collaboration) conjunto de interação entre classes para cumprir umobjetivo do sistema.
Comentário (comment) Ver nota
Componentes 
(component) unidades que armazenam software e permitem a
manipulação: arquivamento, distribuição e instalação deste
software. Devem possuir uma interface bem-definida.
Comportamento (behavior) Os efeitos observáveis de uma operação ou evento, asoperações públicas expostas por uma classe ou componente.
Composição 
 
(composition) relacionamento entre classes com uma forte
propriedade de posse, o todo é formado pelas partes que dependem
existencialmente do todo.
Condição de
disparo
(guard condition) expressão lógica avaliada quando da ocorrência
do evento e que condiciona a execução do evento.
Construção (contruction) fase do desenvolvimento onde os componentessão criados (programados, codificados) a partir dos modelos .
Contexto (context) conjunto de elementos relacionados que interagem para
cumprir um objetivo do sistema.
CRC Classe, Reponsabilidade e Colaboração, do inglês: ClassResponsability and Colaboration
D 
Delegação 
(delegation) A habilidade de um objeto em compartilhar uma
responsabilidade com outro objeto, por meio da duplicação desta
operação entre eles. A delegação pode ser usada como uma
alternativa à herança.
(dependency) relacionamento existente entre classes que de alguma
Dependência forma não está especificada pela relação, forma frace de
relacionamento.
Design
(design) fase do desenvolvimento onde se elaborar uma estratégia
para resolver o problema Na fase de design são tomadas decisões
ligadas à solução do problema.
Diagrama 
(diagram) representação gráfica de uma coleção de elementos
relacionados: diagramas de classes, diagrama de objetos, diagrama
de casos de uso, diagrama de seqüência, diagrama de
colaboração, diagrama de estados, diagrama de atividades,
diagrama de componente, e diagrama de distribuição. 
Diagrama de
objetos
(object diagram) reúne objetos e as suas relações em um instante no
tempo. Um diagrama de objeto pode ser considerado um caso
especial de um diagrama de classes..
Diagrama de
Casos de Uso
(use case diagram) descreve um modelo funcional de alto nível do
sistema de infomações em projeto. Identifica os usuários e
representa o sistemasegundo a sua visão.
Diagrama de
Atividades
(activity diagram) representação gráfica dos diferentes estados e
eventos que estão associados com um cenário. Representa as
mensagens entre classes e os eventos intraclasse.
Diagrama de
Classes
(class diagram) mostra uma coleção estática de elementos do
modelo seus conteúdos e relações. Forma a base para a tradução em
código, criando uma estrutura para orientar a construção.
Diagrama de
Colaboração
(colaboration diagram) mostra as interações de objetos
organizadas entre os objetos e seus vínculos. Assemelha-se em
conteúdo ao diagrama de seqüência.
Diagrama de
Componentes
 
(component diagram) mostra a organização e as dependências entre
os componentes de software.
Diagrama de
Distribuição
(deployment diagram) mostra a configuração, em tempo de
processamento, dos nós de processamento, e os componentes,
processos e objetos que existem neles.
Diagrama de
Estados
(state diagram) mostra o ciclo de vida de uma classe na forma de
uma troca de estados provocada por eventos internos.
Diagrama de
Seqüência
(sequence diagram) mostra uma série de mensagens entre objetos
organizadas seqüencialmente no tempo. Diagramas de seqüência e
diagramas de colaboração expressam informação semelhante.
Disparo (fire) Causa uma transição de estado.
Domínio
(domain) Uma área de conhecimento ou atividade caracterizada por
um conjunto de conceitos e terminologias aceitas por especialistas
naquela área.
E 
Elemento (element) um componente de um diagrama ou modelo.
Encapsulamento
(encapsulation) conceito fundamental dos objetos, associado ao
fato que um objeto deve possuir todos os dados e as funções
necessárias para sua existência independente.
Engenharia de
software
(software engeineering) é a ciência da computação aplicada na
transformação do computador em uma ferramenta útil, resolvendo
problemas para os seus utilizadores.
Engenheiro de
Software
(software engineer) é o profissional que se utiliza de boas práticas
de engenharia em um projeto de software.
Enumeração 
 
(enumeration) lista de valores identificados por nomes e usados
como uma série para um tipo de atributo em particular.
Especificação (specification) descrição do sistema de software ou de seucomponente, detalhando o que ele faz (ou deve fazer).
Estado
(state) caracteriza uma condição onde o objeto daquela classe pode
ser encontrado. O estado é uma atividade da classe de caráter lento
(estado de ação), e às vezes até estático (estado de espera). Os
eventos provocam a mudança no estado.
Estereótipo 
 
(stereotype) são baseados nos elementos já existentes na UML e 
podem estender a semântica, mas não a estrutura destes elementos.
É um dos mecanismos de extendibilidade na UML.
Evento de
tempo 
(time event) evento que acontece em um momento particular. Pode
ser descrito como uma expressão de tempo.
Eventos
(event) retrata uma atividade rápida e que não pode ser
interrompida. Sempre ocorre um evento entre dois estados. Está
associado às operações das classes, e à sua dinâmica.
Expressão 
 
(expression) Uma seqüência de caracteres que resulta em um valor
de um tipo em particular. Por exemplo, a expressão " (7 + 5 * 3) "
resulta em um valor do tipo numérico.
F 
Foco de controle
(focus of control) símbolo em um diagrama de seqüência que
mostra o período de tempo durante o qual um objeto está executando
uma ação diretamente ou por um procedimento subordinado.
Fornecedor (supplier) Um tipo, classe ou componente que provê serviços quepodem ser invocados por outros.
Framework (framework) micro-arquitetura que provê um modelo extensívelpara aplicações dentro de um domínio específico.
G 
Generalização 
(generalization) relação existente entre um elemento mais geral e
um elemento mais específico de uma classificação. O elemento mais
específico é totalmente consistente com o elemento mais geral e
contém informação adicional. Uma instância do elemento mais
específico pode ser usada sempre que o elemento mais geral for
aceito.
Granularidade
(granularity) característica associada ao tamanho dos elementos de
um modelo, uma granularidade alta caracteriza uma grande
abstração, uma granuladidade baixa leva a um alto nível de
especificação.
GUI Interface Gráfica do Usuário, do inglês Graphics User Interface.
H 
Herança
(inheritance) propriedade das classes de poder serem geradas a
partir de outras classes, herdando delas suas propriedades estáticas
(atributos) e dinâmicas (operações) e relacionamentos.
Herança de
interface
 
(interface inheritance) a herança de interface de um elemento mais
genérico, como uma classe abstrata. Não inclui herança da
implementação que será realizada pela classe que herda a interface.
Herança
múltipla
(multiple inheritance) propriedade das classe em poder herdar de
mais de uma classe ao mesmo tempo. Não é um propriedade
facilmente implementável.
I 
IDE Ambiente Integrado de Desenvolvimento, do inglês: IntegratedDevelopment Environment
Implementação 
(implementation) definição de como algo é construído ou é
processado. Por exemplo, uma classe é a implementação de um tipo,
um código é a implementação (contrução) de uma classe.
Instância
(instance) membro individual de um tipo ou uma classe. Em um uso
menos formal é aceitável se referir a um membro de uma classe
como um objeto ou uma instância. Sinônimos de ocorrência em
alguns casos.
Integração
(integration) ação de colocar partes de um sistema juntas para
formar o todo. A união das partes requer conhecimentos específicos
de configuração e de técnicas de integração.
Interação 
(interaction) conjunto das trocas de mensagem entre um conjunto de
objetos dentro de um contexto particular para realizar um propósito
específico. Uma interação pode ser descrita por um ou mais
cenários.
(interface) descreve o comportamento externamente visível de uma
Interface classe, objeto, componente ou outra entidade. É uma classe formada
apenas por métodos abstratos, servindo para se definir uma forma
de comunicação. Descreve o conjunto de mensagens que as classes
que implementam a interface devem obedecer.
J, K,L 
Linha da vida
de um objeto
(object lifeline) linha em um diagrama de seqüência que representa
a existência de um objeto durante um certo tempo.
M 
Máquina de
estado
(state machine) especifica as sucessões de estados que um objeto
ou uma interação passam durante sua vida, em resposta aos eventos
que recebe.
Membro (member) parte de um tipo ou classe, pode ser representado por umatributo ou uma operação.
Mensagem
(message) comunicação entre objetos que leva informação com a
expectativa que resultará em uma atividade. O recebimento de uma
mensagem é, normalmente, considerado um evento.
Mensagem 
assíncrona 
(asynchronous message) tipo de mensagem onde o objeto
emissor não tem sua execução interrompida para esperar por
resultados.
Mensagem
síncrona
(synchronous message) tipo de mensagem onde o objeto
emissor pausa seu processamento para esperar por resultados.
(method) Os métodos sugerem passos a serem seguidos para
Método cumprir o vazio existente entre a idéia e o produto de software. A
implementação de uma operação. O algoritmo ou procedimento que
afetam os resultados de uma operação.
Modelo
(model) representa, simplificadamente, o que se pretende construir,
como uma planta de uma residência. O modelo mostra não só os
requisitos do problema mas também como eles serão atendidos
pelos elementos da solução.
Modelo
conceitual
(conceptual model) modelo que reúne todos os conceitos presentes
no problema em estudo. Construído em escala menor do que o
modelo de contexto, cria a estrutura do sistema, usando para isso um
modelo simplificado de classes.
Modelo
contextual
(contextual model) representa os aspectos funcionais de alto nível
do sistema, possui uma escala grande o bastante para acomodar
todo o sistema em um único diagrama.
Modelo
detalhado
(detailed model) incorpora todos os detalhes de uma versão
projetada do software. O modelo detalhado pode possuir um nível
dedetalhe equivalente ao código do software.
Multiplicidade
(multiplicity) especifica a abrangência da
cardinalidade permissível que um conjunto pode assumir. Podem
ser dadas multiplicidade para papéis dentro de associações, partes
dentro de composições, repetições e em outros propósitos.
N 
Nó
(node) representam os equipamentos em uma rede de processamento
de dados. As ligações entre os nós representar as associações
físicas e lógicas existentes entre os equipamentos.
Nome (name) seqüência de caracteres que identifica um elemento dos
diagramas.
Nota
(note) um comentário preso a um elemento ou a uma coleção de
elementos. Uma nota não acrescenta um significado ao elemento,
pode no entanto restringí-lo.
O 
Objeto ativo
(active object) objeto que possui uma linha de controle de execução
e pode iniciar o controle de uma atividade. Uma instância de uma
classe ativa.
Objeto emissor (sender [object]) objeto que passa uma mensagem para um objeto
receptor.
Objeto
persistente
(persistent object) objeto que existe depois do processo ou da linha
de controle que o criou, normalmente, associado aos bancos de
dados e arquivos.
Objetos
(object) instância de uma classe, ele implementa a classe para o
sistema. A estrutura do objetos é definida pela classe, mas as
operações e estados (valores dos atributos) são definidos na
instância.
Operação
(operation) responsabilidades atribuídas às classes, associadas ao
que a mensagens que a classe pode receber, e que definem as
funcionalidades que aquela classe está apta a realizar. São
implementadas pelos métodos.
P 
(package) elemento da UML utilizado para agrupar outros
Pacote elementos de um sistema, para organizá-los, um pacote pode abrigar
outros elementos, outros diagramas, e até outros pacotes. Um
sistema pode ser pensado como um único pacote de alto nível.
Papel (role) comportamento específicado por um nome de uma entidadeque participa de um contexto particular.
Parâmetro 
(parameter) variável que pode ser alterada, transmitida ou
retornada, possui nome, tipo e direção. Parâmetros são usados para
operações, mensagens e eventos.
Polimorfismo
(polimorfism) propriedade fundamental da orientação a objetos
associada ao fato de não se precisa conhecer a instância da classe
para utilizar seus serviços. Esta propriedade leva ao fato de que
uma mesma mensagem pode ser interpretada de modos diferentes,
quando for recebida por objetos diferentes.
Pós-condição (postcondition) Uma restrição que deve ser verdadeira naconclusão de uma operação.
Precondição (precondition) Uma restrição que deve ser verdadeira quando umaoperação é invocada.
Problema (problem) Como todo projeto de engenharia, o projeto de softwaretem como principal objetivo resolver um problema.
Processo (process) Uma linha de controle que pode ser executadasimultaneamente com outras linhas de controle.
Processo de
desenvolvimento
(development process) conjunto de passos ordenados executados
para um determinado propósito durante o desenvolvimento de
software, que inclui construir modelos e programar.
Produto 
(product) artefatos construídos durante o processo de
desenvolvimento, como modelos, diagramas, códigos,
documentação e planos de trabalho.
Programador de
computadores
(computer programmer) profissional especializado em criar
programas fonte nas diferentes linguagens de programação
existentes.
Projeto
(design) A parte do processo de desenvolvimento de software cujo
propósito principal é decidir como o sistema será implementado.
Durante o projeto são tomadas decisões estratégicas e táticas para
se encontrar os requisitos funcionais e as exigências de qualidade
de um sistema.
Pseudo-estado 
(pseudo-state) vértices de uma máquina de estado, tem a forma de
um estado, mas não se comportam como um estado como: inicial,
final, e as conexões históricas.
Q 
Qualificador 
(qualifier) atributo ligados à uma relação entre classes, seus
valores limitam o conjunto de objetos que participam da
associação.
R 
Raia (swimlane) pacote presente no diagrama de atividade, que servepara organizar as responsabilidades associadas a um objeto.
Receptor (receiver [object]) objeto endereçado por uma mensagem passadapor um objeto emissor. 
Rede
(network) ligações entre os nós representando as associações
físicas e lógicas existentes entre os equipamentos.
Relação (relationship) conexão de significados existente entre elementos dodiagrama.
Requisito 
(requirement) propriedade ou comportamento desejado de um
sistema. Característica de um problema que deve ser resolvida pelo
sistema.
Responsabilidade(responsabilitiy) o que uma classe deve saber ou saber fazer,correspondem aos atributos e às operações de uma classe.
Restrição (contraint) condição que limita o alcance de um elemento, asrestrições fazem parte dos mecanismos de extensibilidade da UML. 
Reuso
(reuse) O uso de um artefato pre-existente em outro contexto além
daquele para o qual ele foi criado originalmente, economizando
tempo e recursos no processo de desenvolvimento.
S 
Sinal
(signal) evento com um nome, que pode ser invocado
explicitamente, pode ser anunciado ou pode ser dirigido para um
único objeto ou conjunto de objetos.
Sistema (system) união de partes com um objetivo específico de resolver umproblema para o seus usuários. União de hardware e software.
Software
estratégia utilizada para resolver um problema real com apoio de
um computador, vai além de um programa de computador
Subclasse (subclass) especialização de outra classe, a superclasse na relaçãode generalização (herança).
Subsistemas (subsistem) um sistema que é parte de um sistema maior. NaUML um subsistema é modelado como um pacote de componentes.
Superclasse (superclass) Em uma relação de generalização (herança) é ageneralização de outra classe, a sub classe.
Superestados (superstate) agrupamento de estados, e os eventos associados aeles, que possuem um comportamento comum.
T 
Texto (string) seqüência de caracteres.
Thread (trread) caminho de execução de um programa, um modelodinâmico, ou alguma outra representação de fluxo de controle.
Tipo
(type) define uma estrutura de dados e operações que afetam esta
estrutura, sem a preocupação de implementar estas operações. Um
tipo pode definir uma especificação de operação (como uma
assinatura) mas não a sua implementação.
Tipo primitivo
(primitive type) tipo básico de um lingaugem, é pré-definido, como
um inteiro ou um caracter.
Transição
(transition) indica que um objeto no primeiro estado poderá ir para
um segundo estado quando um evento especificado acontecer e
condições específicas forem satisfeitas.
U 
UML Linguagem Unificada de Modelagem do inglês: Unified ModelingLanguage
V 
Valor (value) Um elemento de um domínio de tipo, instância de umatributo.
Valor rotulado
(tagged value) definição explícita de uma propriedade pelo par:
nome-valor. Em um valor rotulado, o nome se refere ao rótulo. O
valor rotulado é um dos mecanismos de extendibilidade em UML. 
Vínculo
(link) conexão de significado entre objetos. A instância de uma
associação, servem de meio para que as mensagens fluam e para a
navegabilidade no diagrama.
Visão
 
(view projection) observação de um modelo a partir de uma
determinada perspectiva ou ponto de vista, omite entidades que não
são pertinentes a esta perspectiva.
Visibilidade
(visibility) capacidade das classes de envolver em uma cápsula
atributos e operações, ocultando ou não a informação de outras
classes que se encontram fora desta cápsula. A visibilidade pode
ser: pública, privada ou protegida.
W, X,Y,Z 
 
APÊNDICE
Códigos Java dos Exemplos citados no livro
Seguem-se extratos dos programas Java que implementam os exemplos
desenvolvidos no livro. O objetivo deste apêndice é mostrar, com um pouco mais de
detalhes os códigos das aplicações desenvolvidas como exemplo para o livro. Os
comentários sobre o código, quando necessário, estão presentes no próprio código. Os
exemplos desenvolvidos para este livros podem ser executados pela internet,no
website www.eduardodeboni.com/uml dedicado a este livro..
 
http://www.eduardodeboni.com/uml
Código Java do Sistema de Vendas da Loja
Classe POS (implementada por uma Applet)
/*
 A basic extension of the java.applet.Applet class
 */
 
import java.awt.*;
import java.applet.*;
 
/**
 * Applet original que chama a interface POS da loja
 *
 * @author JEDeboni
 * @version 1.0
 * @since 13/01/2003
 */
public class POS extends Applet
{
 
 Loja aLoja;
 Produto oproduto="null;"
 Cliente ocliente="null;"
 int parcelas="1;"
 
 
 /**
 * Programa principal de uma Applet.
 * Aqui estão as funçoes de desenhar os componentes da
interface
 * e de acioar os objetos de negocio
 */
 public void init()
 {
 /*
 * Cria os dados da Loja
 */
 
 aLoja = new Loja();
 
 //{{INIT_CONTROLS
 setLayout(new BorderLayout(0,0));
 setSize(445,92);
 panel1.setLayout(new GridLayout(3,4,0,0));
 add(BorderLayout.NORTH,panel1);
 label1.setText("Codigo ");
 label1.setAlignment(java.awt.Label.RIGHT);
 panel1.add(label1);
 panel1.add(textField1);
 button3.setLabel("PRODUTO");
 panel1.add(button3);
 button3.setBackground(java.awt.Color.lightGray);
 panel1.add(textField2);
 label2.setText("CGC ");
 label2.setAlignment(java.awt.Label.RIGHT);
 panel1.add(label2);
 panel1.add(textField3);
 button1.setLabel("CLIENTE");
 panel1.add(button1);
 button1.setBackground(java.awt.Color.lightGray);
 panel1.add(textField4);
 label3.setText("N. parcelas");
 label3.setAlignment(java.awt.Label.RIGHT);
 panel1.add(label3);
 panel1.add(textField5);
 button5.setLabel("PARCELAS");
 panel1.add(button5);
 button5.setBackground(java.awt.Color.lightGray);
 panel1.add(textField6);
 button2.setLabel("Limpar");
 add(BorderLayout.SOUTH,button2);
 button2.setBackground(java.awt.Color.lightGray);
 //}}
 
 //{{REGISTER_LISTENERS
 SymAction lSymAction = new SymAction();
 button1.addActionListener(lSymAction);
 button3.addActionListener(lSymAction);
 button5.addActionListener(lSymAction);
 button2.addActionListener(lSymAction);
 //}}
 }
 
 //{{DECLARE_CONTROLS
 java.awt.Panel panel1 = new java.awt.Panel();
 java.awt.Label label1 = new java.awt.Label();
 java.awt.TextField textField1 = new java.awt.TextField();
 java.awt.Button button3 = new java.awt.Button();
 java.awt.TextField textField2 = new java.awt.TextField();
 java.awt.Label label2 = new java.awt.Label();
 java.awt.TextField textField3 = new java.awt.TextField();
 java.awt.Button button1 = new java.awt.Button();
 java.awt.TextField textField4 = new java.awt.TextField();
 java.awt.Label label3 = new java.awt.Label();
 java.awt.TextField textField5 = new java.awt.TextField();
 java.awt.Button button5 = new java.awt.Button();
 java.awt.TextField textField6 = new java.awt.TextField();
 java.awt.Button button2 = new java.awt.Button();
 //}}
 
 class SymAction implements java.awt.event.ActionListener
 {
 
 /**
 * Captura os eventos da interface e os transfere para a
Applet
 *
 * @param event evento capturado
 */
 public void actionPerformed(java.awt.event.ActionEvent
event)
 {
 Object object = event.getSource();
 if (object == button1)
 button1_ActionPerformed(event);
 else if (object == button3)
 button3_ActionPerformed(event);
 else if (object == button5)
 button5_ActionPerformed(event);
 else if (object == button2)
 button2_ActionPerformed(event);
 }
 }
 
 /**
 * Ação do botão CLIENTE
 * que obtem um Cliente da lista com base no seu CGC
 *
 * @param event
 */
 void button1_ActionPerformed(java.awt.event.ActionEvent
event)
 {
 try{
 int cgc = Integer.parseInt(textField3.getText());
 oCliente = aLoja.getCliente(cgc);
 textField4.setText(oCliente.getNome());
 } catch(Exception e){
 textField4.setText("Erro");
 }
 
 
 
 }
 /**
 * Ação do botão PRODUTO
 * Obtem um produto da lista de produtos com base no codigo
 *
 * @param event
 */
 void button3_ActionPerformed(java.awt.event.ActionEvent
event)
 {
 try{
 int codigo = Integer.parseInt(textField1.getText());
 oProduto = aLoja.getProduto(codigo);
 textField2.setText(oProduto.getDescricao());
 } catch(Exception e){
 textField2.setText("Erro");
 }
 }
 /**
 * Ação do botão PARCELAS
 * Verifica se a venda esta aprovada com base no produto e
 * no cliente ja identificados.
 *
 * @param event
 */
 void button5_ActionPerformed(java.awt.event.ActionEvent
event)
 {
 
 try{
 Parcelas = Integer.parseInt(textField5.getText());
 boolean ok = oProduto.isAprovado(Parcelas, oCliente);
 if (ok) {
 textField6.setText(" Aprovada");
 } else {
 textField6.setText(" Não Aprovada");
 } 
 }catch(Exception e){
 textField6.setText("Erro");
 }
 }
 /**
 * Ação do botão Limpar
 * limpa os campos anteriores para facilitar uma nova
consulta
 *
 * @param event
 */
 void button2_ActionPerformed(java.awt.event.ActionEvent
event)
 {
 // to do: code goes here.
 textField1.setText("");
 textField2.setText("");
 textField3.setText("");
 textField4.setText("");
 textField5.setText("");
 textField6.setText("");
 
 }
}
Classe BDLoja
 
/**
 * Classe auxiliar que inicializa a loja.
 */
public class BDLoja
{
 
 /**
 * Numero de Clientes da Loja
 */
 private int N_CLIENTES;
 
 /**
 * Numero de produtos da lista
 */
 private int N_PRODUTOS;
 
 /**
 * Classe auxiliar que implementa a persistencia dos dados dos
produtos e clientes
 * Eh uma classe que e chamada na in cializaçao da loja.
 * Ela guarda os dados dos clientes em codigo.
 * Em aplicaçoes comerciais deveria ser substituida por acesso
a um banco de dados
 */
 public BDLoja(){
 /*
 Definir a quantidade de dados da loja
 */
 N_CLIENTES = 5;
 N_PRODUTOS = 9;
 }
 
 /**
 * Obtem a lista de produtos da loja, cadastrados na classe
BDLoja
 *
 * @return Array de produtos armazenados na Loja
 */
 public Produto[] getListaP() {
 Produto listaP[] = new Produto[10];
 listaP[1] = new Produto(101,"Guitarra Solo Fender",2000);
 listaP[2] = new Produto(102,"Saxofone",800);
 listaP[3] = new Produto(103,"Bateria Eletrônica",750);
 listaP[4] = new Oferta(104,"Piano de Calda",5000);
 listaP[5] = new Produto(105,"Guitarra Baixo",1000);
 listaP[6] = new Produto(106,"Violão",200);
 listaP[7] = new Produto(107,"Trompete",500);
 listaP[8] = new Produto(108,"Flauta doce",100);
 listaP[9] = new Oferta(109,"Baixo Acústico",1500);
 return listaP;
 }
 
 /**
 * Obtem o Numero de produtos da lista
 *
 * @return Numero de produtos da lista
 */
 public int getNPRODUTOS() {
 return N_PRODUTOS;
 }
 
 /**
 * Obtem a lista de clientes da loja, armazenados na classe
BDLoja
 *
 * @return Array de Clientes
 */
 public Cliente[] getListaC() {
 Cliente listaC[] = newCliente[10];
 listaC[1] = new Cliente(1000,"Stan Getz",1000);
 listaC[2] = new ClienteVIP(2000,"H. Hancock",1000);
 listaC[3] = new Cliente(3000,"Charlie Parker",500);
 listaC[4] = new ClienteVIP(4000,"Charlie Mingus",500);
 listaC[5] = new Cliente(5000,"Miles Davis",300);
 
 return listaC;
 }
 
 /**
 * Obtem o numero de clientes da lista
 *
 * @return Numero de clientes da lista
 */
 public int getNCLIENTES() {
 return N_CLIENTES;
 }
 
}
 
Classe Loja
 
/**
 * Classe que representa a Loja no sistema
 *
 * @author JEDeboni
 * @version 1.0
 * @since 2003
 */
public class Loja
{
 
 /**
 * Array de produtos que implementa um catálogo de produto
 */
 protected Produto listaP[] = new Produto[10];
 
 /**
 * array de clientes, que implementa um catálogo de clientes
 */
 protected Cliente listaC[] = new Cliente[10];
 
 /**
 * Numero de clientes do catalogo
 */
 protected int N_CLIENTES;
 
 /**
 * Numero de produtos do catalogo
 */
 protected int N_PRODUTOS;
 
 /**
 * objeto que representa o banco de dados, da acesso aos dados
persistentes
 */
 BDLoja bd = new BDLoja();;
 
 public Loja(){
 /**
 * Construtor padrao da classe Loja.
 * Aciona os métodos de acesso a lista de clientes e produtos da
classe BDLoja
 */
 listaP = bd.getListaP();
 N_PRODUTOS = bd.getNPRODUTOS();
 listaC = bd.getListaC();
 N_CLIENTES = bd.getNCLIENTES();
 }
 
 /**
 * Pesquisa na lista de produtos um produto com um determinado
indice
 *
 * @param index numero inteiro que indica o indice do produto
na lista
 * O indice deve estar dentro dos limites da lista
 * @return O produto da lista com o indice
 */
 public Produto getProdutoIndex( int index) {
 return (listaP[index]);
 }
 
 /**
 * Método de acesso ao Cliente da lista com base no indice
 *
 * @param index indice do cliente na lista. O indice deve estar
dentro do limite da lista
 * @return um cliente que esta na lista
 */
 public Cliente getClienteIndex( int index) {
 return (listaC[index]);
 }
 
 /**
 * método de acesso ao cliente com base no CGC
 * o método pesquisa a lista de clientes para encontrar o
cliente que possui este CGC
 *
 * @param pCGC numero do CGC
 * @return Um cliente da lista com base no CGC
 */
 public Cliente getCliente(int pCGC){
 Cliente c = null;
 for (int i="1;" i<=N_CLIENTES; i++){
 if (listaC[i].getCGC()==pCGC)
 {
 c = listaC[i];
 }
 }
 return (c);
 }
 
 /**
 * Método de pesquisa da lista de produtos por um produto que
possui um codigo
 *
 * @param pCodigo codigo do produto
 * @return um produto com base no codigo da lista
 */
 public Produto getProduto(int pCodigo){
 Produto p = null;
 for (int i="1;" i<=N_PRODUTOS; i++){
 if (listaP[i].getCodigo()==pCodigo)
 {
 p = listaP[i];
 }
 }
 return (p);
 }
}
Classe Produto
 
/**
 * Classe Produto, representa os produtos vendidos na loja
 *
 * @author JEDeboni
 * @version 1.0
 * @since 2003
 */
public class Produto
{
 private int codigo = 0;
 private int preco = 0;
 private String descricao="";
 
 /**
 * Metodo construtor do produto com base apensas no codigo.
 * Deve-se usar os metodos de acesso para complementar as
informaçoes
 *
 * @param pCodigo codigo do produto.
 */
 public Produto ( int pCodigo) {
 codigo = pCodigo;
 return;
 }
 
 /**
 * metodo contrutor do produto com todos os parametros.
 *
 * @param pCodigo codigo do produto
 * @param pDescricao descricao do produto
 * @param pPreco preco do produto
 */
 public Produto (int pCodigo, String pDescricao, int pPreco) {
 preco = pPreco;
 codigo = pCodigo;
 descricao = pDescricao;
 return;
 }
 
 /**
 * metodo de acesso ao preco do produto
 *
 * @return valor atual do preco do produto
 */
 public int getPreco () {
 return preco;
 }
 
 /**
 * metodo para atualização do preco do produto
 *
 * @param pPreco valor do novo preco do produto
 */
 public void setPreco (int pPreco) {
 preco = pPreco;
 }
 
 /**
 * metodo de acesso a descricao do produto
 *
 * @return a descriçao atual do produto
 */
 public String getDescricao(){
 return(descricao);
 }
 
 /**
 * metodo para atualização da descriçao do produto
 *
 * @param pDescricao nova descricao do produto
 */
 public void setDescricao(String pDescricao){
 descricao = pDescricao;
 }
 
 /**
 * metodo de acesso ao codigo do produto
 *
 * @return o codigo do produto
 */
 public int getCodigo() {
 return codigo;
 }
 
 /**
 * metodo que transforma os dados do produto em uma String de
texto
 * para facilitar a impressao
 *
 * @return String com uma descriçao do produto.
 */
 public String toString() {
 String s = "n";
 s = s + getCodigo();
 s = s + " "+getDescricao();
 s = s + " R$ "+getPreco();
 return s;
 }
 /**
 * método de verificação da aprovação do Crédito
 * verificando as regras de venda a crédito para
 * um dado cliente
 *
 * @param n numero de parcelas da venda
 * @param c objeto que representa o Cliente que e o comprador
do produto
 * @return verdadeiro se a venda foi aprovada e falso se a
venda for recusada
 */
 public boolean isAprovado(int n, Cliente c){
 /*
 em linhas gerais a venda é aprovada se a dívida
 da venda for menor que o crédito do cliente
 */
 int divida = preco - (preco/n);
 // System.out.println("divida = "+divida+ " credito =
"+c.getCredito());
 if (divida <= c.getCredito()) {
 return (true);
 } else {
 return (false);
 }
 }
 
}
Classe Oferta
 
/**
 * Classe que representa um produto em oferta.
 *
 * @author JEDeboni
 * @version 1.0
 * @since 2003
 */
public class Oferta extends Produto
{
 /**
 * método de verificação da aprovação do Crédito
 * verificando as regras de venda a crédito para um cliente
 *
 * @param n numero de parcelas da venda
 * @param c objeto que representa o cliente comprador do
produto
 * @return verdadeiro se a venda for aprovada, ou falso se a
venda nao for aprovada
 */
 public boolean isAprovado(int n, Cliente c){
 int preco = super.getPreco();
 int divida = preco - (preco/n);
 // System.out.println("divida = "+divida+ " credito =
"+c.getCredito());
 if ((divida <= c.getCredito()) || (n<=3)) {
 return (true);
 } else {
 return (false);
 }
 }
 
 public String toString()
 {
 String s = "n";
 s = s + getCodigo();
 s = s + " "+getDescricao();
 s = s + " R$ "+getPreco()+" EM OFERTA";
 return s;
 }
 
 /**
 * Construtor de um produto em Oferta
 *
 * @param pCodigo codigo do produto
 * @param pDescricao descrição do produto
 * @param pPreco preço do produto
 */
 public Oferta (int pCodigo, String pDescricao, int pPreco) {
 super (pCodigo, pDescricao, pPreco);
 return;
 }
 
}
Código Java do Jogo da Velha
Segue-se o código completo do jogo da velha na sua implementação básica.
Classe Forca
import javax.swing.JOptionPane;
 
/**
 * Classe principal, que integra as outras na implementaçao do
jogo
 *
 * @author JEDeboni
 * @version 1.0
 */
public class Forca {
 /**
 * objeto boneco usado no jogo
 */
 private static Boneco boneco = new Boneco();
 
 /**
 * objeto ppalavra que implementa a Palavra secreta no jogo
 */
 private static Palavra palavra = new Palavra();
 
 /*** objeto j que representa o jogador no jogo
 */
 private static Jogador jogador = new Jogador();
 /**
 * programa principal do jogo da forca
 *
 * @param arg não é utilizado
 */
 
 public static void main(String arg[]){
 char letra; 
 String tela="";
 palavra.escolheSecreta();
 do {
 //
 // constroi o desenho da forca,
 // da palava e das letras usadas
 tela = boneco.desenha()+"n"
 +palavra.desenha()+"n"
 +jogador.getLetrasChutadas();
 //
 // captura uma letra entrada pelo usuario
 letra="JOptionPane".showInputDialog(tela).toCharArray()[0];
 //
 // Envia mensagem ao jogador para entrar a letra no jogo
 jogador.chutaLetra(letra, palavra, boneco); 
 }while(!(jogador.ganhar(palavra)||jogador.perder(boneco)));
 //
 // envia uma mensagem final
 if (jogador.ganhar(palavra))
 {
 tela = tela + "n Parabens! ganhou!";
 };
 if (jogador.perder(boneco)) 
 {
 tela = tela + "n Que pena, perdeu!";
 };
 JOptionPane.showMessageDialog(null,tela,
 "Jogo da Forca",JOptionPane.INFORMATION_MESSAGE);
 
 System.exit(0);
 }
}
Código da Classe Palavra
 import java.io.*;
 
/**
 * Representa a palavra secreta no jogo da forca.
 * A classe permite escolher uma palavra de uma lista arquivada
 * e verificar se a letra esta n palavra
 *
 * @author JEDeboni
 * @version 1.0
 * @since 2002
 */
public class Palavra 
{
 
 /**
 * array com as letras da palavra escolhida que e mantida
secreta
 */
 private char[] palavraEscolhida = new char[100];
 
 /**
 * array com as letras ja descobertas da palavra
 */
 private char[] palavraDescoberta = new char[100];
 
 /**
 * numero de letras existente na palavra escolhida
 */
 private int np = 0;
 
 /**
 * seleciona aleatoriamente uma palavra de uma lista
 * armazenada em no arquivo ListaPalavras e
 * inicializa a palavra a ser descoberta com '_'
 * vao existir tantos tracos quantas letras na palavra
 */
 public void escolheSecreta () {
 String linha[] = new String[200];
 try
 {
 //
 // abre o arquivo
 FileInputStream ds = new
FileInputStream("ListaPalavras.txt");
 DataInputStream arquivo = new DataInputStream(ds);
 //
 // le as palavras do arquivo
 int i="-1;"
 do
 {
 i++;
 linha[i]=arquivo.readLine();
 } while (linha[i]!=null);
 int lp="i-1;" // numero de palavras no arquivo 
 //
 // escolhe uma palavra da lista e mede o seu tamanho
 int iescolhido = new Double(Math.random()*lp).intValue();
 np="linha"[iescolhido].length();
 //
 // preenche de espaços "_" a palavra descoberta
 for (i="0;" i<np; i++){
 palavraEscolhida[i+1]=linha[iescolhido].toCharArray()
[i];
 palavraDescoberta[i+1]='_';
 }
 } catch (IOException e)
 {
 System.out.println("Erro na leitura do arquivo de
palavras");
 System.out.println(e);
 }
 }
 
 /**
 * metodo para desenhar a palavra secreta
 *
 * @return retorna um texto com a palavra secreta
 * tracos marcam as letras nao descobertas
 */
 public String desenha()
 {
 String linha=" ";
 for (int i="1;" i<=np; i++) {
 linha = linha + palavraDescoberta[i]+" ";
 }
 return(linha);
 }
 /**
 * verifica se a letra esta na palavra secreta
 *
 * @param letra letra a ser testada na palavra
 * @return verdadeiro se a letra está na palavra ou falso se
nao esta
 */
 public boolean letraNaPalavra (char letra)
 {
 boolean achou="false;"
 for (int i="1;" i<=np; i++){
 if (letra==palavraEscolhida[i]){
 achou="true;"
 palavraDescoberta[i]=letra;
 }
 }
 return(achou);
 }
 
 /**
 * verifica se a palavra esta completa ou nao
 * procurando espaços "_" na palavra a ser descoberta
 *
 * @return falso se a palavra esta incompleta ou verdadeiro
esta completa
 */
 public boolean isCompleta ()
 {
 boolean ok = true;
 for (int i="1;" i<=np; i++)
 {
 if (palavraDescoberta[i]=='_')
 {
 ok = false;
 }
 }
 return(ok);
 }
 
 /**
 * metodo construtor da Palavra
 */
 public Palavra ()
 {
 // não existe construção especial para a palavra
 }
}
Classe Jogador
/**
 * Representa o Jogador no jogo da forca
 * Permite que o jogador interaja com o jogo chutando as letras
para adivinhar a palavra secreta
 * Esta classe ainda guarda a palavra secreta
 *
 * @author JEDeboni
 * @version 1.0
 */
public class Jogador 
{
 
 /**
 * numero de letras chutadas até o momento
 */
 private int iletra="0;"
 
 /**
 * lista de letras chutadas no jogo
 */
 private char[]letrasChutadas = new char[50];
 
 
 /**
 * retorna uma lista das letras chutadas no jogo
 *
 * @return uma lista das letras chutadas
 */
 public String getLetrasChutadas(){
 String linha="Letras usadas: ";
 for (int i="1;" i<=iLetra; i++)
 {
 linha="linha"+letrasChutadas[i];
 }
 return(linha);
 }
 
 /**
 * adiciona uma letra na lista de letras chutadas
 *
 * @param letra letra a ser adicionada na lista
 */
 public void addLetrasChutadas(char letra){
 iletra="iLetra"+1;
 letrasChutadas[iLetra]=letra;
 }
 
 /**
 * le uma letra para tentar completar a palavra secreta e
 * verifica se a letra esta na palavra, e desenha uma parte do
 * boneco se não tiver.
 *
 * @param letra letra a ser verificada
 * @param palavra palavra a ser descoberta
 * @param boneco boneco que representa o jogador na forca
 */
 public void chutaLetra (char letra, Palavra palavra, Boneco
boneco)
 {
 addLetrasChutadas(letra);
 if (!palavra.letraNaPalavra(letra))
 {
 boneco.addParte();
 }
 }
 
 /**
 * operaçao que verifica se o jogador ganhou
 *
 * @param palavra palavra a ser descoberta, se for completa o
jogador ganhou
 * @return verdadeiro de o jogador ganhou, falso se não ganhou
 */
 public boolean ganhar(Palavra palavra)
 {
 return(palavra.isCompleta());
 }
 
 /**
 * Operaçao que verifica se o jogador perdeu
 *
 * @param boneco boneco que representa o jogador, se for
completo o jogador perdeu
 * @return verdadeiro de o jogador perdeu, falso se não perdeu
 */
 public boolean perder(Boneco boneco)
 {
 return(boneco.isCompleto());
 }
 
 /**
 * contrutor do Jogador, nao possui parametros
 */
 public Jogador ()
 {
 // não existe construtor especial para o Jogador
 }
 
}
 
Classe Boneco
/**
 * Representa o boneco do jogo da forca
 *
 * @author JEDeboni
 * @version 1.0
 * @since 2002
 */
public class Boneco 
{
 /**
 * numero de partes desenhadas do boneco.
 * Começa com zero e termina com 6 (boneco completo)
 */
 private int parte="0;"
 
 /**
 * Matriz de 3x3 que desenha a forca
 */
 private char[][] Dforca = new char[4][4];
 
 /**
 * inicializa a forca, zerando a matriz Dforca
 * uso privado internamente ao boneco
 */
 private void limpaForca ()
 {
 parte = 0;
 Dforca[1][1]=' '; Dforca[1][2]=' '; Dforca[1][3]=' ';
 Dforca[2][1]=' '; Dforca[2][2]=' '; Dforca[2][3]=' ';
 Dforca[3][1]=' '; Dforca[3][2]=' '; Dforca[3][3]=' ';
 }
 
 /**
 * inclui mais uma parte no boneco, o boneco esta previsto para
 * ser construido com 6 partes
 */
 public void addParte()
 {
 parte="parte"+1;
 if (parte==1) Dforca[1][2]='O'; // desenha cabeça
 if (parte==2) Dforca[2][1]='/'; // desenha bracoE
 if (parte==3) Dforca[2][2]='|'; // desenha corpo
 if(parte==4) Dforca[2][3]='';// desenha bracoD
 if (parte==5) Dforca[3][1]='/'; // desenha pernaE
 if (parte==6) Dforca[3][3]='';// desenha pernaD
 }
 
 /**
 * desenha o boneco na forma de texto
 *
 * @return texto com o desenho de um boneco e da forca feito
com caracteres
 */
 public String desenha()
 {
 String linha = "n /-----";
 linha = linha + "n | "+Dforca[1][1]+Dforca[1][2]+Dforca[1]
[3];
 linha = linha + "n | "+Dforca[2][1]+Dforca[2][2]+Dforca[2]
[3];
 linha = linha + "n | "+Dforca[3][1]+Dforca[3][2]+Dforca[3]
[3];
 linha = linha + "n | ";
 linha = linha + "n |_________";
 return(linha);
 }
 
 
 /**
 * verifica se o boneco esta completo
 *
 * @return verdadeiro se o boneco esta completo ou false se nao
estiver
 */
 public boolean isCompleto() {
 if (parte==6) {
 return(true);
 } else {
 return(false);
 }
 }
 
 /**
 * método construtor da classe Boneco
 * este metodo limpa a forca e prepara para colocar um boneco
 * a forca e representada por uma matrix 3x3 Dforca
 */
 public Boneco ()
 {
 limpaForca();
 }
}
 
Código Java do Item de Estoque
Classe Almoxerife
import java.awt.*;
import java.applet.*;
 
/**
 * Classe de interface do sistema itemEstoque,
 * realiza as açoes de capturar os eventos do usuário,
 * enviar mensagens para a classe de negocio e
 * exibir o resultado na interface
 *
 * @author JEDeboni
 * @version 1.0
 * @since 2003
 */
public class Almoxerife extends Applet
{
 
 /**
 * objeto que representa o item de estoque a ser gerenciado
 */
 ItemEstoque item;
 
 /**
 * objeto que representa o comprador que gerencia este item de
estoque
 */
 Compras comprador;
 
 /**
 * operaçao de inicializaçao da Applet Almoxerife
 */
 public void init()
 {
 //{{INIT_CONTROLS
 setLayout(new BorderLayout(0,0));
 setSize(426,266);
 panel1.setLayout(new FlowLayout(FlowLayout.CENTER,5,5));
 add(BorderLayout.NORTH, panel1);
 label1.setText("Almoxerife: quantidade");
 panel1.add(label1);
 textField1.setText("0");
 panel1.add(textField1);
 btnRetirar.setLabel("Retirar");
 panel1.add(btnRetirar);
 btnRetirar.setBackground(java.awt.Color.lightGray);
 btnRepor.setLabel("Repor");
 panel1.add(btnRepor);
 btnRepor.setBackground(java.awt.Color.lightGray);
 textArea1.setText("Historico das transações");
 add(BorderLayout.CENTER, textArea1);
 panel2.setLayout(new FlowLayout(FlowLayout.CENTER,5,5));
 add(BorderLayout.SOUTH, panel2);
 label2.setText("Mensagem ao comprador");
 panel2.add(label2);
 panel2.add(textField2);
 //}}
 
 comprador = new Compras();
 item = new ItemEstoque("101010", "Tonner de copiadora",
100, 70, 50, comprador);
 textArea1.append(item.toString());
 
 //{{REGISTER_LISTENERS
 SymAction lSymAction = new SymAction();
 btnRetirar.addActionListener(lSymAction);
 btnRepor.addActionListener(lSymAction);
 //}}
 }
 
 //{{DECLARE_CONTROLS
 java.awt.Panel panel1 = new java.awt.Panel();
 java.awt.Label label1 = new java.awt.Label();
 java.awt.TextField textField1 = new java.awt.TextField(2);
 java.awt.Button btnRetirar = new java.awt.Button();
 java.awt.Button btnRepor = new java.awt.Button();
 java.awt.TextArea textArea1 = new java.awt.TextArea();
 java.awt.Panel panel2 = new java.awt.Panel();
 java.awt.Label label2 = new java.awt.Label();
 java.awt.TextField textField2 = new java.awt.TextField(25);
 //}}
 
 class SymAction implements java.awt.event.ActionListener
 {
 
 /**
 * operaçao para capturar os eventos da interface
 *
 * @param event evento vindo do usuário e
 * que devem ser tratados pela classe
 */
 public void actionPerformed(java.awt.event.ActionEvent
event)
 {
 Object object = event.getSource();
 if (object == btnRetirar)
 btnRetirar_ActionPerformed(event);
 else if (object == btnRepor)
 btnRepor_ActionPerformed(event);
 }
 }
 
 /**
 * operacao que trata o evento de Retirar,
 * le o valor da quantidade a ser retirada, 
 * envia uma mensagem de retirar para o itemEstoque e
 * exibe o resultado na interface
 *
 * @param event evento vindo da açao do usuário
 */
 void btnRetirar_ActionPerformed(java.awt.event.ActionEvent
event)
 {
 int n = Integer.parseInt(textField1.getText());
 if (item.retirarMaterial(n))
 {
 textArea1.append("nn*** Ação : Retirar "+n);
 } else
 {
 textArea1.append("nn*** Ação de Retirar bloqueada");
 } 
 textArea1.append(item.toString());
 textField2.setText(comprador.getMensagens());
 }
 
 /**
 * operaçao que trata o evento de repor,
 * envia uma mensagem de repor para o itemEstoque e
 * exibe o resultado na interface
 *
 * @param event evento vindo da interface do usuario
 */
 void btnRepor_ActionPerformed(java.awt.event.ActionEvent
event)
 {
 int n = Integer.parseInt(textField1.getText());
 if (item.reporMaterial(n))
 {
 textArea1.append("nn*** Ação : Repor "+n);
 } else {
 textArea1.append("nn*** Ação de Repor bloqueada");
 } 
 textArea1.append(item.toString());
 textField2.setText(comprador.getMensagens());
 }
}
Classe ItemEstoque
 
/**
 * Representa o item de um sistema de estoque gerenciado
 * A regra de controle de estoque nao permite
 * que se faça uma retirada se o estoque estiver baixo.
 *
 * @author JEDeboni
 * @version 1.0
 * @since 2003
 */
public class ItemEstoque 
{
 private int qtd = 0;
 
 /**
 */
 private int qtdReposicao = 0;
 private int estoqueMinimo = 0;
 private String descricao="";
 private String codigo="";
 private Compras comprador;
 
 /**
 * Metodo construtor do item de estoque,
 * com todos os atributos como parametros
 *
 * @param pCodigo Codigo unico do item de estoque,
 * @param pDescricao Descriçao textual breve do item
 * @param pQtd Quantidade armazenada no item,
 * nao pode ser menor do que o estoque minimo.
 * @param pQtdReposicao Quantidade que deve ser reposta
 * @param pEstoqueMinimo Valor do estoque minimo do item, ao
atingir o estoque minimo e' disparada ao comprador um pedido de
compra
 * @param pComprador Objeto do tipo Compras que representa o
comprador responsavel por repor este item.
 */
 public ItemEstoque(String pCodigo,
 String pDescricao,
 int pQtd,
 int pQtdReposicao,
 int pEstoqueMinimo,
 Compras pComprador)
 {
 codigo = pCodigo;
 descricao = pDescricao;
 qtd = pQtd;
 qtdReposicao = pQtdReposicao;
 estoqueMinimo = pEstoqueMinimo;
 comprador = pComprador;
 }
 
 
 /**
 * metodo chamado para retirada dos itens do estoque
 *
 * @param n quantidade de itens a serem retirados
 * @return verdadeiro se o material foi retirado
 * <br> ou falso se o material nao foi retirado
 */
 public boolean retirarMaterial(int n)
 {
 boolean ok="false;"
 if (isBaixo()) 
 {
 comprador.setMensagens("Estoque Baixo");
 } else 
 {if (qtd>=n) {
 qtd = qtd - n;
 ok = true;
 }
 if (qtd<estoqueMinimo) {
 comprador.comprar(this);
 }
 }
 return(ok);
 }
 
 
 /**
 * metodo chamado na reposicao dos itens no estoque
 *
 * @param n quantidade de itens a ser reposta,
 * mantida para haver coerencia com a retirada,
 * (deve ser sempre igual aa qtdReposicao)
 * @return verdadeiro se a houver a reposicao do material
 * <br> falso se a reposicao não ocorrer porque o estoque
estava normal
 */
 public boolean reporMaterial (int n)
 {
 boolean ok = false;
 if (isBaixo())
 { 
 qtd = qtd + getQtdReposicao();
 comprador.setMensagens("material reposto");
 ok = true;
 }
 return(ok);
 }
 
 
 /**
 * Metodo de acesso a quantidade de itens de estoque
 *
 * @return quantidade em estoque
 */
 public int getQtd ()
 {
 return(qtd);
 }
 
 /**
 * metodo de acesso a quantidade de reposicao
 *
 * @return quantidade a ser reposta
 */
 public int getQtdReposicao ()
 {
 return(qtdReposicao);
 }
 
 /**
 * metodo de acesso ao valor do estoque minimo
 *
 * @return quantidade de estoque minimo
 */
 public int getEstoqueMinimo ()
 {
 return(estoqueMinimo);
 }
 
 /**
 * operaçao de acesso a descricao do item
 *
 * @return descricao do item
 */
 public String getDescricao()
 {
 return(descricao);
 }
 
 /**
 * operação de definiçao da quantidade de reposicao
 *
 * @param pQtdReposicao nova quantidade de reposicao
 */
 public void setQtdReposicao (int pQtdReposicao)
 {
 qtdReposicao = pQtdReposicao;
 }
 
 /**
 * operacao de definicao do estoque minimo
 *
 * @param pEstoqueMinimo novo valor do estoque minimo
 */
 public void setEstoqueMinimo (int pEstoqueMinimo)
 {
 estoqueMinimo = pEstoqueMinimo;
 }
 
 /**
 * operacao que verifica se o estoque esta atualmente baixo
 *
 * @return verdadeiro se o estoque esta baixo,
 * <br> e falso se o estoque estiver normal
 */
 public boolean isBaixo()
 {
 boolean ok = false;
 if (getQtd()<getEstoqueMinimo()) {
 ok = true;
 }
 return(ok);
 }
 
 /**
 * operacao que fornece uma descricao textual do item
 *
 * @return texto que descreve o item em seu estado atual.
 */
 public String toString()
 {
 String s = "n"+codigo+" Item : "+descricao+
 "n Estoque = "+qtd+" Mínimo =
"+estoqueMinimo+" Reposicao = "+qtdReposicao+
 "n Estoque baixo : "+isBaixo();
 return(s); 
 }
}
Classe Comprador
 
/**
 * Classe que representa o setor de compras da empresa.
 * Neste exemplo ira apenas guardar as mensagens recebidas
 * pelo item de Estoque
 *
 * @author JEDeboni
 * @version 1.0
 * @since 2003
 */
public class Compras
{
 /**
 * mensagem que indica a atividade (estado) do comprador
 */
 private String mensagens;
 
 /**
 * metodo contrutor do objeto da classe Compras,
 * inicia informando que nao ha mensagens no comprador
 */
 public Compras()
 {
 mensagens = "não há mensagens";
 } 
 
 /**
 * le as mensagens do comprador
 *
 * @return mensagem armazenada no comprador
 */
 public String getMensagens()
 {
 return(mensagens);
 }
 
 /**
 * define uma mensagem para o comprador
 *
 * @param pMensagens nova mensagem para armazenar
 */
 public void setMensagens(String pMensagens)
 {
 mensagens = pMensagens;
 }
 
 
 /**
 * operacao de comprar,
 * futuramente devera implementar os processos de compras
 *
 * @param item ItemEstoque a ser comprado
 */
 public void comprar(ItemEstoque item)
 {
 setMensagens("comprar "+item.getQtdReposicao()+"
"+item.getDescricao()); 
 }
 
}
Notas de Rodapé
[1] Adaptação do software ao cliente, originaria da palavra: customer, cliente em
inglês.
[2] CGC – Cadatro Geral de Contribuinte, substituído pelo CPF, Cadastro de
Pessoas Físicas, um número único que identifica os contribuintes do Imposto de Renda,
e que é usado para identificar unicamente o cliente.
[3] As funções são escritas usando uma convenção de notação em inglês: get para
obter, set para definir e is para verificar se é falso ou verdadeiro.
[4] A expressão super.getCredito( ) significa, na linguagem Java, que se está
chamando o método getrCredito da classe mãe (super). No caso o método getCredito da
classe ClienteVIP chama o método getCredito da classe Cliente
[5] Object_Oriented Systems, Languages e Applications. Conferência annual sobre a
tecnologia de objetos.
[6] CRC significa Class, Responsability and Colaboration. Em alguns artigos tem
sido encontrato tambem Contract no lugar de Colaboration, mas com um significado
equivalente.
[7] Object Managment Group, organização de padronização de assuntos ligados à
orientação à objetos.
[8] Optou-se por não acentuar os nomes das classes, atributos e operações para
facilitar a transição do modelo para códigos, já que a maioria das linguagens de
implementação não dá suporte à acentuação dos seus componentes.
[9] GUI do inglês, Graphics User´s Interface, interface gráfica do usuário
	Dedicatória
	A quem se destina este livro
	Convenções adotadas neste livro
	1. Introdução
	1.1. Introdução ao Desenvolvimento de Software
	1.2. Como este livro está organizado
	1.3. A importância da modelagem
	2. Fundamentos da Modelagem Orientada a Objetos
	2.1. Processo de Desenvolvimento de Software
	2.1.1. Ciclo de teste do software
	2.1.2. Ciclo de desenvolvimento do software
	Fase de Análise
	Fase de Design
	Fase de Construção doms Componentes
	Fase de Integração
	2.2. Modelos de um Software
	2.3. Documento de Especificação de Projeto
	2.4. A Modelagem Orientada a Objetos
	2.4.1. Encapsulamento
	2.4.2. Mensagens
	2.4.3. Tipos, Classes e Objetos
	2.4.4. Herança
	2.4.5. Polimorfismo
	2.4.6. Vantagens da Orientação a Objetos
	2.5. Estudo de Caso: Automação de Vendas
	2.5.1. Contexto do Problema
	Arquitetura do Sistema
	Regras de negócio
	2.5.2. Modelo Conceitual
	Fase 1 - Identificação do Produto
	Fase 2 - Identificação do Cliente
	Fase 3 - Autorização do Crédito, para vendas à Prazo
	Encapsulamento
	Integração com Banco de Dados
	Mensagens
	Herança
	3. Modelo de Contexto
	3.1. Introdução
	3.2. Pacotes, Sistemas e Subsistemas
	3.3. Modelo de Contexto
	3.3.1. Diagrama de Casos de Uso
	3.3.2. Atores
	Representação
	Exemplo
	3.3.3. Caso de Uso
	Representação Gráfica
	Descrição Textual
	Colaboração entre os Casos de Uso
	3.3.4. Considerações Gerais sobre o Modelo de Contexto
	Independência entre Casos de Uso
	Granularidade dos Casos de Uso
	Evitar a decomposição de casos de uso
	Integrar o cliente na modelagem
	Comprometimento com a implementação
	Casos de Uso em Testes
	Cuidados nas descrições textuais
	3.4. Exemplo de Aplicação: Sistema de Vendas de Loja
	3.4.1. Descrição de Subsistemas
	3.4.2. Descrição dos Casos de Uso
	Identificar Cliente
	Identificar Produto
	Autorizar parcelamento
	4. Modelo Conceitual
	4.1. Introdução ao Modelo Conceitual
	4.2. Diagrama de Classes
	4.2.1. Relacionamento entre as classes
	4.2.2. Dependência
	4.2.3. Associação
	4.2.4. Agregação
	4.2.5. Herança
	4.3. A técnica dos cartões CRC
	4.3.1. Histórico do cartão CRC
	4.3.2. Vantagens do trabalho em equipe
	4.3.3. Objetivos dos cartões CRC
	4.3.4. Organização para aplicação da técnica
	4.3.5. Formação da equipe de trabalho
	4.3.6. Brainstorm para especificação do sistema
	4.3.7. Identificar as classes candidatas
	4.3.8. Analisar os resquisitos
	4.3.9. Distribuir as responsabilidade
	4.3.10. Caracterizar os colaboradores
	4.3.11. Simular a dinâmica do cenário4.3.12. Traduzindo os cartões em classes UML
	4.3.13. Vantagens da técnica dos cartões CRC
	4.4. Estudo de Caso: Jogo da Forca
	4.4.1. Modelo de Contexto
	Diagrama de Casos de Uso
	Ator: Jogador representa os jogadores �⠀甀猀甀爀椀漀猀) do sistema de jogo da forca.
	Ator: Lista de Palavras representa a lista de palavras armazenadas para alimentar o jogo. É um ator passivo, imutável, que só fornece informações.
	Casos de Uso: Novo Jogo Objetivo principalUm novo jogo da forca em computador,exige que se selecione uma palavra secreta escolhida automaticamente de uma lista de palavras já existente.Cenário de exceçãoA lista de palavras não existe ou não pode ser encontrada, impedindo a continuidade do jogo.
	Caso de Uso: Chutar Letras Objetivo principal:O jogador chuta letras para tentar acertar a palavra secreta.Cenário alternativo 1A cada letra errada, ele perde uma parte do corpo do boneco. Ao completar todas as partes do corpo do boneco o jogador perde.Cenário alternativo 2A cada letra certa a palavra vai se desenhando na tela. Ao descobrir todas as letras e descobrir a palavra secreta, o jogador vence o jogo.
	4.4.2. Modelo Conceitual
	Brainstorm
	Distribuição das Responsabildiades
	4.4.3. Cartões CRC
	4.4.4. Tradução dos Cartões em Classes
	5. O Modelo Detalhado
	5.1. Introdução aos modelos detalhados da UML
	5.1.1. Histórico da UML
	5.1.2. Os diagramas da UML
	5.2. Diagrama de classes
	5.2.1. Nomes
	5.2.2. Visibilidade
	5.2.3. Instanciamento de Classes em Objetos
	5.2.4. Classes concretas, abstratas e interfaces
	5.2.5. Adorno dos relacionamentos
	5.3. Diagramas de Interação
	5.3.1. Mensagens
	5.3.2. Diagrama de Seqüência
	5.3.3. Diagrama de Colaboração
	5.4. Diagrama de Estados
	5.4.1. Evento
	5.4.2. Estados
	5.4.3. Superestados
	5.4.4. Eventos e operações, estados e atributos
	5.4.5. Diagrama de estado de uma interface
	5.5. Diagrama de Atividades
	5.5.1. Trilhas de Responsabilidades
	5.6. Diagramas de Implementação
	5.6.1. Diagrama de Componentes
	5.6.2. Diagramas de Distribuição
	5.7. Integração entre os Diagramas
	5.7.1. Integração entre os diagramas de classes e seqüência
	5.7.2. Integração entre os diagramas de classes e estados
	6. Estudo de Casos
	6.1. Introdução
	6.1.1. Estrutura de camadas dos sistema
	6.2. Estudo de Caso: Sistema de Vendas de Loja
	6.2.1. Modelo Conceitual
	6.2.2. Modelo Detalhado
	Diagramas de Interação
	Diagrama de Classes Detalhado
	Projeto da Interface
	Expansão do sistema
	6.3. Estudo de Caso: Jogo da Forca
	6.3.1. Modelo Detalhado da Implementação Básica
	Diagramas de Seqüência
	Diagrama de Classes Detalhado
	Código Java da classe Boneco
	Diagramas de Estado do Jogador
	Diagrama de Estado da classe Boneco
	Detalhamento da classe Forca
	6.3.2. Modelo Detalhado da Implementação WEB
	Implementar um acesso remoto à lista de palavras
	Criar uma interface gráfica
	Exemplo da interface resultante
	6.4. Estudo de Caso: Modelo de um item de estoque
	6.4.1. Modelo de Contexto
	Retira Itens do Estoque
	Repõe Itens do Estoque
	6.4.2. Modelo Conceitual
	6.4.3. Modelo Detalhado
	7. Conclusões
	7.1. Referências Bibliograficas
	7.2. Endereços da Internet
	Glossário
	APÊNDICE
	Códigos Java dos Exemplos citados no livro
	Código Java do Sistema de Vendas da Loja
	Classe POS �⠀椀洀瀀氀攀洀攀渀琀愀搀愀 瀀漀爀 甀洀愀 䄀瀀瀀氀攀琀)
	Classe BDLoja
	Classe Loja
	Classe Produto
	}
	Classe Oferta
	Código Java do Jogo da Velha
	Classe Forca
	Código da Classe Palavra
	Classe Jogador
	Classe Boneco
	Código Java do Item de Estoque
	Classe Almoxerife
	Classe ItemEstoque
	Classe Comprador

Mais conteúdos dessa disciplina