Programação Orientada a Objetos

Slides:



Advertisements
Apresentações semelhantes
Programação em Java Prof. Maurício Braga
Advertisements

Java Básico Orientação a Objeto Marco Antonio Software Architect Fev/2008.
Aula 8 Contratos.
Técnicas de Teste de Software
Tipos de sistemas de Lehman
Prof. Thiago Pereira Rique
Engenharia de Software
Definições operacionais. PASSOS A SEGUIR DEPOIS DESTA AULA 1. Deixe bem claro o problema de investigação com o patrocinador (ou orientador), se preciso.
Refatorações Experiência é aquela coisa maravilhosa que permite que você reconheça um erro tão logo o cometa novamente F.P. Jones.
Adélia Barros Requisitos Adélia Barros
David Menotti Estruturas de Dados I DECOM – UFOP
Padrões GoF – Factory Method
Diagrama de Classes.
IMA - Instituto Mineiro de Agropecuária
Engenharia de Requisitos Requisito – sistema Caso de uso - usuário
Padrões para Atribuições de Responsabilidades
A implementação de avaliação formativa na sala de aula
Princípios e Conceitos de Software(v2)
Classes e objetos P. O. O. Prof. Grace.
JAVA: Conceitos Iniciais
Aula prática 13 Orientação a Objetos – C++ Parte 1
Manual - Bikesys Versão 1.0 – Beta Março 2013.
Gerenciamento de Configuração
Sistemas Operacionais
Conceitos.
DIAGRAMA DE CLASSE Modelagem de Software
Treinamento do Microsoft® Word 2010
Sistemas Distribuídos
Análise e Projeto de Sistemas UNIVERSIDADE DE CRUZ ALTA Ciência da Computação 2010/1.
Entendendo as definições de classe
SELECIONANDO CLIENTES
ACCESS 2007 EDIMILSON JÚNIOR.
Engenharia de Software
Programação Orientada à Objetos
Acoplamento e Coesão Modelagem e Programação Orientada a Objetos
Curso de Aprendizado Industrial Desenvolvedor WEB Disciplina: Programação Orientada a Objetos I Professora: Cheli Mendes Costa Classes e Objetos em Java.
Analises de sistemas ESTRUTURADA Analise de sistema estruturada.
FLUXOGRAMAS.
SISTEMAS DISTRIBUIDOS Aula 4
UTFPR – Campus Curitiba - DAELN Cursos de Eng. Eletrônica/Eng
Documentação de Software
Processos.
Gestão de defeitos.
Aula Prática 4 Monitoria IP/CC (~if669).
Introdução a Banco de Dados
Introdução a Banco de Dados Aula 04
Laboratório de Programação
Requisitos de Software
Técnicas de avaliação de Interfaces Alunos: Joel Levandowski Ranieri R. Tremea Prof ª.:Cristina P. dos Santos URI - Universidade Regional Integrada do.
Modelando Sistemas em UML
Certificação Marco Antonio. Introdução A compreensão desse capítulo é muito importante pois trata de um assunto essencial em qualquer linguagem de programação,
Acabias Marques Luiz. III – Variáveis, constantes e executáveis Parte 1 – Introdução a linguagem  Variáveis e Constantes  Atalhos na manipulação de.
Métodos Ágeis e Programação Extrema (XP)
Sistemas de Arquivos- Cap4
2 – Revisão de Programação Orientada a Objetos
TECNOLOGIA EM ANÁLISE E DESENVOLVIMENTO DE SISTEMAS ANÁLISE E PROJETO DE SISTEMAS Semana /08/2012 Professor Leomir J. Borba-
Trechos de código que permitem reutilização de uma mesma tarefa. Qualquer código PHP pode estar contido no interior de uma função. Não se pode definir.
Linguagem de Programação I Parte IV
Módulo II Capítulo 1: Orientação a Objetos
O Modelo GOMS Fornece um modelo de Engenharia para a performance humana, capaz de produzir predições a priori ou em um estágio anterior ao desenvolvimento.
Módulo I Capítulo 7: Funções e Procedimentos William Ivanski Curso de Programação C#
JavaScript Introdução ao JavaScript 1. Objetivos Introdução Sintaxe Básica Arquivo (script) externo Script no HEAD da página Script no BODY da página.
Java Como Programar, 8/E Deitel/Deitel, 8e. Java – Como programar Copyright © 2010 Pearson Education Slide 1.
Engenharia de Software Orientada a Objetos Professor: Guilherme Timóteo Aula 3: – Modelagem de Classes (parte 2)
Delegação  É uma maneira de tornar a composição tão poderosa para fins de reutilização como a herança. Na delegação, dois objetos são envolvidos no tratamento.
QUALIDADE DE CÓDIGO Dilvan Moreira (baseado no livro Prog. Orientada a Objetos em Java)
GRASP: Projeto de Objetos com Responsabilidade – Parte 2.
Questionário (Básico) Autor: Skyup Informática. Atividade - Questionário O módulo permite criar uma série de questões, que deverão ser respondida pelos.
Herança em Java Curso: Informática Disciplina: Programação Orientada a Objetos Prof. Abrahão Lopes
Testes de Unidade. 2 Pauta Testes de Unidade; Testes de Unidade; Desenvolvimento orientado a testes; Desenvolvimento orientado a testes; Testes unitários.
Transcrição da apresentação:

Programação Orientada a Objetos Projeto de Classes

Agenda Projeto baseado na responsabilidade Acoplamento Coesão 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. 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.

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

Problemas Surgem em geral quando: Classes bem projetadas: 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 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.

Adaptar e estender uma aplicação Muitos dos efeitos de um projeto ruim se tornam evidentes quando se tenta: Adaptar. Estender.

World-of-Zuul

World-of-Zuul Classes bem documentadas Ilustra que projeto ruim envolve algo mais profundo que simplesmente a aparência da classe ou quanto é boa sua documentação.

Introdução a Acoplamento 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

Classes fortemente acopladas 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 fracamente acopladas Pode-se alterar uma classe sem fazer nenhuma alteração em outras classes.

Introdução a Coesão (cohesion) 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

Reutilização 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.

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

Duplicação de Código 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

Exemplo de duplicação de código 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();

Raízes do Erro 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.

Solução do Erro 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.

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

Localizando código relevante 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.

Classe Room Adicionar dois novos campos Alterar metodos setExits(…)

Classe Game 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???????????

Acoplamento 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????

Solução mais adequada 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 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.

Encapsulamento para reduzir acoplamento 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 Diretriz Vantagem 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

Classe Room Modificada 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 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 Alterada 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 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.

Método setExit() 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.

Projeto baseado na responsabilidade 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 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.

Responsabilidade e Acoplamento 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 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 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 Game System.out.println(currentRoom.getLongDescription());

Minimizando as alterações 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 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.

Acoplamento Implícito 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 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 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 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 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 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 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 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 Projeto Aprimorado Adicionar em Game parser.showCommands() showCommands() em Parse Delega responsabilidade ao objeto CommandWords

Pensando a frente 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 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 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.

Coesão Uma unidade de código deve ser sempre responsável por uma e somente uma tarefa. Princípio aplicado : Classes Métodos

Coesão de métodos 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 Classes 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 Abordagem simples Projeto Aprimorado 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 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 para legibilidade 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 reutilização 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

Refatorando Refatorando e testando

Resumo dos Conceitos 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 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 Duplicação de Código Sinal de projeto ruim. Deve ser evitado.

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

Resumo dos Conceitos Coesão de Classe Representa uma entidade bem definida.

Resumo dos Conceitos Encapsulamento Reduz o acoplamento e assim leva a um projeto aprimorado.

Resumo dos Conceitos 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 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 Refatoração Atividade de reestruturar um código existente para manter um bom projeto de classe quando a aplicação for modificada ou estendida.