programação orientada a objetos

69
Programação Orientada a Objetos Projeto de Classes

Upload: margo

Post on 23-Feb-2016

56 views

Category:

Documents


0 download

DESCRIPTION

Programação Orientada a Objetos. Projeto de Classes. Agenda. Projeto baseado na responsabilidade Acoplamento Explícito Implícito Coesão Classes Métodos Refatoração. Projeto. O que torna um projeto bom ou ruim ? Bons projetos Exigem mais esforços à curto prazo . - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Programação Orientada  a  Objetos

Programação Orientada a Objetos

Projeto de Classes

Page 2: Programação Orientada  a  Objetos

Projeto baseado na responsabilidade Acoplamento

◦ Explícito◦ Implícito

Coesão◦ Classes◦ Métodos

Refatoração

Agenda

Page 3: Programação Orientada  a  Objetos

O que torna um projeto bom ou ruim? Bons projetos

◦ Exigem mais esforços à curto prazo.◦ A longo prazo, os esforços são justificados.

Implementação pode realizar suas tarefas com classes mal projetadas.◦ O fato de executar uma aplicação não indica se

ela esta bem estruturada ou não.

Projeto

Page 4: Programação Orientada  a  Objetos

Princípios que devem ser seguidos:◦ Projeto baseado na responsabilidade.◦ Encapsulamento.◦ Fraco acoplamento.◦ Alta coesão.

Princípios

Page 5: Programação Orientada  a  Objetos

Surgem em geral quando:◦ Programador de manutenção tenta fazer algumas

alterações Corrigir uma falha. Adicionar nova funcionalidade.

Classes bem projetadas:◦ Tarefa fácil e óbvia.

Classes mal projetadas:◦ Tarefa muito difícil e envolve muito trabalho.

Problemas

Page 6: Programação Orientada  a  Objetos

Grandes aplicações◦ Tais problemas ocorrem durante a implementação

original.◦ Se o projeto começa com uma estruturação ruim,

terminá-lo pode ser muito complexo Programa não pode ser terminado. Pode conter falhas. Demorar muito mais do que necessário para ser

construído.

Problemas

Page 7: Programação Orientada  a  Objetos

Muitos dos efeitos de um projeto ruim se tornam evidentes quando se tenta:◦ Adaptar.◦ Estender.

Adaptar e estender uma aplicação

Page 8: Programação Orientada  a  Objetos

World-of-Zuul

Page 9: Programação Orientada  a  Objetos

Classes bem documentadas Ilustra que projeto ruim envolve algo mais profundo

que simplesmente a aparência da classe ou quanto é boa sua documentação.

World-of-Zuul

Page 10: Programação Orientada  a  Objetos

Qualidade de um projeto de classe:◦ Acoplamento (coupling)

Refere-se a interconectabilidade da classe. Objetos cooperam via interfaces bem definidas. O grau de acoplamento indica a firmeza que essas

classes estão conectadas. Um bom projeto de classe visa:

Baixo grau de acoplamento Acoplamento fraco

O grau de acoplamento indica como é difícil fazer alterações

Introdução a Acoplamento

Page 11: Programação Orientada  a  Objetos

Uma alteração em uma classe pode tornar necessário alterar várias outras classes

Deve-se evitar isso, pois o efeito de fazer uma alteração pequena pode facilmente se propagar por toda a aplicação

Além disso, localizar todos os lugares onde as alterações devem ser feitas e realmente fazer as alterações pode ser difícil e demorados

Classes fortemente acopladas

Page 12: Programação Orientada  a  Objetos

Pode-se alterar uma classe sem fazer nenhuma alteração em outras classes.

Classes fracamente acopladas

Page 13: Programação Orientada  a  Objetos

Número e diversidade de tarefas pelas quais uma unidade de uma aplicação é responsável◦ Classes.◦ Métodos.

Ideal◦ Uma unidade de código deve ser responsável por

uma unidade coesa (uma tarefa que pode ser vista com uma entidade lógica) Um método deve implementar uma operação lógica Uma classe deve representar um tipo de entidade

Introdução a Coesão (cohesion)

Page 14: Programação Orientada  a  Objetos

Coesão visa reutilização◦ Se um método ou uma classe é responsável por

apenas uma coisa bem definida◦ Bem mais provável que ele possa ser utilizado

novamente em um contexto diferente.

Reutilização

Page 15: Programação Orientada  a  Objetos

Quando alguma alteração é necessária, é provável que encontre-se todas as partes relevantes localizadas na mesma unidade

Vantagem complementar de Coesão

Page 16: Programação Orientada  a  Objetos

Forte indicador de projeto ruim Problemas:

◦ Qualquer alteração em uma parte deve ser feita na outra, caso contrário, a aplicação fica inconsistente.

◦ Aumenta o trabalho que um programador de manutenção tem de fazer e introduz perigo de bugs. O programador pode não achar cópia do código, não

alterá-la e assumir que o trabalho esta concluído. Não há nada que indique que uma segunda cópia do

código existe Sintoma de má coesão

Duplicação de Código

Page 17: Programação Orientada  a  Objetos

Métodos printWelcome() e goRoom() da classe Game

System.out.println("You are " + currentRoom.getDescription());

System.out.print("Exits: "); if(currentRoom.northExit != null) System.out.print("north "); if(currentRoom.eastExit != null) System.out.print("east "); if(currentRoom.southExit != null) System.out.print("south "); if(currentRoom.westExit != null) System.out.print("west "); System.out.println();

Exemplo de duplicação de código

Page 18: Programação Orientada  a  Objetos

Os dois métodos em questão fazem duas coisas:◦ printWelcome() imprime a mensagem de boas

vindas e imprime as informações sobre a localização atual

◦ goRoom() altera a localização atual , e imprime as informações sobre a localização atual

Os dois métodos imprimem as informações atuais de localização, mas nenhum deles pode chamar o outro, porque eles também fazem outras coisas. Isso é um projeto ruim.

Raízes do Erro

Page 19: Programação Orientada  a  Objetos

Um projeto mais aprimorado utilizaria um método mais coeso separando em um única tarefa a impressão das informações atuais de localização.

Os dois métodos podem fazer chamadas a esse novo método quando precisarem imprimir essas informações.

Dessa maneira, não e necessário escrever o código duas vezes, e quando uma alteração for necessária , será preciso uma única modificação.

Solução do Erro

Page 20: Programação Orientada  a  Objetos

Tarefa◦ Adicionar uma nova direção de movimento.◦ Atualmente: norte, leste, sul e oeste.◦ Deve-se permitir: para cima e para baixo.

Fazendo Extensões

Page 21: Programação Orientada  a  Objetos

Duas classes: Room e Game Room é a classe que armazena a saída de

cada sala. Game utiliza as informações de saída da

sala atual para imprimir as informações sobre saídas e para se mover de uma sala para outra.

Localizando código relevante

Page 22: Programação Orientada  a  Objetos

Adicionar dois novos campos Alterar metodos setExits(…)

Classe Room

Page 23: Programação Orientada  a  Objetos

Mais trabalhoso localizar as modificações◦ Localizar todos os lugares exige paciência e

cuidado◦ Métodos que devem ser alterados:

createRoom() printWelcome() goRoom()

◦ Uma possivel solução seria adicionar as novas direções em todos esses métodos É a melhor solução???????????

Classe Game

Page 24: Programação Orientada  a  Objetos

O fato de haver muitos lugares onde todas as saídas são enumeradas e sintomático de projeto ruim.◦ Ao declarar variáveis de saída na classe Room

setExits()há um if por saída goRoom() há um if por saída printLocationInfo() há um if por saída

◦ Essa decisão de projeto cria trabalho: localizar todos esses lugares e adicionar dois novos casos

◦ E se um novo requisito fosse adicionar as direções como noroeste, sudeste????

Acoplamento

Page 25: Programação Orientada  a  Objetos

Usar HashMap<String, Room> para armazenar as saídas◦ Obriga-se a escrever código que pode operar com

qualquer número de saídas◦ Não obriga a tanta alterações no futuro

Essa e uma alteração na maneira como a sala armazena suas informações. Teoricamente essa alteraçao deve afetar somente a classe Room (como as informações de saída são armazenadas), não a interface (o que a sala armazena)

Solução mais adequada

Page 26: Programação Orientada  a  Objetos

De maneira ideal , quando apenas a implementação muda , outras classes não deviam ser afetadas. Isso seria um caso de acoplamento fraco.

Em nosso exemplo, isso não funciona. Se as saídas de Room forem substituídas por um HashMap, a classe Game não compilará mais.

Sintoma de acoplamento forte.

Solução mais adequada

Page 27: Programação Orientada  a  Objetos

Problema principal:◦ Uso de campos públicos◦ Ao tornar públicas as saídas, a classe Room expôs

em sua interface não apenas o fato de que tem saídas, mas exatamente como tais informações são armazenadas. Isso quebra um dos princípios fundamentais do bom projeto, o encapsulamento.

Encapsulamento para reduzir acoplamento

Page 28: Programação Orientada  a  Objetos

Diretriz◦ Ocultar informações de implementação da

visualização O que uma classe pode fazer deve ser visível Como a classe é, não.

Vantagem◦ Se nenhuma outra classe sabe como as

informações são armazenadas, pode-se facilmente alterar como elas são armazenadas em quebrar outras classes

Encapsulamento

Page 29: Programação Orientada  a  Objetos

Impôr separação entre o que e como◦ Tornando os campos privados◦ Método de acesso para obtê-los

A classe Game deverá ser alterada também. Reduzindo drasticamente o código.

Classe Room Modificada

Page 30: Programação Orientada  a  Objetos

Até agora não alteramos a representação de saída. Somente a interface foi limpa.

A alteração em Game e mínima. Ao invés de acesso a campos públicos, o uso de métodos , mas o ganho é significativo.

Agora pode ser alterar, como as saídas são armazenadas na classe Room sem se preocupar com a quebra de qualquer outra classe.◦ A representação interna em Room foi

completamente separada da interface.

Classe Room Modificada

Page 31: Programação Orientada  a  Objetos

Agora que o projeto está como devia estar, a troca dos campos separados por um HashMap é fácil.

Vale enfatizar que pode-se fazer a alteração sem mesmo verificar se qualquer coisa quebrará em outra parte. Pois foram alterados apenas aspectos privados da classe Room. A interface permanece inalterada.

Vantagens da alteração:◦ Classe Room mais curta.◦ Método getExit() foi reduzido ao extremo.

Classe Room Alterada

Page 32: Programação Orientada  a  Objetos

Objetivo: inserir duas novas saídas. Metodo setExits ainda precisa de

aperfeiçoamento Interface da Classe Room Alterações afetam outras classes Não é possível separar completamente as classes,

caso contrário objetos de classe diferentes não seriam capazes de interagir entre si.

Ao invés disso, manter o grau de acoplamento o mais baixo possivel.

Classe Room Alterada

Page 33: Programação Orientada  a  Objetos

public void setExit(String direction, Room neighbor)

Agora, as saídas da sala podem ser configuradas uma saída por vez e qualquer direção pode ser utilizada para uma saída.

Remove-se assim completamente a restrição de Room. A classe Room pode armazenar as direções para cima e para baixo, bem como qualquer outra direção que possa imaginar.

Método setExit()

Page 34: Programação Orientada  a  Objetos

Uso de encapsulamento adequado reduz o acoplamento e pode reduzir significativamente a quantidade de trabalho necessário para fazer alterações em aplicações.

Porem esse não é o único fator que influencia o grau de acoplamento. Outro aspecto é conhecido pelo termo projeto baseado na responsabilidade.

Projeto baseado na responsabilidade

Page 35: Programação Orientada  a  Objetos

Idéia◦ Cada classe deve ser responsável por tratar seus

próprios dados Adição de novas funcionalidades

◦ Qual classe devemos adicionar um método para implementar essa nova função?

◦ Qual classe deve ser responsável pela tarefa?◦ A resposta é: a classe que é responsável por

alguns dados também deve ser responsável por manipulá-los.

Projeto baseado na responsabilidade

Page 36: Programação Orientada  a  Objetos

Versão original do printLocation() com o método getExitString()

As informações sobre saéda estão armazenadas somente na própria sala, e a sala que é responsável por fornecer essas informações.

A sala pode fazer isso muito melhor do que qualquer outro objeto, desde que tenha todo o conhecimento sobre a estrutura de armazenamento interno dos dados.

Responsabilidade e Acoplamento

Page 37: Programação Orientada  a  Objetos

Objetivo◦ Reduzir acoplamento

System.out.println(“You are ” + currentRoom.getDescription()); System.out.println(currentRoom.getExitString());

Implementação ainda pode ser melhorada◦ Se adicionarmos itens as salas?◦ Ou monstros?◦ Ou outros jogadores?◦ Tal descrição deve estar contida na sala.◦ Porém se tais alteracoes fossem necessárias, a

classe Game deve ser alterada (acoplamento)

Responsabilidade e Acoplamento

Page 38: Programação Orientada  a  Objetos

Nova brecha para o projeto baseado em responsabilidade

Room mantem informações sobre a sala Ela tambem deve produzir uma descrição

para a sala public String getLongDescription() { return "You are " + description + ".\n" + getExitString(); } Na classe GameSystem.out.println(currentRoom.getLongDescription());

Responsabilidade e Acoplamento

Page 39: Programação Orientada  a  Objetos

Outro aspecto da separação e de princípios de responsabilidade

Procura-se criar um projeto que facilite alterações posteriores

Idealmente apenas uma única classe precisa ser alterada para fazer uma modificação

Ocasionalmente, várias classes precisam de alteração, mas objetivamente com o mínimo possível de classes.

Além do mais, as alterações necessárias em outras classes devem ser óbvias, fáceis de detectar e fáceis de executar

Minimizando as alterações

Page 40: Programação Orientada  a  Objetos

Alcança-se regras de bons projetos utilizando:◦ Projeto baseado na responsabilidade◦ Fraco acoplamento◦ Alta coesão◦ Ter em mente:

Modificação e extensão Importante antecipar que um aspecto do programa pode

sofrer alteração, a fim de facilitar essa alteração.

Minimizando as alterações

Page 41: Programação Orientada  a  Objetos

Campos públicos◦ Pratica que talvez crie forte acoplamento

Necessário alteração em mais de uma classe para o que devia ser uma simples modificação

◦ Campos públicos devem ser evitados Porém, há formas piores de acoplamento

◦ Acoplamento implícito Uma classe depende de informações internas da outra Dependência não óbvia

Acoplamento Explícito◦ Não é bom◦ Porém é óbvio (aplicação não compila)

Acoplamento Implícito

Page 42: Programação Orientada  a  Objetos

Novo requisito◦ Adicionar nova palavra de comando ao jogo

look (imprimir a descrição da sala e sair novamente) Solução

◦ Introduzir uma nova palavra de comando, no array validCommands na classe CommandWords

◦ Boa coesão Ao invés de definirmos o comando no Parser Facilita encontrar onde os comandos estão definidos e

acrescentar outros O autor esta pensando na frente, assumindo que outros

comandos podem ser definidos, e criou uma estrutura que torna isso fácil

Acoplamento Implícito

Page 43: Programação Orientada  a  Objetos

Após fazer a alteração, isso não funciona. Ao digitar look nada acontece.

◦ Palavra é reconhecida◦ Porém não há ação vinculada a ela

Isso pode ser corrigido adicionando o método look na classe Game. E adicionado mais um if no método processCommand.

O acoplamento entre as classes Game, Parser, e CommandWor dpara ser boa◦ Fácil fazer a extensão

Acoplamento Implícito

Page 44: Programação Orientada  a  Objetos

Emitir comando help◦ Nota-se um pequeno problema

O novo comando não e listado◦ Fácil de corrigir

Editar string do método printHelp de Game Feito rapidamente e não parece um grande problema

◦ E se tal erro não tivesse sido notado?◦ Você pensou nesse erro antes de ler aqui?◦ Problema fundamental

Novo comando Ajuda precisa ser atualiza

Fácil de esquecer tal alteração O programa compila e executa O programador de manutenção pode muito bem acreditar que o trabalho

esta terminado e liberar um programa que agora contem uma falha

Acoplamento Implícito

Page 45: Programação Orientada  a  Objetos

Comandos alterados Texto de ajuda deve ser modificado

(acoplamento) Mas nada no fonte do programa indica

claramente essa dependência (implícito) Classe bem projetada

◦ Evita acoplamento implícito Seguindo a regra do projeto baseado na

responsabilidade

Acoplamento Implícito

Page 46: Programação Orientada  a  Objetos

Classe CommandWord◦ Responsável pelas palavras de comando◦ Deve ser responsável pelas impressão das

palavras de comando◦ Adicionar metodo showAll()

Classe Game◦ printHelp()

Ao invés de imprimir texto fixo Invoca um método de um objeto CommandWord

para imprimir todas as palavras de comando

Acoplamento Implícito

Page 47: Programação Orientada  a  Objetos

Game não tem referência a um objeto CommandWords◦ Pode ser adicionado◦ Diagrama de classe refletiria isso (Game teria

relação com CommandWords) Setas no diagrama de classe são uma

primeira boa indicação do quanto um programa é fortemente acoplado.◦ Mais setas, mais acoplamento◦ Bons projetos

Diagramas com poucas setas

Acoplamento Implícito

Page 48: Programação Orientada  a  Objetos

Game não ter referência a CommandWords é uma boa coisa

Isso não deve ser alterado Ponto de vista de Game

◦ CommandWords é detalhe de implementação do Parser

◦ Parser Retorna comandos Decisão de usar um CommandWords para isso ou

outra coisa é detalhe de implementação

Acoplamento Implícito

Page 49: Programação Orientada  a  Objetos

Projeto Aprimorado Adicionar em Game

◦ parser.showCommands()◦ showCommands() em Parse

Delega responsabilidade ao objeto CommandWords

Acoplamento Implícito

Page 50: Programação Orientada  a  Objetos

Projeto atual é bem melhor que o original Contudo é possível aperfeiçoa-lo ainda mais Característica de um bom projetista

Capacidade de pensar a frente O que pode ser mudado? O que permanecera inalterado durante toda a vida do

programa?

Pensando a frente

Page 51: Programação Orientada  a  Objetos

Assumiu-se que o jogo será baseado em texto e um terminal de entrada e saída

Mas isso será sempre assim?◦ Seria uma extensão interessante, a adição de

uma GUI com menus, botões e imagens. Nesse caso, nao imprimiria-se as informações no

terminal O metodo showAll () por exemplo, imprime as

informações no console. Seria mais interessante deixar a classe CommandWords produzir a saída, porém a classe Game deve decidir como ela será apresentada ao usuário.

Pensando a frente

Page 52: Programação Orientada  a  Objetos

Observe que tais alterações não trás nenhum benefício agora, porém tal projeto aperfeiçoado pode trazer grandes benefícios no futuro.

Pensando a frente

Page 53: Programação Orientada  a  Objetos

Uma unidade de código deve ser sempre responsável por uma e somente uma tarefa.◦ Princípio aplicado :

Classes Métodos

Coesão

Page 54: Programação Orientada  a  Objetos

Qualquer método deve ser responsável por somente uma tarefa bem definida

Exemplo de metodo coeso◦ printWelcome() da classe Game

Ponto de vista Funcional Todas as instruções que estão em printWelcome() poderiam ser

colocadas diretamente no metodo play() de Game, evitando até uma chamada de método.

Métodos coesos◦ Fácil de entender◦ Fazer modificações

Métodos devem ser◦ Razoavelmente curtos◦ Seus nomes devem indicar claramente seus propósitos

Coesão de métodos

Page 55: Programação Orientada  a  Objetos

A classe deve apresentar uma unica entidade bem definida no domínio do problema.

Outra extensão no projeto◦ Adição de itens ao jogo◦ Cada sala pode conter um item◦ Item

Descrição Peso (Determina se ele pode ser carregado ou nao)

Coesão de Classes

Page 56: Programação Orientada  a  Objetos

Abordagem simples◦ Adicionar dois campos a classe Room

itemDescription itemWeight

◦ Tal abordagem não possui um bom grau de coesão Room descreve tanto uma sala quanto um item Outro problema e que isso vincula um item a uma sala, e isso

pode não ser desejável Projeto Aprimorado

◦ Criar uma classe separada para item (Item). Descrição Peso

◦ Room manteria uma referência a um objeto da classe Item

Coesão de Classes

Page 57: Programação Orientada  a  Objetos

Benefícios reais de separar itens de salas◦ Novos requisitos

Numero ilimitados de itens por sala Com o projeto aprimorado isso e fácil Criar multiplos objetos Item e armazenar em uma

Collection na classe Room Abordagem ingênua

Tal alteração seria quase impossível

Coesão de Classes

Page 58: Programação Orientada  a  Objetos

Metodo printWelcome() Classe Item

◦ Se uma alteração de alguma característica dos itens do jogo for necessária, um programador de manutenção sabe facilmente em qual classe começar examinar o código

Coesão para legibilidade

Page 59: Programação Orientada  a  Objetos

Segunda grande vantagem de coesão é um potencial mais alto para reutilização

Por exemplo criando uma classe Item separada, pode-se criar múltiplos itens e assim utilizar o mesmo código de um único item.

A reutilização é um aspecto importante de coesão de método

Coesão para reutilização

Page 60: Programação Orientada  a  Objetos

Refatorando e testando

Refatorando

Page 61: Programação Orientada  a  Objetos

Acoplamento◦ Descreve a interconectabilidade das classes. ◦ Objetivo

Acoplamento fraco Cada classe e amplamente independente e comunica-se

com outras classes por uma interface pequena e bem definida

Resumo dos Conceitos

Page 62: Programação Orientada  a  Objetos

Coesão◦ Como uma unidade de código mapeia para uma

tarefa lógica ou entidade.◦ Objetivo

Sistema altamente coeso Cada unidade de código é responsável por uma tarefa

ou entidade bem definida.

Resumo dos Conceitos

Page 63: Programação Orientada  a  Objetos

Duplicação de Código◦ Sinal de projeto ruim.◦ Deve ser evitado.

Resumo dos Conceitos

Page 64: Programação Orientada  a  Objetos

Coesão de Método◦ Responsável apenas por uma tarefa bem definida.

Resumo dos Conceitos

Page 65: Programação Orientada  a  Objetos

Coesão de Classe◦ Representa uma entidade bem definida.

Resumo dos Conceitos

Page 66: Programação Orientada  a  Objetos

Encapsulamento◦ Reduz o acoplamento e assim leva a um projeto

aprimorado.

Resumo dos Conceitos

Page 67: Programação Orientada  a  Objetos

Projeto baseado na responsabilidade◦ Processo de projetar classes atribuindo

responsabilidades bem definidas a cada classe. ◦ Determina qual classe deve implementar qual

parte de uma função da aplicação.

Resumo dos Conceitos

Page 68: Programação Orientada  a  Objetos

Minimizar as alterações◦ Objetivos principais de um bom projeto

Localizar a alteração Ao fazer alterações em uma classe, deve-se provocar o

mínimo de efeitos em outras classes.

Resumo dos Conceitos

Page 69: Programação Orientada  a  Objetos

Refatoração◦ Atividade de reestruturar um código existente

para manter um bom projeto de classe quando a aplicação for modificada ou estendida.

Resumo dos Conceitos