Aula 24 Programação Modular, POO e Padrões de Projetoinf1301/docs/INF1301_Aula24_Modular... ·...
Transcript of Aula 24 Programação Modular, POO e Padrões de Projetoinf1301/docs/INF1301_Aula24_Modular... ·...
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