19
1 Aula 24 Programação Modular, POO e Padrões de Projeto Alessandro Garcia Alessandro Garcia LES/DI/PUC-Rio Junho 2010 Diferenças entre... Módulos (em C) e Classes (Linguagens OO) Classes possuem um operador de instanciação explícito Hierarquia de classes Uso de herança para reuso de estrutura e comportamento C: reuso somente através de chamadas de funções Suporte direto a funções polimórficas (polimorfismo) Destruição de objetos (desalocação de memória) em algumas linguagens OO é feita de forma automática Suporte direto a definição de interfaces... Nov 2009 2 / 27 Alessandro Garcia © LES/DI/PUC-Rio

Aula 24 Programação Modular, POO e Padrões de Projetoinf1301/docs/INF1301_Aula24_Modular... · Programação Modular, POO e Padrões de Projeto Alessandro Garcia LES/DI/PUC-Rio

Embed Size (px)

Citation preview

1

Aula 24Programação Modular, POO e

Padrões de Projeto

Alessandro GarciaAlessandro GarciaLES/DI/PUC-Rio

Junho 2010

Diferenças entre...

• Módulos (em C) e Classes (Linguagens OO)– Classes possuem um operador de instanciação explícito

– Hierarquia de classes

– Uso de herança para reuso de estrutura e comportamento• C: reuso somente através de chamadas de funções

• Suporte direto a funções polimórficas (polimorfismo)

– Destruição de objetos (desalocação de memória) em algumas linguagens OO é feita de forma automática

– Suporte direto a definição de interfaces...

Nov 2009 2 / 27Alessandro Garcia © LES/DI/PUC-Rio

2

Interfaces (em Java)

• Interfaces– As interfaces definem assinaturas de conjuntos de métodos,

mas não os implementam• tem o papel do módulo de declaração (*.h)

• ... mas permite definir interfaces reutilizáveis (p.e. serializable)

– Interface é uma especificação que permite que classes, não diretamente relacionadas na mesma hierarquia, possam incorporar propriedades similares

– Uma classe que implemente a interface deve implementar TODOS os métodos definidos nesta

Nov 2009 3 / 27Alessandro Garcia © LES/DI/PUC-Rio

– public interface Sleeper {

public void wakeUp();

public long ONE_SECOND = 1000; // milli

}

Diferenças entre...

• Módulos (em C) e Classes (Linguagens OO)– Classes possuem um operador de instanciação explícito

– Hierarquia de classes

– Uso de herança para reuso de estrutura e comportamento• C: reuso somente através de chamadas de funções

– Destruição de objetos (desalocação de memória) em algumas linguagens OO é feita de forma automática

– Suporte direto a definição de interfaces...

– Linguagens OO: melhor controle de visibilidade (graus de en p l mento)

Nov 2009 4 / 27Alessandro Garcia © LES/DI/PUC-Rio

encapsulamento)• exemplo: Java...

3

Visibilidade de membros da classe

Controlando o acesso aos membros da classe

Especificador classe subclasse pacote todos

private X

protected X X X

public X X X X

Nov 2009 5 / 27Alessandro Garcia © LES/DI/PUC-Rio

public X X X X

default X X

Pacotes (em Java)

• Pacotes– Para facilitar o uso, controle de acesso e controle de conflito de

nomes, os programadores agrupam classes e interfaces l i d trelacionadas em pacotes

– Para definir qual pacote uma classe pertence, basta incluir no início arquivo da classe a linha:package nomePacote;

– Os pacotes necessários a uma classe devem ser incorporados

Nov 2009 6 / 27Alessandro Garcia © LES/DI/PUC-Rio

Os pacotes necessários a uma classe devem ser incorporados através do comando import

• similar ao include

4

Abstract e Final

• Métodos Abstract: não possuem implementação e devem ser implementados pelas subclasses– classe deve ser definida como “abstract” quando possuir pelo

menos um método abstratomenos um método abstrato

• Métodos Final: não podem ser sobrescritos– é válido estender uma classe não marcada como final

• mas não podemos sobrescrever seus métodos final

Nov 2009 7 / 27Alessandro Garcia © LES/DI/PUC-Rio

Erro de compilação

Membros estáticos de uma classe

• Métodos e variáveis estáticos– Declarados com o especificador static– São comuns a todos os objetos da classe

Utili d d l ã d t t– Utilizados para declaração de constantes– Utilizados para declaração de métodos que não necessitam

de uma instância da classe

static int FALSO 0;

static int VERDADEIRO 1;

public static boolean testa( int p ) {

Nov 2009 8 / 27Alessandro Garcia © LES/DI/PUC-Rio

public static boolean testa( int p ) {if( p == this.VERDADEIRO )

return( true );else

return( false );}

5

Diferenças entre...

• Módulos (em C) e Classes (Linguagens OO)– Classes possuem um operador de instanciação explícito

– Hierarquia de classes

– Uso de herança para reuso de estrutura e comportamento• C: reuso somente através de chamadas de funções

– Destruição de objetos (desalocação de memória) em algumas linguagens OO é feita de forma automática

– Suporte direto a definição de interfaces...

– Linguagens OO: melhor controle de visibilidade (graus de en p l mento)

Nov 2009 9 / 27Alessandro Garcia © LES/DI/PUC-Rio

encapsulamento)• exemplo: Java...

– Suporte direto à funções polimórficas• É possível a implementação de funções polimórficas em C?

Polimorfismo em C? Função como um dado

• Uma função definida é uma seqüência de bytes contida em um espaço de dados

• usualmente contíguo

• em geral, não alterável constanteg ,

– possui um nome• usualmente o nome da função

– possui um endereço• origem de execução

TamanhoEndereço do

Meionome da função

Maio 2009 10 / 32Alessandro Garcia © LES/DI/PUC-Rio

– possui também um tipo...

Espaço de dados

Endereço do espaço

Função de acesso( x , y, ... , z )

6

Função como um dado

• O tipo de uma função é estabelecido pela sua assinatura física– valor retornado

– lista dos tipos de parâmetros • os nomes dos parâmetros não fazem parte da assinatura

• o nome da função não faz parte da assinatura

– exemplo: int ( int , double )

• Uma função A será do mesmo tipo que a função B caso b t h i t

Maio 2009 11 / 32Alessandro Garcia © LES/DI/PUC-Rio

ambas tenham a mesma assinatura– programador deve garantir que exista uma “igualdade”

semântica

Dado tipo ponteiro para função

• Em C e C++ podem ser definidas variáveis do tipo ponteiro para função– exemplo: int (* VarF1 )( int , double )

• VarF1 é um ponteiro para função do tipo: int ( int , double )

– Exemplo de atribuição

int Func( int X , double Y )

{

...

Func é uma constante do tipo ponteiro para uma função do tipo:int ( int , double )

Maio 2009 12 / 32Alessandro Garcia © LES/DI/PUC-Rio

} /* Func */

main(...) {

VarF1 = Func ;

}

7

Exemplo simples: integração por trapézio

• Seja f(x) uma função contínua em [a, b]– o problema da integração numérica consiste em calcular um valor

aproximado para

solução: calcular a integral b

dxxfI )(– solução: calcular a integral

“aproximada” através da regra dostrapézios

a

f )(

função a ser integrada

Exemplo: f(x) = 2 * x

doubleY

limite superiorlimitei f i

mmmTR fffffffh

I 123210 22

Maio 2009 13 / 32Alessandro Garcia © LES/DI/PUC-RioA B X

0 1 2 3 4 5 6 7 8

limite superiorinferior

f0 f1f1 f2f2 f3f3 fm

Parâmetros:- número de interações: 8- limites inferior e superior: 0 e m- e a própria função f

Exemplo simples: integração

/* Função de integração numérica utilizando regra dos trapézios */double Integrar( double LimInf ,

double LimSup , int NumInt , double ( * Func )( double X ))

{{double Integral = 0.0 ;double Intervalo ;int i ;assert( NumInt >= 2 ) ;Intervalo = ( LimSup - LimInf ) /

( NumInt - 1 ) ;Integral += Func( LimSup ) ;Integral += Func( LimInf ) ;for ( i = 1 ; i < NumInt - 1 ; i++ )

Y

Maio 2009 14 / 32Alessandro Garcia © LES/DI/PUC-Rio

{Integral += 2 * Func( Intervalo * i ) ;

} /* for */Integral *= Intervalo/2;return Integral ;

} /* Integrar */

A B X0 1 2 3 4 5 6 7 8

mmmTR fffffffh

I 123210 22

8

Exemplo simples: integração, uso

/* exemplo de uso */

double Quadrado( double X ) {

t X ** 2return X ** 2 ;}

double Cubo( double X ) {

return X ** 3 ;}

printf( ″\n F = x ** 2 de x=1 a x=10: %lf″

Maio 2009 15 / 32Alessandro Garcia © LES/DI/PUC-Rio

printf( \n F = x 2 de x=1 a x=10: %lf ,Integrar( 1.0 , 10.0 , 20 , Quadrado )) ;

printf( ″\n F = x ** 3 de x=1 a x=10: %lf″ ,Integrar( 1.0 , 10.0 , 20 , Cubo )) ;

Função como um dado

• A assinatura pode estar associada a um de vários corpos – na hora da chamada é estabelecida a associação da chamada

• estática (tempo de compilação), caso normal de linguagens procedurais• dinâmica (tempo de execução), caso freqüente em linguagens orientadas a

objetos

Chama

F( float )

Associaçãoda chamada *F( float )

F( int )

Associaçãoestática

Assinatura

Assinatura

Maio 2009 16 / 32Alessandro Garcia © LES/DI/PUC-Rio

CorpoF( float )

CorpoF ( int )

CorpoF( float )

Associaçãodinâmica

9

Da aula passada... Para aula de hoje...

• Objetivos– discutir os conceitos de programação orientada a objetos (OO)

do ponto de vista de programação modular

– o que são padrões de projeto?

– discutir como projetar programas C de forma reusável• com padrões de projeto (ex. esquemas de algoritmos, estruturas

de cabeças, etc...)

– discutir como projetar programas OO de forma reusável• com padrões de projeto

• fazem sentido em programação modular em C?

Maio 2009 17 / 27Alessandro Garcia © LES/DI/PUC-Rio

fazem sentido em programação modular em C?

Sumário

• Introdução à padrões de projeto

• Padrões de projeto em C– Estrutura cabeça

– Esquemas de algoritmo:• Pesquisa Binária

– Iterador

• Padrões de projeto OO– Singleton

Maio 2009 18 / 27Alessandro Garcia © LES/DI/PUC-Rio

g

– Adapter

– Observer

– Etc...

10

Iterador: exemplo de esquema de algoritmo

• Problema: como seqüencialmente acessar os elementos de um conjunto de dados (ordenado ou não), expondo o mínimo possível da sua representação interna?

• Solução de projeto: Um iterador (função geradora) é um esquema de algoritmo composto por:– tipo tpEstado: o descritor (tipo) do estado

• possivelmente define uma constante: ESTADO_NIL

– um ou mais tipos tpValorX que determinam o tipo dos elementos acessados pela correspondente função: tpValorX ObterValorX( tpEstado , ...)

E i di l d l d id

Maio 2009 19 / 27Alessandro Garcia © LES/DI/PUC-Rio

• E.g. indice atual de um valor sendo percorrido• valores acessíveis à partir do escritor do estado

– função tpEstado DefinirPrimeiro( ... )– função tpEstado DefinirProximo( tpEstado , ... )– função boolean Terminou( tpEstado , ... )

Iterador: exemplo pesquisa em tabela

• Esquema do algoritmo para pesquisa em qualquer tabela

tpEstado Corrente ; Corrente = DefinirPrimeiro( ValorProcurado ) ;while ( !Terminou( Corrente )){if ( Comparar( ObterValor( Corrente ),

ValorProcurado ) == EH_IGUAL ){return Corrente ;

} /* if */

Maio 2009 20 / 27Alessandro Garcia © LES/DI/PUC-Rio

} / /Corrente = DefinirProximo(Corrente, ValorProcurado);

} /* while */return ESTADO_NIL ;

11

Padrões de projeto

• Servem para resolver problemas/perguntas recorrentes em projeto (e programação) de software– Exemplo: como implementar um mecanismo de observação?

• Estabelecem soluções elegantes para tais problemas– definem papéis/participantes (módulos conceituais) a serem

implementados– soluções não são suportadas diretamente por uma primitiva única da

linguagem (p.e. Singleton)– provêem exemplos em uma linguagem de programação (p.e. Java)

• Através de nomes/metáforas, um catálogo de padrões permite

Maio 2009 21 / 27Alessandro Garcia © LES/DI/PUC-Rio

estabelecer um idioma entre programadores– Comunicação eficiente: “Vamos usar o padrão Adapter para …”

• Estabelece as conseqüências positivas e negativas de usar aquele padrão: reuso, manutenibilidade, segurança, performance, etc...

Padrões de projeto

• Exemplos de padrões de projeto OO:– Singleton

Strategy

Padrões de problemas Padrões de soluções

– Strategy– Adapter– Template Method– Observer– State

• Vantagem: reuso e manutenibilidade do código genérico dos padrões– de um projeto para outro– dentro de um projeto, poder have várias instâncias do mesmo padrão

Maio 2009 22 / 27Alessandro Garcia © LES/DI/PUC-Rio

• História: desde os anos 90, padrões OO em engenharia de software• 1995, Gang of Four (Gamma, Helm, Johnson, Vlissides): “Design

Patterns: Elements of Reusable Object-Oriented Software”– criação (Singleton), estrutural (Adapter), comportamental

(Observer)

12

Criação: Padrão Singleton (Objeto Unitário)

1a instanciação

Classe Singleton

Objeto único da classe singleton

Maio 2009 23 / 27Alessandro Garcia © LES/DI/PUC-Rio

Instanciaçõessubsequentes

Padrão Singleton (Objeto Unitário)

SecurityManager

private SecurityManager( )public static SecurityManager getInstance( )// other methods

private static SecurityManager uniqueInstance// other attributes

Uma classe singleton sempre tem uma variável estática privada para manter a instância única

Um construtor privado

Maio 2009 24 / 27Alessandro Garcia © LES/DI/PUC-Rio

// other methods…

Um método público estático para invocar o construtor privado se uniqueInstance é null; caso contrário, retorna uniqueInstance

13

Padrão Strategy (Estratégia)

• Encapsula variantes de um algoritmo relacionados em classes que são subclasses de uma classe comum

• Permite a seleção de algoritmo variar por objeto e também no decorrer do tempop– estratégias podem variar de forma independente de clientes

– evita tornar complexa a classe contexto com diferentes algoritmos (e respectivas estruturas de dados) para o mesmo propósito

• Forma Geral: Java: pode ser

uma classeabstrata ou interface

Maio 2009 25 / 27Alessandro Garcia © LES/DI/PUC-Rio

Padrão Estratégia – Exemplo 1

qual padrão/conceitopoderia ser usado em combinaçãocom o padrão Estratégia?

Maio 2009 26 / 27Alessandro Garcia © LES/DI/PUC-Rio

número de métodosabstratos pode variar deaplicação para aplicação

14

Padrão Estratégia – Exemplo 2

Maio 2009 27 / 27Alessandro Garcia © LES/DI/PUC-Rio

número de métodosabstratos pode variar deaplicação para aplicação

Padrão Estratégia – Exemplo 2

public class BubbleSort implements SortStrategy {

public void sort(double[] list) {double temp;for(int i = 0; i < list.length; i++) {

for(int j = 0; j < list.length - i; j++) {if(list[i] < list[j]) {

Maio 2009 28 / 27Alessandro Garcia © LES/DI/PUC-Rio

temp = list[i];list[i] = list[j];list[j] = temp;

}}

}}

}

15

Padrão Estratégia – Exemplo 2

public class QuickSort implements SortStrategy {

public void sort(double[] a) {quicksort(a, 0, a.length - 1);

}

private void quicksort(double[] a, int left, int right) {

Maio 2009 29 / 27Alessandro Garcia © LES/DI/PUC-Rio

p q ( [] , , g ) {if (right <= left) return;int i = partition(a, left, right);quicksort(a, left, i-1);quicksort(a, i+1, right);

}

private int partition(double[] a, int left, int right) {…}; …

}

Padrão Estratégia – Exemplo 2

SortingClient

public class SortArray {

private SortStrategy sorter = null;

public void sortDouble(double[] list) {sorter.sort(list);

}

public class SortingClient {

public static void main(String[] args) {double[] list = {1,2.4,7.9,3.2,1.2,0.2, …};SortArray context = new SortArray();context.setSorter(new BubbleSort());

Context

Maio 2009 30 / 27Alessandro Garcia © LES/DI/PUC-Rio

public SortInterface getSorter() {return sorter;

}

public void setSorter(SortStrategy sorter) {this.sorter = sorter;

}}

context.sortDouble(list);for(int i =0; i< list.length; i++) {

System.out.println(list[i]);}context.setSorter(new QuickSort());…context.setSorter(new InsertionSort());

}}

16

Padrão Estratégia

• Conseqüências– Benefícios

• evolução modular das estratégias

• permite facilmente a troca dinâmica das estratégias para o mesmo contexto

– qual mecanismo de OO permite isso? é possível em C?

– desvantagens• aumenta o número de objetos

– pode ter um efeito negativo sobre performance devido a criação de objetos para cada troca de estratégia

todos algo itmos de em sa a mesma inte face St ateg

Maio 2009 31 / 27Alessandro Garcia © LES/DI/PUC-Rio

• todos algoritmos devem usar a mesma interface Strategy– nem sempre é natural ou possível

Comportamental: Padrão Observer

Maio 2009 32 / 27Alessandro Garcia © LES/DI/PUC-Rio

Sujeito ObservadoObservadores

- Sujeito é independente dos observadores- Observadores são atribuidos dinamicamente aos observados- Sujeito informa observadores sobre suas mudanças de estado

17

Comportamental: Padrão Observer

variantes: uso de interfaces ou classes abstratas

Maio 2009 33 / 27Alessandro Garcia © LES/DI/PUC-Rio

Padrão Observer

• O Padrão Observer– paper “subject”: elemento do sistema sendo observado

• mantém referências para os “observadores”

• notifica os observadores que mudanças ocorreram• notifica os observadores que mudanças ocorreram

Point Line

FigureElementFigure 1 *

Screen

update

<<interface>>Observer

addObserverremoveObservernotify

<<interface>>Subject

*

*

Maio 2009 34 / 27Alessandro Garcia © LES/DI/PUC-Rio

Members exclusively dedicated to the pattern

Methods including some code relative to the pattern

observersgetXgetYgetColoraddObserverremoveObservernotifysetXsetYsetColor

updateDisplay

Sc eeobserversgetP1getP2getColoraddObserverremoveObservernotifysetP1setP2setColor

*

*

18

Estrutural: Padrão Adaptador

• A função de um adaptador é tornar possível a conexão de dois objetos: a tomada e o plugue de diferentes países– converte a interface de uma classe (A) em outra interface (B)

que clientes (C) conhecem – Classes adaptadoras permitem duas classes (com interfaces – Classes adaptadoras permitem duas classes (com interfaces

originalmente incompatíveis) interagirem

classe (componente) existente(funcionalidade externa)

objeto clienteprovidedinterface

Maio 2009 35 / 27Alessandro Garcia © LES/DI/PUC-Rio

Tomada Alemã Plugue UKAdaptador

A B C

requiredinterface

Padrão Adapter (Adaptador)

• Permite que uma aplicação utilize funcionalidades externas

• Uma classe Adapter implementa uma interface conhecida dos clientes e permite acesso a instâncias de uma classe não conhecida dos clientes.

• Exemplo:

SystemOutPrinterprintToSystemOut(String s)…

write ()

Writer<<inteface>>adaptado

adaptador

Maio 2009 36 / 27Alessandro Garcia © LES/DI/PUC-Rio

PrinterAdapter

adaptee write()

ClientwriterObject.write()

adaptador

19

Aula 24Programação Modular com

Padrões de Projeto

Alessandro GarciaAlessandro GarciaLES/DI/PUC-Rio

Junho 2010