Práticas de Desenvolvimento de Software

110
Universidade Positivo Especialização em Engenharia de Software Práticas de Desenvolvimento de Software Tiago Barros | [email protected]

description

Slides da disciplina de práticas de desenvolvimento de software da pós-graduação em eng. de software da universidade positivo.

Transcript of Práticas de Desenvolvimento de Software

Page 1: Práticas de Desenvolvimento de Software

Universidade Positivo Especialização em Engenharia de Software

Práticas de Desenvolvimento de Software

Tiago Barros | [email protected]

Page 2: Práticas de Desenvolvimento de Software

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

Page 3: Práticas de Desenvolvimento de Software

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

Page 4: Práticas de Desenvolvimento de Software

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.

Page 5: Práticas de Desenvolvimento de Software

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.

Page 6: Práticas de Desenvolvimento de Software

Práticas de Desenvolvimento de Software

Construção de Software

Tiago Barros | [email protected]

Page 7: Práticas de Desenvolvimento de Software

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?

Page 8: Práticas de Desenvolvimento de Software

Construção de Software

Figura retirada do livro Code Complete

Page 9: Práticas de Desenvolvimento de Software

Construção de Software

Figura retirada do livro Code Complete

Page 10: Práticas de Desenvolvimento de Software

Construção de Software

O que significa “codificar e debugar”?

Page 11: Práticas de Desenvolvimento de Software

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

Page 12: Práticas de Desenvolvimento de Software

Construção de Software

Porque construção de

software é importante?

Page 13: Práticas de Desenvolvimento de Software

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

Page 14: Práticas de Desenvolvimento de Software

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.

Page 15: Práticas de Desenvolvimento de Software

Práticas de Desenvolvimento de Software

Paradigmas de Programação

Tiago Barros | [email protected]

Page 16: Práticas de Desenvolvimento de Software

Construção de Software

O que é uma linguagem de programação?

Page 17: Práticas de Desenvolvimento de Software

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

– ____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

Page 18: Práticas de Desenvolvimento de Software

Construção de Software

O que é um paradigma de programação?

Page 19: Práticas de Desenvolvimento de Software

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

– ____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

Page 20: Práticas de Desenvolvimento de Software

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

Page 21: Práticas de Desenvolvimento de Software

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

Page 22: Práticas de Desenvolvimento de Software

• 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

Page 23: Práticas de Desenvolvimento de Software

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.

Page 24: Práticas de Desenvolvimento de Software

• 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

Page 25: Práticas de Desenvolvimento de Software

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

Page 26: Práticas de Desenvolvimento de Software

• 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

Page 27: Práticas de Desenvolvimento de Software

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

Page 28: Práticas de Desenvolvimento de Software

Práticas de Desenvolvimento de Software

Conceitos Básicos de Desenvolvimento

Tiago Barros | [email protected]

Page 29: Práticas de Desenvolvimento de Software

Conceitos Básicos

Como funciona um compilador

Como funciona a execução de um programa

Variáveis e tipos de dados

Page 30: Práticas de Desenvolvimento de Software

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

Page 31: Práticas de Desenvolvimento de Software

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

Page 32: Práticas de Desenvolvimento de Software

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

Page 33: Práticas de Desenvolvimento de Software

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

Page 34: Práticas de Desenvolvimento de Software

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

Page 35: Práticas de Desenvolvimento de Software

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

Page 36: Práticas de Desenvolvimento de Software

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

Page 37: Práticas de Desenvolvimento de Software

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)• _________________________________• _________________________________• _________________________________• _________________________________

Page 38: Práticas de Desenvolvimento de Software

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

Page 39: Práticas de Desenvolvimento de Software

Conceitos Básicos

• Como Funciona um compilador – Ligação > Erros

• Símbolos não existem• _________________________________• _________________________________• _________________________________• _________________________________• _________________________________• _________________________________

Page 40: Práticas de Desenvolvimento de Software

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

Page 41: Práticas de Desenvolvimento de Software

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

Page 42: Práticas de Desenvolvimento de Software

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

Page 43: Práticas de Desenvolvimento de Software

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

Page 44: Práticas de Desenvolvimento de Software

Conceitos Básicos

• Como Funciona a execução de um programa

Registers

MemoryALU

Page 45: Práticas de Desenvolvimento de Software

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”

Page 46: Práticas de Desenvolvimento de Software

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

Page 47: Práticas de Desenvolvimento de Software

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

Page 48: Práticas de Desenvolvimento de Software

Áreas de memória de um programa

Memória e tipos de dados

Variáveis ponteiros

Memória

Page 49: Práticas de Desenvolvimento de Software

Memória

• Classificação

Page 50: Práticas de Desenvolvimento de Software

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

Page 51: Práticas de Desenvolvimento de Software

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

Page 52: Práticas de Desenvolvimento de Software

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

Page 53: Práticas de Desenvolvimento de Software

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;

Page 54: Práticas de Desenvolvimento de Software

Memória

• Variáveis ponteiros– O que significa:

&i*i&intPtr*intPtr

– Os operadores new e deleteint *intPtr = new int;...delete intPtr;

Page 55: Práticas de Desenvolvimento de Software

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

Page 56: Práticas de Desenvolvimento de Software

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?

Page 57: Práticas de Desenvolvimento de Software

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

Page 58: Práticas de Desenvolvimento de Software

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

Page 59: Práticas de Desenvolvimento de Software

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

Page 60: Práticas de Desenvolvimento de Software

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

Page 61: Práticas de Desenvolvimento de Software

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)

Page 62: Práticas de Desenvolvimento de Software

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

Page 63: Práticas de Desenvolvimento de Software

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.

Page 64: Práticas de Desenvolvimento de Software

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.

Page 65: Práticas de Desenvolvimento de Software

Maquina Virtual JAVA

Page 66: Práticas de Desenvolvimento de Software

Chamada de funções e mudança de contexto

Passagem de parâmetros

Ponteiros para funções

Funções

Page 67: Práticas de Desenvolvimento de Software

Funções

• Declaração de funçõestipo nome(argumentos...);

• Corpo das funçõestipo nome(argumentos...){ instruções; return expressão_de_retorno;}

Page 68: Práticas de Desenvolvimento de Software

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

Page 69: Práticas de Desenvolvimento de Software

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++

Page 70: Práticas de Desenvolvimento de Software

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)

Page 71: Práticas de Desenvolvimento de Software

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);

Page 72: Práticas de Desenvolvimento de Software

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();

}

}

Page 73: Práticas de Desenvolvimento de Software

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);

Page 74: Práticas de Desenvolvimento de Software

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)

Page 75: Práticas de Desenvolvimento de Software

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();

Page 76: Práticas de Desenvolvimento de Software

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};

Page 77: Práticas de Desenvolvimento de Software

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.

Page 78: Práticas de Desenvolvimento de Software

Práticas de Desenvolvimento de Software

Design de Software

Tiago Barros | [email protected]

Page 79: Práticas de Desenvolvimento de Software

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

Page 80: Práticas de Desenvolvimento de Software

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)

Page 81: Práticas de Desenvolvimento de Software

Níveis de Design

Figura retirada do livro Code Complete

Page 82: Práticas de Desenvolvimento de Software

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

Page 83: Práticas de Desenvolvimento de Software

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);

Page 84: Práticas de Desenvolvimento de Software

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.

Page 85: Práticas de Desenvolvimento de Software

Design de Software

Voltando ao Design...

Page 86: Práticas de Desenvolvimento de Software

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

Page 87: Práticas de Desenvolvimento de Software

Design de Software

Porque?

• Design envolve restrições e trade offs

• Design é não determinístico

• Design é um processo heurístico

Page 88: Práticas de Desenvolvimento de Software

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

Page 89: Práticas de Desenvolvimento de Software

Design de Software

Então porque Design

Patterns?

Page 90: Práticas de Desenvolvimento de Software

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

Page 91: Práticas de Desenvolvimento de Software

Práticas de Desenvolvimento de Software

Design Patterns

Tiago Barros | [email protected]

Page 92: Práticas de Desenvolvimento de Software

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.

Page 93: Práticas de Desenvolvimento de 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.

Page 94: Práticas de Desenvolvimento de Software

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.

Page 95: Práticas de Desenvolvimento de Software

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.

Page 96: Práticas de Desenvolvimento de Software

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.”

Page 97: Práticas de Desenvolvimento de Software

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.

Page 98: Práticas de Desenvolvimento de Software

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.

Page 99: Práticas de Desenvolvimento de Software

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

Page 100: Práticas de Desenvolvimento de Software

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

Page 101: Práticas de Desenvolvimento de Software

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

Page 102: Práticas de Desenvolvimento de Software

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.

Page 103: Práticas de Desenvolvimento de Software

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.

Page 104: Práticas de Desenvolvimento de Software

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.

Page 105: Práticas de Desenvolvimento de Software

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.

Page 106: Práticas de Desenvolvimento de Software

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;• }• }• };

Page 107: Práticas de Desenvolvimento de Software

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();• };

Page 108: Práticas de Desenvolvimento de Software

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.

Page 109: Práticas de Desenvolvimento de Software

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;

Page 110: Práticas de Desenvolvimento de Software

Universidade Positivo Especialização em Engenharia de Software

Práticas de Desenvolvimento de Software

Tiago Barros | [email protected]