Práticas de Desenvolvimento de Software
-
Upload
tiago-barros -
Category
Education
-
view
891 -
download
1
description
Transcript of Práticas de Desenvolvimento de Software
Universidade Positivo Especialização em Engenharia de Software
Práticas de Desenvolvimento de Software
Tiago Barros | [email protected]
Conteúdo do curso
• Construção de software– O que é construção de software– Construção de software dentro de um processo de
desenvolvimento
• Paradigmas de programação e a construção de software– Paradigmas de linguagens de programação– Compilação e execução de programas– Alocação de memória
Conteúdo do curso
• Arquiteturas de software
• Introdução aos Padrões de Projeto
• Tipos de Padrões de projeto– Criacionais– Arquiteturais– Comportamentais
• Documentação de padrões de projeto
Avaliação
• Exercícios realizados em sala
• Identificação e documentação da aplicação de técnicas de reengenharia, reuso e padrões no projeto de desenvolvimento de software.
• Apresentação das mudanças na arquitetura, com seus benefícios e custos.
Bibliografia
• Code Complete: A Practical Handbook of Software Construction. Steve McConnell.
• Design Patterns: Elements of Reusable Object-Oriented Software. Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides.
• The Pragmatic Programmer: From Journeyman to Master. Andrew Hunt, David Thomas.
• Software Engineering. Ian Sommerville.
• C.R.U.I.S.E – Component Reuse In Software Engineering. Eduardo Almeida, Alexandre Alvaro, Vinicius Garcia, Jorge Mascena, Vanilson Burégio, Leandro Nascimento, Daniel Lucrédio, Silvio Meira.
Construção de Software
• A etapa de construção consiste na parte “mão na massa” da criação de alguma coisa
• Inclui alguns aspectos de planejamento, projeto e verificação, mas é essencialmente execução
• Quais as fases de um projeto de software que fazem parte da construção de software?
Construção de Software
Figura retirada do livro Code Complete
Construção de Software
Figura retirada do livro Code Complete
Construção de Software
O que significa “codificar e debugar”?
Construção de Software
• O que significa “codificar e debugar”?
• Projetar e codificar classes e funções
• Criar e nomear variáveis e tipos de dados corretamente
• Definir as estruturas de controle
• Fazer testes unitários e debugar o próprio código
• Fazer revisão de código
• Formatar e comentar o código
• Selecionar e integrar os componetes de software utilizados
• Otimizar o código
Construção de Software
Porque construção de
software é importante?
Construção de Software
• Porque construção de software é importante?
• É uma grande parte do processo de desenvolvimento de
software
• É a parte central do processo de desenvolvimento de
software
• Foco na construção aumenta a produtividade
• A construção de software é a única atividade que é
garantida de acontecer e ser entregue em todo projeto
Construção de Software
Pontos chave
• Construção de software é a parte que o cliente realmente compra
• A qualidade da construção afeta diretamente a qualidade do software
• As principais atividades da construção são: design detalhado, codificação, depuração e testes unitários e de integração.
Construção de Software
O que é uma linguagem de programação?
Paradigmas de Programação
• O que é uma linguagem de programação?
– Conjunto de expressões, com regras sintáticas e semânticas, para expressar um programa de computador
– ____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Construção de Software
O que é um paradigma de programação?
Paradigmas de Programação
• O que é um paradigma de programação?
– Modelo de programação suportado por linguagens que agrupam certas características em comum
– Impactam na forma como um problema real é modelado computacionalmente
– ____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Paradigmas de Programação
• Paradigma Imperativo
– É definido como uma sequência de comandos (ordens) que modificam o estado (variáveis) de um programa, de acordo com os dados de entrada, para produzir uma determinada saída.
PROGRAMAComando...Comando...Comando...
DADOS (estado)
ENTRADA SAÍDA
Paradigmas de Programação
• Paradigma Imperativo
– Vantagens• Modelagem natural de aplicações do mundo real• Eficiência (diretamente implementado pelos processadores)• Bem estabelecido (dominante)
– Desvantagens• Difícil legibilidade • Problemas de manutenção, principalmente em grandes
sistemas
• Paradigma Orientado a Objetos
– Define uma aplicação como um conjunto de módulos (objetos que são representados por classes), que possuem um estado (variáveis) e operações que modificam este estado (métodos).
– É uma subclassificação do paradigma imperativo (não é uma classificação de paradigma)
Paradigmas de Programação
CLASSE
Operação...Operação...Operação...
DADOS (estado)
ENTRADA SAÍDA
CLASSE
Operação...Operação...Operação...
DADOS (estado)
ENTRADA SAÍDA
CLASSE
Operação...Operação...Operação...
DADOS (estado)
ENTRADA SAÍDA
Paradigmas de Programação
• Paradigma Orientado a Objetos
– Vantagens• Modelagem natural de aplicações do mundo real• Eficiência (diretamente implementado pelos processadores)• Classes são abstrações auto-contidas de elementos do
mundo real (tipos complexos)• Modularidade• Reusabilidade• Extensibilidade• Bem estabelecido
– Desvantagens• Semelhantes ao imperativo, mas amenizadas pela maior
estruturação do programa.
• Paradigma Funcional
– Define um programa como um conjunto de funções que fazem o mapeamento dos valores de entrada em valores de saída, sem o conceito de estado do paradigma imperativo.
– Funções são tratadas como valores e cada função é declarada em termos de outras funções (programação declarativa).
Paradigmas de Programação
PROGRAMA(função)
ENTRADA SAÍDA
Paradigmas de Programação
• Paradigma Funcional
– Vantagens• Manipulação de programas mais simples (prototipação)• Prova de propriedades• Transformação (otimização)
– Desvantagens• Difícil mapeamento do mundo real na linguagem de
programação• Baixa eficiência devido à dificuldade da implementação nos
processadores • Entrada e saída (formatação, tela, etc) possuem apens
mecanismos primitivos
• Paradigma Lógico
– Define um programa que formará conclusões a partir de um conjunto de premissas (declarações).
– Possui um conjunto de fatos (declarações verdadeiras) e regras (manipulação) que descrevem o domínio do problema a resolver.
Paradigmas de Programação
PROGRAMA(fatos, regras)
ENTRADA SAÍDA
Paradigmas de Programação
• Paradigma Lógico
– Vantagens• Acumulam as mesmas vantagens do paradigma funcional• Permite a concepção de aplicações em um alto nível de
abstração (através de associações de entrada e saída)
– Desvantagens• Acumulam as mesmas desvantagens do paradigma
funcional• Usualmente não possuem tipos nem funções de alta ordem
Práticas de Desenvolvimento de Software
Conceitos Básicos de Desenvolvimento
Tiago Barros | [email protected]
Conceitos Básicos
Como funciona um compilador
Como funciona a execução de um programa
Variáveis e tipos de dados
Conceitos Básicos
Objetivos
• Entendimento de como um programa é compilado e executado, no paradigma imperativo/orientado a objetos
• Entendimento de como funciona a execução de um programa
• Entendimento de como funcionam elementos básicos de um programa
Conceitos Básicos
• Compilação em C/C++
– Arquivo fonte (.c / .cpp)• Possui a implementação do código• É compilado
– Arquivo de cabeçalho (.h)• Possui a declaração dos símbolos
– Funções e variáveis• Não é compilado
Conceitos Básicos
• Compilação em C/C++
– Arquivo fonte (.c / .cpp)• O que não é encontrado, vai para a tabela de
simbolos para ser resolvido na ligação (linker)• Cada arquivo fonte (.c / .cpp) gera um arquivo
objeto (.o)
– Arquivo de cabeçalho (.h)• É incluído no arquivo fonte para que o arquivo
fonte “conheça” as declarações do cabeçalho
Conceitos Básicos
• Compilação em JAVA
– Arquivo fonte (.java)• Possui a declaração e implementação da classe• Cada arquivo fonte (.java) gera um arquivo objeto
(.class)• Os arquivos .class são “executados” (interpretados)
pela máquina virtual
Conceitos Básicos
• Como Funciona um compilador – Instruções
• Operação realizada por um processador• Linguagem fonte• Código intermediário• Código de máquina
Conceitos Básicos
• Como Funciona um compilador – Pré-processamento
• Substituição de termos (macros)• Ativação de funcionalidades do compilador• Compilação condicional
#include#define#pragma#if / #ifdef / #else / #endif
Conceitos Básicos
• Como Funciona um compilador – Compilação
• Transformar código fonte em código objeto• Diferentes formatos de código objeto (dependente da
máquina)• Código objeto pode ser diretamente executável
Conceitos Básicos
• Como Funciona um compilador – Compilação > Erros:
• Definição de símbolos errada• Falta de definição de símbolos• Tipos de dados incompatíveis (impossível converter
diretamente)• _________________________________• _________________________________• _________________________________• _________________________________
Conceitos Básicos
• Como Funciona um compilador – Ligação
• Juntar um ou mais códigos objeto e gerar um arquivo executável
• Tabela de símbolos– Exportados– Importados
Conceitos Básicos
• Como Funciona um compilador – Ligação > Erros
• Símbolos não existem• _________________________________• _________________________________• _________________________________• _________________________________• _________________________________• _________________________________
Conceitos Básicos
• Compilação dinâmica (nativa) em Java– Código 100% interpretado chega a ser 10x mais
lento que código compilado– Mas...– Código compilado é 4 a 5 x maior que código
interpretado– Tradeoff entre performance e tamanho do código
final
Conceitos Básicos
• Compilação dinâmica (nativa) em Java– Utilizar compilação adaptativa
• Compila os métodos considerados “hot spots” para código nativo
• Mantêm o restante como bytecode• Aumenta o uso de memória, mas também aumenta a
performance
Conceitos Básicos
• Como Funciona a execução de um programa – Memória
• Armazenamento• Programas e dados
Address Data
0x00000000 0101100100110011
0x00000001 0001000110011110
0x00000002 1110010101010111
… …
0x00FD347B 0001010110110101
… …
0xFFFFFFFF 0011010101110110
Conceitos Básicos
• Como Funciona a execução de um programa – Unidade de processamento
• Carregar e decodificar instruções
• Controlar unidade de execução
PC
DecoderMemory
ExecutionUnit
Conceitos Básicos
• Como Funciona a execução de um programa
Registers
MemoryALU
Conceitos Básicos
• Como Funciona a interpretação de uma classe Java
– A VM recebe como parâmetro a classe a ser executada
– A Classe é “carregada” na máquina virtual
– O interpretador da VM procura o método main na classe
– O interpretador inicia a execução do bytecode que está no método main
• Caso a classe não tenha um método main, uma exceção é “jogada”
Conceitos Básicos
• Class loader carrega cada uma das classes e verifica se as classes estão ok• Methods area quando uma classe é carregada, os seus bytes codes são salvos nessa
região• Heap área de execução. Todos os objetos criados são colocados aqui• Java Stacks pilhas de execução que guardam as chamadas dos métodos. Quando não
existe mais nenhuma pilha, a VM é finalizada• Execution engine interpretador do bytecode
• Como Funciona a interpretação de uma classe Java
Conceitos Básicos
• Variáveis e tipos de dados– Tamanho do barramento de dados do
processador (palavra)
charintshortlongPonteiro
word
c c c c
short short
int
long
pointer
Áreas de memória de um programa
Memória e tipos de dados
Variáveis ponteiros
Memória
Memória
• Classificação
Memória
• Áreas de armazenamento de variáveis de um programa– memória estática– pilha
int g = 0;
int main(){ int x = 20; g = x;}
ESTÁTICA
100 (g) 0
PILHA
200 (x) 20
20
Memória
• Áreas de armazenamento de variáveis de um programa– Heap
int* g = NULL;
int main(){ int x = 20; g = (int*)malloc(sizeof(int)); *g = x;}
ESTATICA
100 (g) 0x00000000
PILHA
200 (x) 20
0x00001000
HEAP
1000 ????????20
Memória
• Áreas de armazenamento de variáveis de um programa– Desalocando memória
int* g = NULL;
int main(){ int x = 20; g = (int*)malloc(sizeof(int)); *g = x; free(g);}
ESTÁTICA
100 (g) 0x00000000
PILHA
200 (x) 20
0x00001000
HEAP
1000 ????????20
Memória
• Variáveis ponteiros– Endereços de memória
• O operador referência: &• O operador desreferência: *
– Declarando ponteirosint i=10;int *intPtr;intPtr = &i;
Memória
• Variáveis ponteiros– O que significa:
&i*i&intPtr*intPtr
– Os operadores new e deleteint *intPtr = new int;...delete intPtr;
Memória
• Variáveis ponteiros
int x = 10;char c = ‘c’;int* pi;char* pc = &c;
int** ppi;int*** pppi;
pc = “uma string”;pi = &x;ppi = πpppi = &ppi;
ADDRESS DATA
0x00000100 (x) 10
0x00000104 (c) ‘c’
0x00000108 (pi) 0x00000100
0x0000010C (pc) 0x00000104
0x00000110 (ppi) 0x00000108
0x00000114 (pppi) 0x00000110
.......................... ....................
0x00001100 “uma string”
0x0000110C
0x00001100
Memória
• Variáveis ponteiros – Exercício!
int global = 0;
int inc(int* num){ return save(*num = *num + 1);}int save(int y){ global = y;}void main(){ int *ptr = (int*)malloc(sizeof(int)); inc(ptr); printf(“%d”, *ptr); printf(“%d”, global);}
1. Descreva o que acontece com a memória do programa ao lado, conforme visto nos exemplos anteriores;
2. O programa ao lado compila?
3. Existe algum erro de execução no programa?
Memória
• Tipos de dados derivados – Arrays
void main()
{
char array[] = “Hello!”;
char *ptr = array;
*ptr = ‘W’;
ptr++;
*ptr = ‘o’;
ptr++;
*ptr = ‘r’;
ptr+= 2;
*ptr = ‘d’;
}
PILHA
100 (array) H
101 e
102 l
103 l
104 o
105 !
106 \0
1070x00000100108 (ptr)
10C
W
0x000001010x00000102
o
r
d
0x00000104
Memória
• Tipos de dados derivados – Estruturas
typedef struct __point
{
int x, y;
} Point;
void inc (Point q)
{
q.x++;
q.y++;
}
void main()
{
Point p;
p.x = 10;
p.y = 20;
inc(p);
}
PILHA
p100 (x)
104 (y)
10
20
q108 (x) 10
10C (y) 20
11
21
Memória
• Tipos de dados derivados – Estruturas
typedef struct __point
{
int x, y;
} Point;
void inc (Point* ptr)
{
p->x++;
p->y++;
}
void main()
{
Point p;
p.x = 10;
p.y = 20;
inc(&p);
}
PILHA
p100 (x)
104 (y)
108 (ptr) 0x00000100
10
20
11
21
Memória
• Tipos de dados derivados – Uniões
#define B 0
#define G 1
#define R 2
#define A 3
#define MAX_COMP 4
typedef union __color
{
int value;
char comp[MAX_COMP];
} Color;
void main()
{
Color color;
color.value = 0;
color.comp[R] = 0xFF;
}
PILHA 3 2 1 0
100(color)
value
comp 0 0 0 0255
Memória em Java
• A “carga” de uma classe java equivale a “carga” de um código nativo para ser executado. As classes ficam na “área de métodos”
• Todo objeto criado em java é colocado na heap java (similar ao heap nativa)– No momento de executar a VM no PC é possível passar como parâmetro o
tamanho máximo da heap java• Java não requer que o código “desaloque” explicitamente memória
– A VM utiliza um “garbage collector”– Quando um objeto da heap não tem mais nenhum outro objeto
apontando para ele, o coletor de lixo o remove da memória– É necessário então “limpar” referências que não são mais utilizadas
(atribuir para null), caso contrário pode causar memory leak• Variáveis locais a um método são colocadas na pilha de java (similar a
pilha nativa)
Maquina Virtual JAVA
• A HotSpot VM otimiza o gerenciamento de memória por idades (generational).
• O heap da maquina virtual é dividida em young generation, old gereration e permanent generation de acordo com a idade do objeto
Maquina Virtual JAVA
• Na Young generation estão os objetos considerados com tempo curto relativo a um intervalo de coletas.
• A young generation é dividida em 3 espacos : – um eden – dois espaços “Survivor”(to-space e from-space).– As alocações acontecem do eden para o from-space.Quando estes estão
preenchidos a coleta na Young generation é feita. – Geralmente a young generation é muito menor em relação ao tamanho da
heap.Isto leva a pequenas mas freqüentes pausas na young generation durante a execução do garbage collection.
Maquina Virtual JAVA
• Objetos que sobreviventes a um determinado numero de coletas são movidos(promovidos) para a old generation.
• A old generation é tipicamente maior em relação a Young o que leva a pausas maiores e menos freqüentes .
• A permanent generation é usada para armazenar classes de objetos e meta dados relacionados.
Maquina Virtual JAVA
Chamada de funções e mudança de contexto
Passagem de parâmetros
Ponteiros para funções
Funções
Funções
• Declaração de funçõestipo nome(argumentos...);
• Corpo das funçõestipo nome(argumentos...){ instruções; return expressão_de_retorno;}
Funções
• Chamada de funções / Pilha de execução
int fib(int x){ int ret = 1; if (x > 1) ret = fib(x-1)+ fib(x-2); return ret;}void main(){ int n = 3; n = fib(n);}
PILHA
100 (n) 3
104
108 (x) 3
10C (ret) 1
1
110
114 (x) 2
118 (ret) 1
11C
120 (x) 1
124 (ret) 1
110
114 (x) 0
118 (ret) 1
1
2
2
3
3
3
110
114 (x) 1
118 (ret) 1
1
Funções
• Passagem de parâmetros / Retorno– Por valor
• Variável é duplicada na pilha e seu valor é copiado• C / C++ / Java
– Por referência• A referência (endereço) da variável é passada• C++
Funções
• Funções e arrays em C– Arrays como argumentos
int add(int intArray[], int numElemnetos);int add(const int *intArray, int numElemnetos);
– Arrays como retornoint * createArray(int numElementos)
Funções
• Funções e estruturas em C / C++– Estruturas como argumento e retorno de funções: são
passadas por valor (cópia)struct TBall{ int x, y;};void move(TBall ball);TBall createBall(int x, int y);
– Para evitar o overhead da cópia, costuma-se passar estruturas por referência constante:void move(const TBall &ball);
Funções
• Funções em Java (Métodos)– Java passa seus objetos como ponteiros!– Ponteiros são endereços passados por valor!
class TBall {
public int x, y;
}
class c1 {
public void moveBall(TBall ball) {
ball.x += 1;
ball.y += 1;
}
public void createBall(TBall ball) {
ball = new TBall();
}
}
Funções
• Ponteiros para funçõesint funcao(int i);int (*ponteiro_para_funcao)(int i);
ponteiro_para_funcao = funcao;
int ret, arg;ret = (*ponteiro_para_funcao)(arg);
Exercício
• implementar um stream de dados na memória de acordo com os seguintes requisitos:– O stream deverá ter uma quantidade de memória previamente alocada e deverá
prever casos de falta de memória, alocando mais se for preciso. – O stream de dados poderá armazenar dados dos seguintes tipos: char, short, int,
long, float. – Deverá ser implementada um conjunto de funções para escrita e leitura de cada tipo
de dados no stream. – O stream funcionará como uma fila FIFO, ou seja: o primeiro dado que for escrito
será o primeiro dado a ser lido.– Cada tipo de dado inserido no stream deverá ocupar apenas a memória necessária
(não deverá haver desperdício de memória, ou seja, alocação de memória a mais do que o necessário para armazenar o tipo de dado)
– O usuário do stream é quem deverá se preocupar com a ordem de inserção / remoção de dados do stream, ou seja: se forem inseridos 2 int e depois tentar ler 2 char, deverão ser retornados os 2 primeiros bytes do primeiro int.
– Deverão ser tratados os erros de falta de memória (na escrita do stream) e falta de dados (na leitura do stream)
Exercício
• Implementação em C– Implementar uma estrutura de dados para armazenar o stream e as
seguintes funções para manipular esta estrutura:
– void WriteChar(char c);– void WriteInt(int i);– void WriteShort(short s);– void WriteLong(long l);– void WriteFloat(float f);– char ReadChar();– int ReadInt();– short ReadShort();– long ReadLong();– float ReadFloat();
Exercício
• Implementação em C++– Implementar a seguinte classe:
class Stream{ public: //construtor: initMemory é a mem inicial alocada Stream(int initMemory); // destrutor: libera toda memória utilizada ~Stream() // métodos de escrita no stream void WriteChar(char c); void WriteInt(int i); void WriteShort(short s); void WriteLong(long l); void WriteFloat(float f); // métodos de leitura do stream char ReadChar(); int ReadInt(); short ReadShort(); long ReadLong(); float ReadFloat(); private: // declare aqui todas as variáveis necessárias // para implementação deste código};
Exercício
• Testes
– Implementar código de testes para testar o uso do stream, prevendo as situações de erro e verificando a completude do teste.
Design de Software
• Processo de projetar um software
• Concepção de um esquema para transformar a especificação em um software desenvolvido
• O design de software é bastante útil em projetos pequenos e indispensável em projetos grandes
• O design deve ser detalhado na quantidade de níveis necessária
Design de Software
Características de um bom Design• Minimização da complexidade
• Facilidade de entendimento e manutenção
• Baixo acoplamento
• Estensibilidade
• Reusabilidade
• Portabilidade
• Alto “fan-in” (várias classes usam uma classe)
• Médio a baixo “fan-out” (uma classe usa poucas classes)
Níveis de Design
Figura retirada do livro Code Complete
Arquitetura de Software
• Design de software de alto nível
• Abstração do sistema computacional em módulos (sub sistemas)
• Com o crescimento dos sistemas computacionais, é preciso tomar decisões que vão além dos algoritmos e estruturas de dados utilizados
Arquitetura de Software
• A arquitetura de software trata de decisões sobre:
– os componentes que formarão o sistema;
– o papel que cada componente representará no sistema;
– protocolos de comunicação entre os componentes;
– formas de acesso a dados;
– distribuição dos componentes do sistema;
– atributos de qualidade do sistema (desempenho, escalabilidade, etc);
Exercício
• Seminário sobre arquiteturas de software
– Apresentar e discutir os principais modelos de arquitetura utilizados no desenvolvimento de software;
– Apresentar e discutir os modelos de arquitetura utilizados no projeto; (porque do uso, benefícios e custos)
– Exemplos:• Arquitetura de repositório;• Arquitetura cliente-servidor;• Arquitetura em camadas;• Arquitetura orientada a serviços;• Arquitetura de objetos distribuídos;• etc.
Design de Software
Voltando ao Design...
Design de Software
• Rittel e Webber definem design como um problema cruel: a única forma de definir este problema é resolvendo o problema ou uma parte dele
Design de Software
Porque?
• Design envolve restrições e trade offs
• Design é não determinístico
• Design é um processo heurístico
Design de Software
Entretanto...• Design pode ser capturado
• Design é uma mistura de conhecimento e criatividade
• Soluções de design que já foram resolvidas são reutilizadas, formam padrões
Padrões de Projeto – Design Patterns
Design de Software
Então porque Design
Patterns?
Design de Software
Então, porque Design Patterns?
• Uma vez que definimos o problema através da sua resolução, podemos reusar esta resolução
• Design Patterns permitem aos desenvolvedores compartilhar conhecimento sobre o design
• São soluções de Design comprovadas para um determinado problema dado um contexto
Design Patterns
Histórico
• Christopher Alexander (1970)– “Each pattern describes a problem that occurs over and over again in our environment and
then describes the core of the solution to that problem in such a way that you can use this solution a million times over without ever doing it the same way twice.”
• Patterns apareceram novamente na OOPSLA conference (1987).
• Gamma, Helm, Johnson and Vlissides (the Gang of Four, or GoF) escreveram em conjunto o famoso livro: Design Patterns: Elements of Reusable Object-oriented Software.
Design Patterns
Conceitos• Patterns
– Um padrão é uma forma completamente compreendida de um modelo aceito ou proposto para imitação… de acordo com o dicionário.
– No nosso dia-a-dia encontramos vários problemas que já ocorreram e vão ocorrer de novo. Design Patterns nos permitem compartilhar a resolução destes problemas, que são bem conhecidos e já foram bem resolvidos.
Design Patterns
Conceitos• Anti-Patterns
– Demosntram uma resolução errada, que deve ser evitada.
– Descrevem como sair de um problema e como proceder para encontrar um solução adequada.
Design Patterns
Conceitos• Tipos de padrões
– Padrões Arquiteturais• Descrevem a estrutura e o relacionamento entre os componentes de
um software.– Padrões de Análise
• Descrevem modelos cuja semântica os fazem aplicáveis a domínios de aplicação específicos.
– Padrões de projeto• Identificam as relações internas de um grupo de componentes de
software e descrevem a responsabilidade e colaboração entre eles.– Idiomas
• Descrevem como implementar aspectos de sistemas de software em uma linguagem de programação específica.
Design Patterns
Conceitos
• Design Patterns– “Descrição de objetos e classes que estão relacionados e
customizados para resolver um problema de projeto, em um determinado contexto.“
– GoF define seus design patterns como:• “A design pattern names, abstracts, and identifies the key aspects of a
common designstructure that make it useful for creating a reusable object-oriented design. The design pattern identifies the participating classes and instances, their roles and collaborations, and the distribution of responsibilities.”
Design Patterns
Aplicabilidade• Por que usar design patterns?
– Foram provados. Patterns refletem a experiência, conhecimento e insights dos desenvolvedores que já utilizaram os padrões com sucesso em seu próprio código.
– São reusáveis. Patterns proveem uma solução pronta que pode ser adaptada para diferentes problemas se necessário.
– São expressivos. Patterns proveem um vocabulário comum de soluções que podem expressar soluções maiores de forma sucinta.
Design Patterns
Aplicabilidade• Quando usar um design pattern?
• Responda as seguintes questões:• As consequencias do uso do padrão são aceitáveis?• Existe uma solução mais simples?• Existe algum padrão que ataca problemas similares?• Existe alguma restrição no uso do padrão?
• Regras:• Preste atenção no contexto e no problema do padrão, verificando se o padrão é
adequado e consistente com seu contexto.• Uso excessivo de padrões pode criar um projeto pesado.• Algumas pessoas acreditam que o uso de padrões pode limitar a criatividade do
desenvolvedor.
Design Patterns
Aplicabilidade
• Escrevendo padrões: um template
– Pattern Name and Classification– Intent – Also Known As – Motivation – Applicability – Structure – Participants – Collaborations – Consequences – Implementation – Sample Code – Known Uses – Related Patterns
Design Patterns
Exemplo• Manager Design Pattern (from Realtime Mantra Pattern Catalog)
– Intent• The main intention here is to manage multiple entities of same type. For
example, a Terminal Manager will manage all the Terminal objects under its control. This will involve Terminal creation, Terminal deletion, message routing to the Terminal and coordination of activities like switchover between two Terminals.
– Also Known As• Manager-Managed Design Pattern• Managed Object Design Pattern
Design Patterns
Exemplo• Manager Design Pattern cont(2/9)
– Diagram
Manager
objectArray[]
handleMessage(Message msg)Handles all messages to all objectsthat includes creation and deletion
Array that holds the objects
ManagedObject
handleMsg1()handleMsg2()
.
.
.
Methods that handles each kind of message sent to object
Design Patterns
Exemplo• Manager Design Pattern (cont 3/9)
– Motivation• Consider the case where no Manager object is defined. Each Terminal object has
to know about all other Terminal objects for purposes of message routing and coordination. Also, in the absence of a Manager there will be no single point for Terminal object creation and deletion.
– Applicability• This design pattern can be applied whenever a system needs to support many
entities of same or similar type. The Manager object is designed to keep track of all the entities. In many cases, the Manager will also route messages to individual entities.
Design Patterns
Exemplo• Manager Design Pattern (cont 4/9)
– Structure• The Manager object may manage all the entity objects by implementing
standard data structures like array or STL map. The idea is to have a quick way of indexing to get to a particular entity. This indexing capability is required to quickly access an entity from a numerical id assigned to the entity. This numerical id will be typically included in all the messages received for these entities.
– Participants• The Manager object and the Managed Entities are the main actors in this design
pattern. A single Manager object manages multiple entity objects.
Design Patterns
Exemplo• Manager Design Pattern (cont 5/9)
– Collaboration• Manager to Managed Entity communication is typically done via manager
invoking methods for the individual entities. The return value of a method is used by the entity to communicate with the manager. The routing of messages is also achieved by invoking the message handler for the entity object.
• In more complicated designs, the Manager and entity may communicate via local messages. In such cases, the various coordination design patterns like parallel and serial coordination may be used.
Design Patterns
Exemplo• Manager Design Pattern (cont 6/9)
– Consequences• The Manager object introduces a clean interface for communicating with any of
the managed entities. It also provides a centralized point for coordinating operations on multiple entity objects.
– Implementation• As mentioned earlier, the Manager object contains an array or STL map of all
the entities under its control. The entity collection may be maintained as pointers to the entity objects or entity objects themselves.
Design Patterns
Exemplo
• Manager Design Pattern (cont 7/9)
– Sample Code and Usage• class TerminalManager• {• Terminal* terminals[MAX_TERMINALS];• public:• void handleMessage(Msg* pMsg)• {• switch (pMsg->getType())• {• case CREATE_TERMINAL:• terminals[pMsg->getTerminalId()] = new Terminal(pMsg->getTerminalId());• break;• case DELETE_TERMINAL:• delete terminals[pMsg->getTerminalId()];• break;• case RUN_DIAGNOSTICS:• status = terminals[pMsg->getTerminalId()]->handleRunDiagnostics();• break;• case PERFORM_SWITCHOVER:• status1 = terminals[pMsg->getTerminalId1()]->handleOutOfService();• status2 = terminals[pMsg->getTerminalId2()]->handleInService();• break;• }• }• };
Design Patterns
Exemplo
• Manager Design Pattern (cont 8/9)
– Sample Code and Usage
• class Terminal• {• TerminalId terminalId;• public:• Terminal(TerminalID terminalId);• ~Terminal();• Status handleRunDiagnostics();• Status handleOutOfService();• Status handleInService();• };
Design Patterns
Exemplo• Manager Design Pattern (cont 9/9)
– Known Uses• The manager design pattern is used wherever there is a need to manage
multiple objects of same or similar behavior.
– Related Patterns• Feature Design Patterns like parallel and serial coordination.
Design Patterns - Exercício
• Identificar e descrever os design patterns utilizados no projeto, apresentando o racional de uso;
• Identificar e descrever a possibilidade de uso de design patterns no projeto, defendendo o porque da escolha e os impactos da mudança no projeto;
• Extra: identificar novos padrões (designs que podem ser reutilizados em outros projetos) e descrevê-los de acordo com o template apresentado anteriormente;
Universidade Positivo Especialização em Engenharia de Software
Práticas de Desenvolvimento de Software
Tiago Barros | [email protected]