Buscar

Projeto e desenvolvimento de sistemas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 70 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 70 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 70 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

1 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2 
 
 
SUMÁRIO 
1 INTRODUÇÃO ..................................................................................... 4 
2 PROCESSOS DE SOFTWARE ........................................................... 5 
2.1 PROCESSOS DE SOFTWARE E SUAS ETAPAS ....................... 5 
3 REQUISITOS DE UM SOFTWARE ..................................................... 7 
3.1 REQUISITOS FUNCIONAIS ......................................................... 8 
3.2 REQUISITOS NÃO FUNCIONAIS ................................................ 8 
4 PROCESSO DE DESENVOLVIMENTO E GERENCIAMENTO DE UM 
SOFTWARE .......................................................................................................... 12 
5 PADRÕES DE PROJETO DE ARQUITETURA DE SISTEMAS ........ 15 
5.1 DEFINIÇÃO E SURGIMENTO DOS PADRÕES DE 
PROJETOS....... ................................................................................................ 16 
5.2 VANTAGENS EM UTILIZAR PADRÕES DE PROJETOS .......... 18 
6 QUAL É O MELHOR PADRÃO DE PROJETO PARA O SEU 
SOFTWARE? ........................................................................................................ 20 
7 TIPOS DE PADRÕES DE PROJETO ................................................ 24 
7.1 CREATIONAL PATTERNS (PADRÕES DE CRIAÇÃO) ............. 24 
7.2 STRUCTURAL PATTERNS (PADRÕES ESTRUTURAIS) ......... 25 
7.3 BEHAVIORAL PATTERNS (PADRÕES COMPORTAMENTAIS) 26 
8 MÉTODOS ÁGEIS ............................................................................. 28 
8.1 CONCEITO DE MÉTODO ÁGIL ................................................. 29 
8.2 FERRAMENTAS ELETRÔNICAS DE MÉTODOS ÁGEIS .......... 30 
 
 
3 
 
9 VALORES E PRINCÍPIOS ÁGEIS ..................................................... 32 
10 PRINCIPAIS MÉTODOS ÁGEIS EXISTENTES ............................. 36 
11 TEST-DRIVEN DEVELOPMENT ................................................... 44 
11.1 SURGIMENTO DE UM MÉTODO DE DESENVOLVIMENTO 
DIRIGIDO POR TESTES ................................................................................... 44 
11.2 HISTÓRICO ................................................................................ 45 
11.3 CONCEITOS DO TEST-DRIVEN DEVELOPMENT ................... 46 
11.4 O TEST-DRIVEN DEVELOPMENT NO CICLO DE VIDA DO 
SOFTWARE.... .................................................................................................. 50 
11.5 DOCUMENTAÇÃO ..................................................................... 62 
12 VANTAGENS E DESVANTAGENS DO TEST-DRIVEN 
DEVELOPMENT ................................................................................................... 63 
12.1 VANTAGENS DA UTILIZAÇÃO DO TEST-DRIVEN 
DEVELOPMENT ................................................................................................ 64 
12.2 DESVANTAGENS DA UTILIZAÇÃO DO TEST-DRIVEN 
DEVELOPMENT ................................................................................................ 65 
13 REFERÊNCIAS BIBLIOGRÁFICAS ............................................... 68 
 
 
 
 
 
 
 
 
 
 
4 
 
1 INTRODUÇÃO 
 
Prezado aluno! 
 
O Grupo Educacional FAVENI, esclarece que o material virtual é 
semelhante ao da sala de aula presencial. Em uma sala de aula, é raro – quase 
improvável - um aluno se levantar, interromper a exposição, dirigir-se ao professor 
e fazer uma pergunta, para que seja esclarecida uma dúvida sobre o tema tratado. 
O comum é que esse aluno faça a pergunta em voz alta para todos ouvirem e todos 
ouvirão a resposta. No espaço virtual, é a mesma coisa. Não hesite em perguntar, 
as perguntas poderão ser direcionadas ao protocolo de atendimento que serão 
respondidas em tempo hábil. 
Os cursos à distância exigem do aluno tempo e organização. No caso da 
nossa disciplina é preciso ter um horário destinado à leitura do texto base e à 
execução das avaliações propostas. A vantagem é que poderá reservar o dia da 
semana e a hora que lhe convier para isso. 
A organização é o quesito indispensável, porque há uma sequência a ser 
seguida e prazos definidos para as atividades. 
Bons estudos! 
 
 
 
 
 
 
 
 
 
 
5 
 
2 PROCESSOS DE SOFTWARE 
Um dos itens primordiais de fator de sucesso em empresas de 
desenvolvimento de software é a utilização de um processo de software, que pode 
ser definido brevemente como um conjunto de atividades exigidas no 
desenvolvimento de um sistema de software. Logo, pode-se dizer que se trata de 
um conjunto de atividades e resultados que juntos produzem um software. Essas 
atividades são relacionadas entre elas e operam de acordo com padrões 
preestabelecidos para alcançar um objetivo ou resultado desejado. Ou seja, a partir 
dessa definição, você pode produzir um software de alta qualidade e custo baixo 
Sommerville (2011). 
A partir desses conceitos, pode-se considerar que um processo de software 
pode ser visto como um conjunto de atividades, métodos, ferramentas e práticas 
que podem ser utilizadas para construir um produto. Entre as atividades 
relacionadas ao processo de software, estão: especificação, desenvolvimento, 
verificação e manutenção Sommerville (2011). 
 
2.1 PROCESSOS DE SOFTWARE E SUAS ETAPAS 
As principais fases de um processo de software são: a especificação de 
requisitos, na qual são traduzidas as necessidades ou requisitos operacionais para 
a descrição da funcionalidade a ser implementada; o projeto de sistema, no qual 
tudo o que foi traduzido terá uma descrição item a item de componentes necessários 
para a codificação do software; a programação propriamente dita, em que ocorre a 
codificação que controla o sistema e é implementada a lógica necessária; a 
verificação, onde se observa se todos os requisitos iniciais foram implementados e 
o objetivo alcançado Sommerville (2011). 
 
 
6 
 
Segundo Sommerville (2011), podemos identificar as seguintes atividades 
no processo de software: 
Especificação 
 
• Engenharia de sistema: solução para o problema em questão, 
envolve questões amplas, inclusive que sejam a parte em relação ao 
software, porém pertençam ao problema a ser solucionado. 
• Análise de requisitos: área em que as necessidades para atender 
ao cliente são levantadas, tendo como principal objetivo especificar 
os requisitos documentando-os. 
• Especificação do sistema: ocorre a descrição funcional do 
software, incluindo planos de testes para verificar se está adequado. 
 
Projeto 
 
• Arquitetura: neste item, ocorre o desenvolvimento do modelo 
conceitual para o software, composto de módulos que podem ser 
independentes. 
• Interface: é definida e estudada a interface de comunicação para 
cada módulo. 
• Detalhamento: neste item, os módulos são definidos e podem ser 
traduzidos para pseudocódigos. 
 
Implementação 
 
Codificação: a implementação e o desenvolvimento em si do software. 
 
Validação 
 
 
 
7 
 
• Teste unitário: ocorre a realização de testes para verificar se há erros 
e se o comportamento está adequado. 
• Integração: união de diferentes módulos do software em um só, 
assim como a verificação da interação entre eles quando estão 
funcionando em conjunto. 
 
Manutenção e evolução 
 
• O software desenvolvido e implementado entra em um ciclo que 
abrange todas as fases anteriores. 
 
 
3 REQUISITOS DE UM SOFTWARE 
Requisitos são condições que devem ser alcançadas, ou seja, é o que um 
software ou componente deve possuir para satisfazer uma especificação de um 
sistema a fim de atender às necessidades dos clientes, restrições e serviços que 
devem ser contemplados. Normalmente são identificados a partir das regras de 
negócio estabelecidas, que estão diretamente ligadas à área específica em que o 
software será desenvolvido. Durante o levantamento de requisitos, os 
desenvolvedores devem ter conhecimento sobre o queo sistema deverá 
proporcionar e compreender a necessidade do usuário. Entre os requisitos, existem 
os funcionais e os não funcionais Sommerville (2011). 
 
 
 
8 
 
3.1 REQUISITOS FUNCIONAIS 
Requisitos funcionais são os que abordam o que o software deverá fazer, 
como deverá reagir a entradas específicas e o comportamento. Dependem do tipo 
de software que será desenvolvido, de quem o utilizará e da maneira como é feita 
a escrita dos requisitos pela empresa. Ou seja, pode ser descrito de uma forma mais 
abstrata para que o usuário do sistema tenha uma compreensão mais fácil ou 
podem ser mais específicos tecnicamente, com entradas, saídas, exceções e 
restrições Sommerville (2011). 
Como um dos problemas em desenvolvimento de software, pode-se citar a 
imprecisão na especificação dos requisitos, o que pode ocasionar atrasos e 
aumento de custos na engenharia do software. Por essa razão, preza-se que seja 
sempre completa e consistente, sendo todos os serviços requeridos pelo usuário 
explícitos plenamente Sommerville (2011). 
 
3.2 REQUISITOS NÃO FUNCIONAIS 
Requisitos não funcionais são restrições aos serviços ou às funções 
oferecidos pelo software, incluindo normas e timing e, normalmente, aplicam-se ao 
software como um todo. Não estão relacionados diretamente a serviços específicos 
que sejam oferecidos pelo software, podem estar relacionados às propriedades do 
sistema, como: tempo de retorno, confiabilidade. Normalmente especificam ou 
restringem características do sistema e frequentemente são mais críticos que os 
funcionais, ou seja, se deixar de atendê-los, pode ser que o sistema seja inutilizado 
Sommerville (2011). 
Os requisitos não funcionais podem afetar a arquitetura do software, 
assegurando que sejam cumpridos requisitos de desempenho, organizando o 
sistema para que seja minimizada a comunicação entre componentes. Você poderá 
 
 
9 
 
verificar que um único requisito não funcional poderá gerar outros requisitos 
funcionais relacionados a ele, os quais possam definir serviços necessários, como 
um requisito de proteção. A Figura 1 apresenta tipos de requisitos não funcionais, 
segundo Sommerville (2011). 
 
 
Fonte: Adaptado de Sommerville (2011) 
Geralmente, os requisitos não funcionais conflitam com outros requisitos funcionais 
ou não funcionais. 
A especificação de requisitos de software nada mais é do que um documento oficial, 
em que os desenvolvedores baseiam-se para implementar o software solicitado. 
Esse documento deve incluir requisitos de usuário e uma especificação detalhada 
 
 
10 
 
dos requisitos (funcionais e não funcionais) de sistema, ou seja, esses documentos 
são essenciais quando alguém está desenvolvendo um sistema. O Quadro 1 mostra 
usuários desses documentos e como eles o utilizam, conforme Kotonya e 
Sommerville (1998). 
 
 
Fonte: Adaptado de Sommerville (2011) 
Dessa forma, você deverá incluir em documento de requisitos detalhes que 
dependerão do tipo de software que deverá ser desenvolvido e o processo utilizado 
Sommerville (2011). 
O quadro a seguir apresenta uma maneira de organizar o documento de 
requisitos com base na norma IEEE (IEEE, 1998). 
 
 
 
 
11 
 
 
 
 
12 
 
 
Fonte: IEEE (IEEE, 1998). 
 
4 PROCESSO DE DESENVOLVIMENTO E GERENCIAMENTO DE UM 
SOFTWARE 
Conforme abordado anteriormente, o documento de especificação é um 
item primordial para que o software seja desenvolvido de acordo com as 
necessidades dos clientes, com as restrições necessárias, abordando 
confiabilidade, portabilidade, segurança e usabilidade, assim como desempenho e 
hardware necessário. A Figura abaixo mostra as fases e cada uma de suas etapas 
antes do desenvolvimento do software Sommerville (2011). 
 
 
 
13 
 
 
Fonte: Adaptado de Sommerville (2011) 
A análise e a elicitação de requisitos envolvem vários tipos de pessoas de 
uma organização, geralmente o stakeholder, que inclui usuários finais que 
interagirão direto com o sistema, e alguma outra pessoa que será afetada direta ou 
indiretamente pelo software Sommerville (2011). 
 
 
14 
 
O gerenciamento de projetos em software leva em consideração primeiro a 
qualidade, a produtividade e a redução de riscos. Os pontos técnicos devem incluir 
a definição do ciclo de vida e tipos de planos a serem utilizados para testes, 
documentação, desenvolvimento, qualidade e gerenciamento Sommerville (2011). 
No quesito ciclo de vida do software, identificam-se três fases: definição, 
desenvolvimento e operação. Em definição, os requisitos são determinados e a 
viabilidade é estudada, assim como o planejamento de atividades é elaborado. Na 
fase do desenvolvimento, são realizadas atividades para a produção do software, 
como: concepção, especificação, design de interface, prototipação, arquitetura, 
codificação e verificação. Na fase da operação, o software será utilizado pelos 
usuários e podem ocorrer manutenções, para correções ou evoluções Sommerville 
(2011). 
Os principais motivos para problemas apresentados estão relacionados a 
falhas no gerenciamento de projetos durante a fase de desenvolvimento, segundo 
Standish Group (1994). Uma das tarefas de um gestor de projetos é identificar as 
partes mais difíceis e buscar soluções eficientes Sommerville (2011). 
O gestor de projetos deve trabalhar com ideias e com pessoas, tendo como 
principais atividades planejamento, assessoria, organização, saber dirigir e 
controlar o projeto. Da mesma forma que deve ter comprometimento com equipe, 
prazos, custos e qualidade em suas entregas Sommerville (2011). 
Como há muitas mudanças de requisitos, o ciclo mostrado na figura 
apresentada deve ser repetido toda vez que for necessário. As novas técnicas com 
metodologias ágeis facilitam a vida dos gerentes de projeto desde que estes tenham 
uma equipe qualificada e comprometida, pois podem facilitar a adaptação às 
mudanças que ocorrem no decorrer dos projetos Sommerville (2011). 
É importante que aspectos como arquitetura de sistema, linguagem de 
programação, sistema gerenciador de banco de dados e padrão de interface gráfica 
sejam considerados na fase do projeto Sommerville (2011). 
 
 
15 
 
É fundamental que gerentes de projeto estejam atualizados sobre novas 
tecnologias, ferramentas, metodologias, modelos e melhores práticas para que o 
projeto tenha sucesso e o desenvolvimento seja eficaz e eficiente Sommerville 
(2011). 
 
5 PADRÕES DE PROJETO DE ARQUITETURA DE SISTEMAS 
O processo de desenvolvimento de software consiste em inúmeras 
atividades determinadas e organizadas, que têm como objetivo resolver um 
problema da área de tecnologia da informação. O objetivo principal dessas 
atividades é satisfazer as necessidades dos clientes/ usuários do sistema. Para 
tanto, é preciso analisar os requisitos do sistema e projetar e implementar um código 
padronizado, para evitar erros e falhas Zenker (2020). 
Padronizar consiste em empregar técnicas e padrões que auxiliam no 
desenvolvimento e aumentam a produtividade, a segurança e a qualidade no 
projeto. Um padrão é um molde, um exemplo, um protótipo, um paradigma ou uma 
referência de algo a seguir. Um projeto é um desenho, uma planta, um esquema, 
um plano ou um programa Zenker (2020). 
Padrões de projeto (do inglês design patterns) são alternativas ou modelos 
de soluções para problemas encontrados no desenvolvimento de um projeto de 
software independente do paradigma; porém, sua aplicabilidade maior é no 
paradigma orientado a objetos. Os padrões de projetos facilitam a reutilização de 
soluções e arquiteturas de software de forma fácil e flexível, reduzindo a 
complexidade do projeto e resolvendo os problemas apresentados Zenker(2020). 
 
 
 
16 
 
5.1 DEFINIÇÃO E SURGIMENTO DOS PADRÕES DE PROJETOS 
Os padrões de projetos, comumente conhecidos como design patterns, são 
modelos, isto é, referências aplicadas ao projeto, trazendo soluções para problemasespecíficos do desenvolvimento do projeto de software orientado a objetos. Os 
padrões são aplicáveis a outros paradigmas, porém, não são tão relevantes quanto 
no paradigma orientado Zenker(2020). 
Por meio dos design patterns, é possível definir nomes e descrever o 
problema e a solução a ser aplicada ao projeto. Eles trazem exemplos de 
implementações e uma organização geral de classes e objetos. Os padrões de 
projetos facilitam a reutilização de soluções e arquiteturas bem-sucedidas na 
construção de um projeto com paradigma orientado a objetos. Além disso, eles 
promovem a organização no código e garantem ao programador um código limpo e 
padronizado, além de melhorar a documentação e a manutenção do sistema, ao 
fornecer uma especificação de interações entre os objetos das classes 
Zenker(2020). 
Em resumo, os padrões de projetos auxiliam o projetista, o desenvolvedor 
e o analista a obterem um projeto adequado, sendo uma solução para um problema 
em um determinado contexto Zenker(2020). 
Os problemas surgem com o desenvolvimento do projeto, podendo ser uma 
dificuldade em desenvolver ou apenas um desafio. O contexto determina qual 
padrão deve ser aplicado para a resolução do problema. A solução surge com a 
escolha do padrão (pattern) adequado ao projeto em questão. Todo padrão de 
projeto possui elementos ou componentes essenciais, conforme listado a seguir. 
 
• Nome: descreve a essência do padrão; é uma referência para poder 
escrever o problema do projeto. 
• Objetivo: descreve como o padrão atua, em que modelo de software 
se aplica. 
 
 
17 
 
• Problema: descreve o problema, em que situação se aplica o padrão. 
• Contexto: descreve uma situação que complemente o problema. 
• Solução: descreve a solução; é uma descrição abstrata de um 
problema e de como as classes e os objetos o resolverão. 
• Consequências: descreve as vantagens e desvantagens da 
utilização do padrão; são críticas para a avaliação de alternativas de 
projetos e a compreensão de custos e benefícios para aplicação no 
software desenvolvido Zenker(2020). 
 
O padrão de projetos surgiu como um conceito de arquitetura, no final dos 
anos 1970, documentado no livro A Pattern Language: Towns, Buildings, 
Construction. Nesse livro, os arquitetos Christopher Alexander, Sara Ishikawa e 
Murray Silverstein catalogaram 253 tipos de problemas de projeto e desafios e 
analisaram cada situação, descrevendo e propondo um padrão de solução. O livro 
foi publicado em português em 2012, com o nome Uma Linguagem de Padrões — 
a Pattern Language Zenker(2020). 
Nos anos 1980, os engenheiros de software Kent Beck e Ward Cunninghan 
começaram a aplicar a ideia de padrões na área de programação em uma palestra 
denominada "Utilizando a linguagem dos padrões para programação orientada a 
objetos”, em tradução livre. Porém, somente nos anos 1990, os padrões ganharam 
credibilidade, após serem publicados no livro Design Patterns — Elements of 
Reusable Object-Oriented Software, escrito por Erich Gamma, Richard Helm, Ralph 
Johnson e John Vlissides Zenker(2020). 
O livro apresentou 23 padrões de projetos. Os autores ficaram conhecidos 
como a gangue dos quatro (GoF, do inglês gang of four), termo utilizado nos 
padrões definidos no livro Zenker(2020). 
Os padrões facilitam o desenvolvimento do projeto, conforme apontam 
Gamma et al. (2000, p. 17): 
 
 
 
18 
 
 Uma coisa que os melhores projetistas sabem que não devem fazer é 
resolver cada problema a partir de princípios elementares ou do zero. 
Quando encontram uma boa solução, eles a utilizam repetidamente. 
Consequentemente, você encontrará padrões de classes e de 
comunicação entre objetos. Esses padrões resolvem problemas 
específicos de projetos e tornam os projetos orientados a objetos mais 
flexíveis e, em última instância, reutilizáveis. 
 
5.2 VANTAGENS EM UTILIZAR PADRÕES DE PROJETOS 
Os padrões de projetos são modelos que já foram utilizados, implementados 
e testados em diversos projetos, o que traz segurança ao utilizá-los, além de outras 
vantagens, descritas a seguir Zenker(2020). 
 
• Com o uso de padrões de nomenclatura, o projeto possuirá nomes 
estandardizados, trazendo referência e credibilidade para o software 
desenvolvido. 
• Melhorar técnicas e princípios da programação orientada a objetos, 
como implementação de herança, composição e polimorfismo. 
• Aumentar a organização e a manutenção de projetos, já que esses 
padrões se baseiam em baixo acoplamento entre as classes e 
padronização do código. 
• Melhorar o desenvolvimento de projetos tanto individualmente 
quanto em equipe. 
• Implementar hierarquias de herança, diminuindo o tamanho do 
projeto e aprimorando o mesmo. 
• Facilitar a manutenção do projeto e a edição do código. 
• Utilizar o padrão para a refatoração de um código ruim, altamente 
acoplado e de baixa coesão. 
 
 
 
19 
 
Veja a seguir a terminologia relacionada ao programa orientado a objetos: 
 
• Classe: representa um conjunto de objetos com 
características afins. Uma classe define o comportamento do 
objeto, por meio de métodos, e quais estados ele é capaz de 
manter, por meio de atributos. 
• Atributos: são características de um objeto. Basicamente, 
trata-se da estrutura de dados que vai representar a classe. 
• Métodos: definem as habilidades dos objetos. São ações que 
o objeto pode fazer ou sofrer. 
• Objeto: instância da classe, elemento que foi gerado por meio 
da classe. 
• Interface: é um contrato entre a classe e o mundo externo. 
Quando uma classe implementa uma interface, ela está 
comprometida a fornecer o comportamento publicado pela 
interface. 
• Abstração: é a habilidade de se concentrar nos aspectos 
essenciais de um contexto qualquer, ignorando características 
menos importantes ou acidentais. Em modelagem orientada a 
objetos, uma classe é uma abstração de entidades existentes 
no domínio do sistema de software. 
• Associação: é o mecanismo pelo qual um objeto utiliza os 
recursos de outro. Pode tratar-se de uma associação simples 
"usa um" ou de um acoplamento "parte de". 
• Coesão: é quando as tarefas que um elemento realiza estão 
relacionadas a um mesmo conceito; é o princípio da 
responsabilidade única, isto é, a ideia de que a classe não 
deve assumir responsabilidades que não são suas. 
 
 
20 
 
• Sobrecarga: é a utilização do mesmo nome para símbolos ou 
métodos com operações ou funcionalidades distintas. 
Geralmente os métodos se diferenciam pela sua assinatura. 
• Acoplamento: significa o quanto uma classe depende da 
outra para funcionar. Surge da associação entre as classes; 
conforme for a dependência entre ambas, surge o termo 
“fortemente acopladas”. 
• Refatoração: é o processo de alterar um software de maneira 
que não mude o seu comportamento externo e ainda melhore 
a sua estrutura interna, modificando apenas a estrutura 
interna do código. 
 
 
6 QUAL É O MELHOR PADRÃO DE PROJETO PARA O SEU SOFTWARE? 
Encontrar o padrão de projeto adequado ao software é difícil. Os padrões 
de GoF, segundo Gamma et al. (2000), apontam 23 padrões na lista de escolhas. 
Porém, é fundamental seguir alguns critérios, com o objetivo de solucionar o 
problema do projeto sem cometer erros e tornando o projeto o mais padronizado e 
organizado possível. Observe a figura abaixo: 
 
 
 
21 
 
 
Fonte: Gamma et al. (2000) 
Cada padrão de projeto é dividido em seções, consistindo em critérios que 
apresentam e justificam seu uso, possibilitando comparações, entendimento e 
aplicabilidade Zenker(2020). Entre os critérios para a escolha do melhor padrão, 
destacam-se os seguintes: 
 
 
 
22 
 
1. Considerar como os padrões de projeto solucionam problemas de 
projeto. Avaliar a necessidade do software e qual é a intenção ao 
utilizar o padrão. 
2. Examinar qual é a intenção do padrão, o que faz, de fato, o padrão 
de projeto, quais são os princípios do modelo e se o mesmosolucionará o problema em questão. 
3. Estudar como os padrões se relacionam. Avaliar, por meio da tabela 
de escopo e propósitos do projeto (Quadro 1), qual é a relação 
existente entre os padrões. 
4. Estudar as semelhanças existentes entre os padrões. Verificar 
semelhanças entre os grupos de padrões de criação, estruturados e 
comportamentais. 
5. Examinar uma causa de reformulação de projeto. 
6. Considerar o que deveria ser variável no seu projeto; ou seja, em vez 
de considerar o que pode forçar uma mudança em um projeto, deve-
se considerar o que se deseja mudar sem necessitar reprojetá-lo. 
 
 
 
23 
 
 
Fonte: Adaptado de Gamma et al. (2000). 
Analisando o Quadro acima, percebe-se que o primeiro critério abordado é 
a finalidade do padrão, separada em três propósitos: criação, estrutura e 
comportamento. Além do propósito, há o escopo definido, que estabelece se o 
padrão é relacionado a classes e subclasses ou envolve objetos. Os padrões 
relacionados a classes e subclasses são estáticos, enquanto os padrões 
relacionados a objetos são dinâmicos, isto é, podem ser modificados no tempo real 
do projeto. 
 
 
 
24 
 
7 TIPOS DE PADRÕES DE PROJETO 
Seguindo o repositório GoF definido no livro de Gamma et al. (2000), os 
padrões são listados de acordo com o contexto aplicado e o tipo de problema. Os 
principais padrões de projetos são divididos em segmentos de criação (creational 
patterns), estrutura (structural patterns) e padrões de comportamento (behavioral 
patterns) Zenker(2020). 
 
7.1 CREATIONAL PATTERNS (PADRÕES DE CRIAÇÃO) 
O objetivo desse tipo de padrão é a abstração da instância de objetos. É 
possível criar um objeto sem se preocupar com o todo envolvido na criação desse 
componente. Esse padrão abstrai ou adia o processo de criação, tornando o sistema 
independente de como os seus objetos são criados. O mesmo pode impedir que um 
sistema crie mais de um objeto de uma classe, ou pode postergá-lo até o tempo de 
execução Zenker(2020). 
Suponha o projeto do jogo Imagem e Ação, em que os jogadores 
desenharão objetos para que os outros adivinhem. O usuário pode desenhar 
qualquer forma, sendo figuras vetoriais geométricas ou vetoriais à mão livre. 
Supondo que cada forma no programa de desenho seja representada por um objeto, 
no tempo de execução do projeto, não se sabe a forma que o usuário desenhará. 
Com base na entrada do jogador, o programa deve ser capaz de determinar em que 
classe instanciar um objeto. Se o jogador criar um retângulo na interface gráfica do 
utilizador (GUI, do inglês graphical user interface), nosso programa deve estar 
preparado para a instância de um objeto da classe Rect(). Quando o jogador decide 
qual objeto desenhar, o programa deve determinar em que subclasse específica 
deve instanciar esse objeto Zenker(2020). 
Os padrões de criação são os seguintes. 
 
 
25 
 
• Abstract Factory: fornece uma interface para a criação de conjuntos 
de objetos relacionados ou dependentes, sem precisar especificar 
sua classe 
• Builder: separa a construção de um objeto complexo da sua 
representação. Possibilita que seu processo de construção crie 
diferentes representações 
• Factory Method: define a interface para a criação de um objeto, mas 
são as subclasses que decidem qual classe deve ser instanciada. 
• Prototype: especifica os tipos de objetos a serem criados usando 
uma instância prototípica e criando objetos copiando esse protótipo 
• Singleton: garante que a classe tenha somente uma instância e 
fornece um ponto global de acesso a ela. 
 
7.2 STRUCTURAL PATTERNS (PADRÕES ESTRUTURAIS) 
 
O objetivo desse padrão é a organização e a estruturação das classes e 
dos seus relacionamentos com os objetos. Ao contrário do padrão de criação, o 
padrão de estrutura é voltado para os objetos, descrevendo maneiras de montá-los, 
isto é, a maneira como as classes e os objetos serão compostos para formar 
estruturas maiores. A flexibilidade obtida pela composição de objetos provém da 
capacidade de mudar a composição em tempo de execução Zenker(2020). 
Segundo Ricardo (2006), do site DevMedia, um exemplo do uso do padrão 
estruturado é no framework Hibernate. Este faz uso do padrão proxy ao executar a 
técnica utilizada para acessar o banco de dados apenas quando for necessário. Em 
muitas buscas, o Hibernate usa o método session.load(id); nesse momento, um 
proxy para o objeto real é retornado. Nesse caso, o objeto ainda não está 
completamente preenchido, pois nenhum SQL foi realizado até esse momento. 
 
 
26 
 
Apenas quando uma propriedade desse objeto (método getX) ou um 
relacionamento (por exemplo, empresa.getFuncionarios()) for chamado, a consulta 
no banco será realizada — tudo isso de forma transparente para o cliente 
Zenker(2020). 
Os padrões de estrutura são os seguintes. 
 
• Adapter: converte a interface de uma classe em outra interface 
esperada pelo cliente. O Adapter permite que as classes trabalhem 
em conjunto para promover essa mudança. 
• Bridge: separa uma abstração da sua implementação, permitindo 
uma variação individual de cada uma. 
• Composite: compõe objetos em estruturas hierárquicas, como 
árvores. Trata objetos individuais e composições de objetos de forma 
uniforme. 
• Decorator: atribui de forma dinâmica responsabilidades adicionais a 
um objeto. 
• Façade: fornece uma interface unificada para um conjunto de 
interfaces em subsistema. 
• Flyweight: suporta grandes quantidades de objetos de forma 
eficiente, por meio de compartilhamento. 
• Proxy: fornece um objeto representante (surrogate) ou marcador de 
outro objeto. 
 
7.3 BEHAVIORAL PATTERNS (PADRÕES COMPORTAMENTAIS) 
O objetivo é delegar responsabilidades, definindo como os objetos devem 
se comportar e se comunicar. Esses padrões se concentram nos algoritmos 
Zenker(2020). 
 
 
27 
 
São 11 os padrões comportamentais, que são descritos a seguir 
Zenker(2020). 
 
• Chain of Responsibility: evita o acoplamento de remetente de uma 
solicitação ao destinatário, dando chance ao objeto para tratar a 
solicitação. 
• Command: encapsula uma solicitação como objeto, permitindo 
parametrizar clientes com diferentes solicitações, enfileirando ou 
registrando os “logs” de solicitações. 
• Interpreter: define para a linguagem uma representação gramatical 
dentro do interpretador. 
• Iterator: possibilita o acesso sequencial dos elementos de uma 
agregação de objetos, sem a necessidade de expor sua 
representação subjacente 
• Mediator: define um objeto que encapsula a forma como um 
conjunto de objetos interage 
• Memento: captura e externaliza um estado interno do objeto sem 
violar seu encapsulamento, possibilitando restaurar para esse estado 
— por exemplo, um controle de históricos de ações. 
• Observer: define uma dependência um-para-muitos entre objetos; 
quando um objeto muda, todos os seus dependentes são notificados 
e atualizados automaticamente. 
• State: permite que o objeto altere seu comportamento quando o 
estado interno for modificado. 
• Strategy: define uma família de algoritmos, encapsulando cada um 
e os tornando intercambiáveis. 
• Template Method: define o esqueleto de um algoritmo em uma 
operação, postergando a definição de alguns passos para 
subclasses. 
 
 
28 
 
• Visitor: representa uma operação a ser executada sobre os 
elementos da estrutura de um objeto 
 
8 MÉTODOS ÁGEIS 
Atualmente, dois cenários impactam a rotina dos desenvolvedores: o 
cenário da big data e o cenário da Internet das Coisas. Profissionais que estudam 
software e atuam na área de desenvolvimento de software, sistemas e sites são 
forçados a implementar tecnologias novas a todo momento. A Internet das Coisas 
fez com que câmeras, smartphones e relógios fiquem conectados à internet a todo 
momento, e as empresas veem nisso uma oportunidade para estudar 
comportamentos através dos logs e registros das pessoas nos sistemas. Quemquer 
que trabalhe na área certamente será forçado a adaptar software rapidamente às 
tecnologias que surgem diariamente. Por isso, a rotina dos desenvolvedores é 
recheada de adrenalina (Andrade, 2020). 
Em pouco tempo, vimos os sites que possuíam linguagens HTML 4, CSS , 
PHP 5 e JavaScript se tornarem HTML 5 com suas animações, CSS 3, com suas 
decorações extravagantes, PHP 7, com sua agilidade e códigos novos, e JavaScript 
React, Angular e JQuery, trazendo novas formas de controlar e manipular os 
elementos frontais das páginas. Além disso, você deve ter percebido que os bancos 
de dados SQL ganharam a companhia dos bancos NoSQL, que chegaram com 
agilidade para sites que contêm muita interação com pessoas. Na criação de 
software, percebemos que o que antes era feito através de Ionic, um framework 
JavaScript que cria aplicativos com plugins, hoje é feito através de React Native, 
que traz experiências mais satisfatórias ao usuário e usa a linguagem nativa dos 
aparelhos mobiles (Andrade, 2020). 
Neste cenário, várias formas de planejamento de criação de software 
disputam as decisões das equipes que desenvolvem, e disso surgem dúvidas 
 
 
29 
 
quanto ao critério de escolha do método de desenvolvimento de software mais 
dinâmico e condizente com o tempo em que vivemos. De acordo com Sommerville 
(2011), em 1980, com o surgimento das linguagens de quarta geração, e em 1990, 
com o surgimento de metodologias ágeis, como a Metodologia de Desenvolvimento 
de Sistemas Dinâmicos e a Metodologia Extreme Programming, os 
desenvolvedores se viram forçados a mudar a forma de trabalho. Vamos discutir um 
pouco sobre isso neste capítulo Andrade, (2020). 
 
8.1 CONCEITO DE MÉTODO ÁGIL 
O desenvolvimento ágil envolve mudanças rápidas e prioriza-se, às vezes, 
agilidade frente à qualidade — alguns analistas dizem que este método é uma 
resposta ao cenário tecnológico. Após se fazer um planejamento de etapas de 
requisitos, é comum ter que se deparar com mudanças dos próprios requisitos, e 
isso é aceito neste método de desenvolvimento, pois não impossível antever todas 
as necessidades do mercado, visto que elas mudam com frequentemente; em 
alguns casos, os requisitos mudam depois da entrega do projeto (SOMMERVILLE, 
2011). 
De acordo com Amaral et al. (2012, p. 21) o conceito de ágil pode ser visto 
como: 
[...] é uma abordagem fundamentada em um conjunto de princípios, cujo 
objetivo é tornar o processo de gerenciamento de projetos mais simples, 
flexível e iterativo, de forma a obter melhores resultados em desempenho 
(tempo, custo e qualidade), menos esforço em gerenciamento e maiores 
níveis de inovação e agregação de valor para o cliente. 
 
O desenvolvimento ágil é feito em equipes multidisciplinares, onde os 
processos são feitos em espiral e as equipes priorizam conversas em detrimento da 
documentação, ou seja, a rigidez é menor. Aqui, é mais importante a funcionalidade 
 
 
30 
 
do software do que a documentação; é mais importante satisfazer as necessidades 
do cliente do que seguir um plano. No método ágil, os colaboradores têm perfil 
motivado, as entregas são semanais e não mensais, o que facilita o 
acompanhamento da satisfação do cliente. Logo, neste modelo, as adaptações 
falam mais alto do que a disciplina, e o processo de criação de software é 
transparente, o cliente vê tudo, o que ajuda na customização, conforme Sommerville 
(2011). No método ágil, as equipes são pequenas, com alto nível técnico, feedbacks 
constantes, as reuniões são rápidas — duram geralmente 15 minutos — e muitas 
vezes são feitas em pé, e cada reunião gera um plano de ação, em outras palavras, 
um conjunto de atividades a serem realizadas em um intervalo de tempo 
determinado. A maioria dos métodos ágeis foi criada na década de 1990, e eles 
serão explicados mais adiante (Andrade, 2020). 
 
8.2 FERRAMENTAS ELETRÔNICAS DE MÉTODOS ÁGEIS 
Que tal falarmos sobre ferramentas de gestão? O primeiro passo para criar 
um painel de metodologia ágil é escolher o seu modelo de gestão, estes modelos 
denominados Scrum, Kanban, entre outros, serão explicados posteriormente, mas 
precisamos mencionar que as empresas estão usando preferencialmente dois sites: 
Trello e Jira (Andrade, 2020). 
O Trello é uma ferramenta de gestão on-line para métodos ágeis que auxilia 
na organização de tarefas e possui três versões. O Quadro 1 compara as três 
versões desta ferramenta. A primeira é o plano básico, que é gratuito e, mesmo 
assim, permite vários usuários, porém não tem todas as ferramentas dos outros 
planos. A segunda versão do Trello, chamada Business Class, é paga e possui, por 
exemplo, relação com o Github. Hoje muitas empresas de tecnologia usam 
programas como o Github a fim de salvar versões de cada alteração do código 
automaticamente no servidor da plataforma. A terceira versão, o plano Enterprise, 
 
 
31 
 
também é paga e possui muitas ferramentas de gerenciamento de acessos a pastas 
e a convites, entre outras funcionalidades administrativas (Andrade, 2020). 
 
 
Fonte: Adaptado de Trello (2020) 
O Jira também é uma ferramenta on-line de gestão ágil muito usada em 
métodos ágeis. Esta ferramenta é mais complexa que o Trello e possui maior 
processamento e velocidade, seu suporte é muito completo, atende 24 horas por 
dia, e foi desenvolvido para projetos de software (Andrade, 2020). 
 
 
32 
 
O Quadro 2 mostra as utilidades do Jira e compara três planos: o básico, 
gratuito, e os demais, Standart e Premium, sendo este último o mais caro (Andrade, 
2020). 
 
 
Fonte: Adaptado de Atlassian (c2020). 
9 VALORES E PRINCÍPIOS ÁGEIS 
De acordo com o site do Manifesto Ágil (BECK et al., c2001), no ano 2001, 
em Utah, nos EUA, 17 profissionais que praticavam metodologias ágeis se reuniram 
para praticar Snowbird e conversar sobre métodos de planejamento de software. 
 
 
33 
 
Criaram, portanto, um documento, chamado de grito de guerra, o Manifesto Ágil, 
que possui quatro valores (contidos na coluna da esquerda na Figura 1). Estes 
valores priorizam os pontos a seguir. 
 
1. Pessoas frente aos processos — Este tópico objetiva favorecer 
relacionamentos no ato da construção do software. 
2. Funcionamento versus documentação — Este tópico objetiva 
favorecer a funcionalidade da criação de software, e não somente o 
design. 
3. Colaboração do cliente, a funcionalidade da criação de software — 
Este tópico objetiva favorecer a interação contínua com o cliente, a 
fim de compreender seus desejos e anseios com mais precisão. 
4. Consertar problemas e se adaptar a mudanças — Este tópico 
objetiva favorecer uma construção dinâmica e não engessada, onde 
consertar problemas é mais importante que manter a burocracia. 
 
 
 
 
34 
 
 
Fonte: Adaptada de Isotani e Rocha (2020). 
Perceba o quanto esses valores são aplicáveis. Não se trata de deixar de 
se organizar ou de documentar, obviamente, mas de tornar o trabalho mais 
funcional e orgânico. Considere que os profissionais da área de programação ficam 
sobrecarregados e que a área de tecnologia é estressante; há muita demanda para 
pouco profissional, e a tendência é aumentar a necessidade de profissionais 
(Andrade, 2020). 
Uma situação que pode acontecer durante o desenvolvimento de um 
software, por exemplo, é, apesar de haver um plano de ação, as pessoas 
perceberem, em meio ao processo, a necessidade de alterações ou de inclusão de 
novas funcionalidades. Outro exemplo seria, na criação de um app, constatar que 
os dados precisam ficar em uma tabela temporária, e então ter que parar tudo e 
criar um banco de dados temporário no painel do servidor (Andrade, 2020). 
 
 
35 
 
Agora, imagine que você tem que ficar documentando os detalhes de tudo 
que fizer. Os programadores ficariam mais sobrecarregados ainda, pois além de 
programar eles teriam que documentar. Neste ponto, ferramentas como o Github 
ajudam, pois salvam automaticamenteas versões (Andrade, 2020). 
Imagine agora que você não permite que seus funcionários mudem um 
pouco o curso? Isso acabaria atrapalhando um atributo muito importante: 
funcionalidade! Por isso devemos seguir, sim, as boas práticas, sem, contudo, 
negligenciar o tempo de execução, pois cada minuto poderia ser um recurso a mais 
no seu software (Andrade, 2020). 
Falamos dos quatro valores do Manifesto Ágil. Vejamos agora seus 12 
princípios desenvolvimento de software? Eles estão presentes do próprio site oficial 
do Manifesto Ágil (BECK et al., 2001). 
 
• Nossa prioridade é satisfazer o cliente através da entrega contínua e 
adiantada de software com valor agregado. 
• Aceitar mudanças de requisitos, mesmo no fim do desenvolvimento. 
Processos ágeis se adequam a mudanças, para que o cliente possa 
tirar vantagens competitivas. 
• Entregar frequentemente software funcionando, de poucas semanas 
a poucos meses, com preferência à menor escala de tempo. 
Indivíduos e interação entre eles mais que processos e ferramentas. 
• Pessoas de negócio e desenvolvedores devem trabalhar diariamente 
em conjunto por todo o projeto. 
• Construir projetos em torno de indivíduos motivados, dando a eles o 
ambiente e o suporte necessário e confiando neles para fazer o 
trabalho. 
• O método mais eficiente e eficaz de transmitir informações para e 
entre uma equipe de desenvolvimento é por meio de conversa face 
a face. 
 
 
36 
 
• Software funcionando é a medida primária de progresso. 
• Os processos ágeis promovem desenvolvimento sustentável. Os 
patrocinadores, desenvolvedores e usuários devem ser capazes de 
manter um ritmo constante indefinidamente. 
• Contínua atenção à excelência técnica e bom design aumentam a 
agilidade. 
• Simplicidade: arte de maximizar a quantidade de trabalho não 
realizado é essencial. 
• As melhores arquiteturas, requisitos e designs emergem de times 
auto-organizáveis. 
• Em intervalos regulares, a equipe reflete sobre como se tornar mais 
eficaz, e então refina e ajusta seu comportamento de acordo. 
 
Como você pode perceber, é um método poderoso, para quem já atua com 
programação ele faz muito sentido. O sistema tradicional se mostra lento: nele, os 
clientes chamam a empresa de criação de software, e para fazer a elicitação são 
necessárias longas visitas técnicas, análises de documentos, entrevistas e análises 
de processos, para então dar uma data relativamente demorada com um valor 
relativamente alto para entregar a aplicação. Resultado? Alto custo e lentidão. No 
sistema ágil o processo é mais fatiado e incrementado. Falaremos agora sobre 
algumas metodologias famosas (Andrade, 2020). 
 
10 PRINCIPAIS MÉTODOS ÁGEIS EXISTENTES 
Primeiramente, listaremos os métodos ágeis famosos. O primeiro citado é 
o Scrum (será explicado adiante), no Trello. Na década de 1990 vários modelos 
influenciaram na criação de métodos ágeis. Podemos citar como exemplo os 
 
 
37 
 
seguintes modelos: Desenvolvimento Incremental, DSDM (Metodologia de 
Desenvolvimento de Sistemas Dinâmicos), Crystal Clear, FDD (Desenvolvimento 
Direcionado a Funcionalidade), XP (Extrem Programming) e Scrum. (Andrade, 
2020). 
O Quadro abaixo mostra a recomendação de métodos por fases do projeto 
de desenvolvimento de software. 
 
 
Fonte: Adaptado de Alegría et al. (2011) 
O primeiro, desenvolvimento incremental, criado pela IBM em 1990, faz a 
construção do sistema de pedaço em pedaço, ou de incremento em incremento. 
Geralmente, um pedaço é feito, e após o cliente dá alguns feedbacks. Cada pedaço 
é uma parte inteira: por exemplo, uma página de login link com acesso a banco de 
dados é um incremento (SOMMERVILLE, 2011). 
O segundo método cabível de explicação é a Metodologia de 
Desenvolvimento de Sistemas Dinâmicos, o qual é usado em situações onde o 
tempo e a verba são limitados. De acordo com Cruz (2018, p. 316) “[...] tem um 
 
 
38 
 
conceito mais próximo a um framework do que um método propriamente dito, sua 
ênfase foca a criação de protótipos que posteriormente evoluem para o sistema, e 
para isso é utilizada muito fortemente a colaboração próxima com o cliente”. 
Este método buscar entregar 80% do projeto em 20% do tempo disponível. 
Ele é composto por três fases: a fase do pré-projeto (onde se elabora o orçamento), 
a fase do ciclo de vida (onde se analisa a viabilidade) e a fase do pós-projeto (onde 
ocorrem as alterações), conforme a Figura abaixo: 
 
 
Fonte: Adaptado de Alegría et al. (2011) 
A Metodologia de Desenvolvimento de Sistemas Dinâmicos é recomendada 
quando os projetos são urgentes, quando os projetos são formados por uma nova 
tecnologia e precisam ser acompanhados de testes do usuário, ou quando remetem 
a um lançamento de produto com data marcada. Qual é a diferença entre este 
método e outros? Em metodologias tradicionais, como por exemplo, o famoso 
Project Management Institute (PMI), o cronograma e o orçamento são abertos, e o 
escopo é fechado; já a Metodologia de Desenvolvimento de Sistemas Dinâmicos 
 
 
39 
 
tem cronograma e orçamento fechados, mas o roteiro é aberto (SOMMERVILE, 
2011). 
O Crystal Clear (ISOTANI; ROCHA, [20––]) é outra metodologia ágil. Ela 
atende vários tipos de projetos e tem como valor a comunicação com o cliente, bem 
como o relacionamento do desenvolvedor com o cliente, a fim de que possa captar 
com facilidade suas expectativas. Este método evita a criação de ferramentas 
complexas que não serão utilizadas, objetivando reduzir tempo e custo na entrega. 
Este método busca diferenciar a metodologia específica conforme a natureza de 
cada projeto e permite que os desenvolvedores se manifestem quando algo os 
incomodar. O método Crystal é um cristal em figura elaborado pela gestão e 
mostrado com uma escala de cores, onde as cores variam de acordo com nível de 
criticidade e com o tamanho da equipe: quanto mais escuro o cristal, mais crítico de 
fazer é o software ou projeto; já as cores claras (branco e amarelo) atestam que os 
software ou projetos serão simples e poucas pessoas serão necessárias; projetos 
alaranjados ou até vermelhos demandam mais pessoas e são mais arriscados. No 
Crystal da Figura 3, desenhado pela gestão, C significa confortável e D significa 
baixo custo, E significa alto custo, e L significa risco de vida. O números indicam o 
número de funcionários. 
 
 
 
 
40 
 
 
Fonte: Adaptada de Abrahamsson et al. (2002) 
A metodologia Feature-driven development (FDD), ou “Desenvolvimento 
Dirigido por Funcionalidades”, em português, fragmenta os projetos de gestão e de 
software em features (funcionalidades). Ela foi concebida na década de 1990, e tem 
como características os pontos, de acordo com Sommerville (2011): 
 
• elaboração de lista de tarefas de funcionalidades, ou seja, cada 
passo tem foco em alguma funcionalidade do software; 
• planejamento voltado ao método incremental por funcionalidade, ou 
seja, planeja-se etapas de acordo cada parte. Por exemplo: o 
primeiro item a ser feito é a área do cliente completa; o segundo item 
 
 
41 
 
será o carrinho de compras completo; o terceiro item será o catálogo 
completo, e assim por diante; 
• design voltado à funcionalidade, ou seja, criar um design que 
simplifica a navegação e promove a experiência do usuário; 
• teste de software orientado à funcionalidade, ou seja, testar cada 
função em detrimento de testar uma interface, por exemplo. 
 
Pode-se perceber que neste projeto a soma de cada etapa se faz maior do 
que o todo; assim, recomenda-se dividir em features curtas, a fim de agilizar a 
conclusão de cada função, aumentando a eficiência da construção do programa. 
Por exemplo: cria-se uma função de upload de imagens, cria-se uma função de 
adicionar produto, e assim sucessivamente. 
De acordo com Sommervile (2011), o quarto método a ser citado é o XP, 
mais conhecido como Extremming Programing. Criado em 1996, possui comoprincípios básicos: trabalho de qualidade, mudanças incrementais, feedback rápido 
e abraçar mudanças. A metodologia possui algumas práticas: 
 
• Jogos de planejamento: no início da semana os clientes e developers 
(desenvolvedores) se reúnem parar priorizar funcionalidades que 
serão entregues no final da semana. Cada versão deve ser pequena. 
• Propriedade coletiva: qualquer pessoa do time pode usar o código 
do programa sem precisar de permissão para alterar, assim todos 
têm a oportunidade de conhecer o código inteiro e se familiarizar com 
ele. Isso é muito importante para agilizar manutenções. 
• Teste de usuário: em equipes pequenas são realizados testes do 
software por clientes e desenvolvedores da empresa para avaliar sua 
qualidade. 
• Ritmo sustentável: as equipes devem trabalhar 40 horas, divididas 
em 8 horas por dia, sem sobrecarga. 
 
 
42 
 
• Equipe inteira: as reuniões devem ser em pé e devem ser rápidas. 
• Programação em par: um desenvolvedor mais experiente fica com 
um novato, o novato codifica e o mais experiente programa. O 
benefício deste método é que ele é revisado por duas pessoas. 
• Padronizações de código: a equipe de dev (developers) determina 
regras de codificação de salvamento, bem como as boas práticas 
que devem ser seguidas. Assim, parecerá que foi a mesma pessoa 
que editou o código, ele ficará com uma “cara” única. 
• Desenvolvimento orientado a teste: elaborar códigos de forma que 
sejam capazes de ser testados por software de teste como Imeter 
(um software que mede desempenho), Selenium (um software que 
mede erros de sites), etc. 
• Refatoração: é o processo de otimizar a estrutura do código sem 
alterar o seu comportamento externo para o usuário final. 
• Integração contínua: integrar alterações de forma contínua, sem 
esperar uma semana, por exemplo. Permite saber a real situação do 
software da programação 
• Entregas curtas: entregar pequenos pedaços para o cliente corrigir e 
avaliar, aumentando a probabilidade de acertar o todo. 
• Metáfora: entender a linguagem e as expressões do cliente. 
• Design simples: o código deve ter exatamente o que o cliente pediu. 
 
A quinta metodologia a ser citada é a Scrum. Ela também é citada por 
Sommervile (2011). Não citaremos todas que existem, obviamente. Vamos abordar 
alguns pontos sobre o Scrum (Andrade, 2020). 
 
• Três pessoas principais devem ser citadas: 
 
 
 
43 
 
• o Product Owner, que define o que comporá o Product Backlog (lista 
de ações do Sprint) e prioriza isso nas Sprint Planning Meetings 
(reuniões de planejamento do Sprint); 
• o Scrum Master (geralmente um gerente ou líder técnico), que 
verifica se todos seguem as regras e também busca impedir 
trabalhos excessivos; 
• o Scrum Team é a equipe de desenvolvimento 
 
No Scrum os projetos são divididos em etapas geralmente mensais. Pode-
se dizer que são ciclos mensais. Essas etapas chamam-se Sprints. Cada Sprint é 
um Time Box, uma caixa no tempo com um conjunto de metas. 
No Scrum existem reuniões diárias, chamadas Daily Scrum. Elas são feitas 
no início do expediente e revisam os itens do dia anterior e determinam o que será 
feito no dia. 
As funcionalidades são agrupadas em uma lista. Product Backlog é esta 
lista; ela contém todas as funcionalidades necessárias para um produto, e é feita 
pelo Product Owner. 
O Sprint Planning Meeting é uma reunião feita no início de cada Sprint. 
Nesta reunião estarão presentes o Product Owner, o Scrum Master, o Scrum Team 
e interessados. Nesta reunião o Product Owner determina as prioridades, e todos 
juntos definirão um objetivo para aquele Sprint. 
Este objetivo Sprint será revisado na Sprint Review Meeting, uma reunião 
com o Product Owner, o Scrum Team, o Scrum Master, e algumas vezes com 
gerência e clientes, a fim de revisar o que foi atingido e o que não foi. 
O Release Burndown Chart é uma análise de metas atingidas no final de 
cada Sprint (iteração). 
 
 
 
 
 
44 
 
11 TEST-DRIVEN DEVELOPMENT 
Dentre as etapas genéricas presentes nos métodos de desenvolvimento de 
software trabalhados pela literatura, a etapa de testes sempre esteve presente. 
Após a popularização dos métodos ágeis, uma forma de desenvolver com foco nos 
testes emergiu: o test-driven development (TDD). Nesse método, o teste deixa de 
ser etapa e passa a ser o elemento protagonista, guiando o desenvolvimento do 
início ao fim do projeto e invertendo a lógica de programar e depois testar, pois o 
teste passa a ser a primeira ação nas iterações (Ladeira, 2020). 
Neste capítulo, você estudará sobre o TDD, um método de desenvolvimento 
dirigido por testes, conhecendo seus conceitos e sua história. Você estará apto a 
entender o processo de desenvolvimento de software com o TDD, bem como a 
identificar os seus benefícios e as suas limitações (Ladeira, 2020). 
 
11.1 SURGIMENTO DE UM MÉTODO DE DESENVOLVIMENTO DIRIGIDO POR 
TESTES 
O TDD, também chamado de “desenvolvimento guiado por testes”, é um 
método ágil de desenvolvimento que concentra os esforços de desenvolvimento na 
capacidade de projetar testes e elaborar até que o componente esteja 
completamente codificado e todos os testes executem sem erro (PRESSMAN; 
MAXIM, 2016). Nesta seção, você aprenderá um pouco sobre a história deste 
método, e compreenderá os conceitos centrais por ele utilizados (Ladeira, 2020). 
 
 
 
45 
 
11.2 HISTÓRICO 
No ano de 2001, um grupo de desenvolvedores propôs mudanças nos 
elementos essencialmente valorizados nos processos de desenvolvimento 
tradicionais, o que culminou na elaboração do Manifesto para Desenvolvimento Ágil 
de Software (BECK et al., 2001). Esse manifesto motivou a criação de diversos 
métodos ditos ágeis, entre os quais estão Scrum, XP e outros. Um dos idealizadores 
do manifesto foi Kent Beck, um engenheiro de software estadunidense que já 
trabalhava em uma iniciativa de método ágil chamada extreme programming 
(conhecido pela sigla XP ou também por “programação extrema”, em tradução livre), 
que veio a se popularizar (Ladeira, 2020). 
O método XP sempre conteve o teste entre as suas práticas. No contexto 
do XP, a prática estava descrita como test-first (teste antes). Com o passar do 
tempo, Beck percebeu que tal prática poderia ser desmembrada do XP e utilizada 
de forma isolada, configurando-se em um novo método de desenvolvimento. De 
acordo com Prikladnicki, Willi e Milani (2014), Beck publicou um artigo em 2001 
relatando a prática como sendo uma técnica de design, e não propriamente de 
testes, e, em 2003, publicou um livro sobre esta técnica, passando a chamá-la de 
test-driven development (Ladeira, 2020). 
O interessante é que Beck não se considera o criador do TDD, mas sim o 
seu redescobridor, pois alega que essa prática é muito antiga. Mas será que é 
mesmo? Conforme Larman e Basili (2003), sim: a IBM, na década de 60, executou 
um projeto para a NASA chamado Mercury. Neste projeto, foi utilizada a prática de 
teste-antes para cada pequeno incremento desenvolvido (Ladeira, 2020). 
O registro mais antigo, entretanto, é de McCracken (1957), que relata a 
necessidade de se trabalhar com ciclos curtos iterativos e de se elaborar o que 
chamava de casos de verificação antes do código a fim de evitar erros lógicos e 
mal-entendidos. Assim, o primeiro a mencionar as práticas do TDD é Daniel 
 
 
46 
 
McCracken, mas Beck é o responsável por redescobrir a técnica e sistematizá-la, 
além de ser um dos grandes responsáveis pela sua popularização (Ladeira, 2020). 
 
11.3 CONCEITOS DO TEST-DRIVEN DEVELOPMENT 
De acordo com Beck (2011 apud PRIKLADNICKI; WILLI; MILANI, 2014, p. 
201), “desenvolvimento dirigido por testes é um conjunto de técnicas [...] que 
encorajam design simples e suítes de teste que inspiram confiança”. Segundo 
Pressman e Maxim (2016, p. 854), “[...] o TDD não é realmente uma nova tecnologia, 
mas sim uma tendência que enfatiza o projeto de casos de testeantes da criação 
do código-fonte”. Neste modelo o elemento central é o teste, um conjunto de ações 
relacionadas a um diagnóstico. Um teste sempre pode passar, o que significa que 
o resultado retornado é o resultado esperado, ou falhar, o que significa diferença 
entre esses resultados (Ladeira, 2020). 
O tipo de teste que é realizado em todas as unidades de código criadas é o 
teste unitário. Neste teste todas as pequenas porções de códigos criadas são 
testadas por meio da citada comparação entre o valor esperado e o valor retornado. 
A menor unidade testável pode variar de paradigma para paradigma, podendo ser 
um arquivo, uma classe, um método, uma função etc (Ladeira, 2020). 
O modelo de desenvolvimento dirigido por testes realmente tem design 
simples. Ele é modelado em três estados: vermelho, verde e refatorar. A Figura 1 
resume o modelo visualmente. Nela podemos ver três círculos, cada um 
representando um dos estados do TDD (Ladeira, 2020). 
 
 
 
47 
 
 
Fonte: Ladeira (2020) 
 
A ação inicial no TDD, antes mesmo de iniciar a implementação do 
componente, é a elaboração do teste automatizado. Este teste inevitavelmente 
falhará, pois ainda não há código. O conceito de falha está atrelado ao estado 
vermelho, o primeiro estado possível definido pelo método. O conceito de sucesso 
é modelado pelo estado verde, obtido a partir do momento em que o desenvolvedor 
ou a equipe de desenvolvimento implementa um código que passa pelo teste. Já o 
 
 
48 
 
conceito de refatoração é modelado pelo terceiro e último estado: refatorar. Mas o 
que é refatoração ? (Ladeira, 2020). 
A refatoração é um conjunto de ações de aprimoramento da estrutura 
interna do componente. Estas ações envolvem (Ladeira, 2020). 
 
• eliminação de redundâncias no código; 
• renomeação dos identificadores dos elementos internos, atendendo 
aos padrões exigidos pela equipe; 
• uso de estruturas de dados mais eficientes; 
• uso de soluções mais eficientes; 
• uso de bibliotecas mais adequadas; 
• melhoria no gerenciamento de recursos. 
 
Após a refatoração, o ciclo é reiniciado com um teste automatizado que 
falha. 
Existe ainda outro conceito importante relativo aos testes: como garantir que 
uma alteração em um código novo não interferiu negativamente em uma unidade já 
criada — e testada — anteriormente? É equivocado pensar que uma unidade já 
testada não pode apresentar erros em função de outra criada depois, já que é 
normal existir interdependência entre os componentes criados. A técnica de testes 
de regressão, no entanto, é a proposta de solução nestes casos. Como os testes 
são automatizados e escritos antes dos códigos, tem-se o histórico de todos os 
testes realizados anteriormente; assim, para garantir que novas unidades não 
tenham inserido erros em unidades já criadas, basta realizar os testes 
automatizados novamente (Ladeira, 2020). 
A ação de elaborar testes automatizados faz com que a equipe ganhe 
tempo. Afinal, é mais rápido realizar testes de forma automática do que exigir a ação 
humana para interagir com o componente, além de possibilitar que um conjunto 
grande de dados seja testado. Essa ação contribui para a confiabilidade do 
 
 
49 
 
componente, pois passar por um conjunto volumoso de testes automatizados 
minimiza as chances de problemas futuros. Prikladnicki, Willi e Milani (2014) 
complementam afirmando que o teste automatizado é composto por etapas de 
preparação, exercício e verificação, e definem como fundamental que o teste seja 
autocontido, isto é, não dependa de intervenção humana para decidir o resultado 
Como o TDD preconiza a realização de testes que sejam automáticos, por 
vezes é necessário simular comportamentos de outros componentes que interagem 
com a unidade testada mas não estão disponíveis neste formato ou não são viáveis 
de se utilizar por questões de, por exemplo, desempenho ou complexidade. Alguns 
componentes nessas situações estão relacionados à elaboração de interfaces cujo 
comportamento depende da forma de ação do usuário, de acesso a arquivos 
externos, a sistemas de gerenciamento de banco de dados ou até mesmo à 
transmissão de dados em uma rede de computadores. Nestes casos, para viabilizar 
os testes, foi proposto o conceito de mocks. Os mocks, também chamados de fake 
mocks, mock objects ou objetos de simulação, representam simulações dos 
componentes necessários. Esses objetos tentam reproduzir os objetos reais que 
por algum motivo não podem ser utilizados nos testes (Ladeira, 2020). 
Entre os motivos válidos para o uso de mocks estão, por exemplo, a 
indisponibilidade do componente, seja por complexidade ou por ainda não estar 
desenvolvido, ou até mesmo o desempenho do componente real, tal como um 
sistema de gerenciamento de banco de dados cujas consultas sejam demoradas. 
Assim, o uso de um objeto de simulação pode ser vantajoso por poupar tempo da 
equipe de desenvolvimento e abstrair detalhes do componente (Ladeira, 2020). 
A equipe de desenvolvimento pode elaborar seus próprios mocks ou utilizar 
frameworks de suporte a mocks disponíveis para as principais linguagens de 
programação do mercado (Ladeira, 2020). 
 
 
 
50 
 
11.4 O TEST-DRIVEN DEVELOPMENT NO CICLO DE VIDA DO SOFTWARE 
Nesta seção analisaremos o TDD no ciclo de desenvolvimento de software 
do ponto de vista de sua aplicabilidade. Discutiremos também a geração de 
documentação para este método (Ladeira, 2020). 
Pensemos agora na aplicabilidade do TDD por meio de um exemplo: uma 
função que recebe um número natural (inteiro positivo) n entre 0 e 50 (inclusive) e 
deve retornar o n-ésimo termo da Série de Fibonacci (Ladeira, 2020). 
A Série de Fibonacci é uma sequência numérica na qual o primeiro valor é 
o 0, o segundo é 1, e do terceiro valor em diante o elemento é sempre igual à soma 
dos dois elementos anteriores. Os 10 primeiros elementos desta série são: 0, 1, 1, 
2, 3, 5, 8, 13, 21 e 34. Você consegue identificar os elementos seguintes? (Ladeira, 
2020). 
O n-ésimo termo da Série de Fibonacci também é um número natural e, 
portanto, a função recebe um número natural como parâmetro e retorna outro 
número natural. Em uma pseudolinguagem de programação, a assinatura da função 
seria como segue: 
 
inteiro termoFibonacci(inteiro n) 
 
Em um teste realizado com o parâmetro n = 7, qualquer resultado 
retornado diferente de 8 resultará em um teste que falha, já que o valor esperado 
para o sétimo termo de Fibonacci é 8. Se, por algum motivo, um teste com n = 7 
resultar em valor diferente de 8 e o teste não falhar, o problema estará no caso de 
teste projetado. Como o nosso método termoFibonacci seria testado utilizando a 
abordagem do TDD? Inicialmente, precisaríamos escrever um teste, utilizando 
nossa pseudolinguagem de programação (Ladeira, 2020). 
 
 
 
 
51 
 
 
 
testaTermoFibonacci() { 
inteiro n = 10 
inteiro resposta 
inteiro respostaEsperada = 34 
 resposta = termoFibonacci(n) 
escreva verificaIgualdade(respostaEsperada, resposta) 
 } 
 
 
O teste demonstrado no exemplo é o teste unitário, sendo aplicado a uma 
pequena porção testável (neste caso, o método termoFibonacci). O teste verifica 
através do método verificaIgualdade se o valor retornado pelo método 
termoFibonacci é igual ao valor da variável respostaEsperada (34, neste caso). 
Por estarmos utilizando uma pseudolinguagem, considere que verificaIgualdade é 
um método predefinido para comparação de valores. Os frameworks de testes 
unitários costumam implementar este método com um nome semelhante a 
assertEqual, mas há várias abordagens possíveis para escrever um teste unitário 
(Ladeira, 2020). 
As ferramentas de testes unitários criam seus métodos comparativos, mas 
você pode elaborar testes sem depender destas ferramentas. Podemos elaborar 
uma resposta diferente para o nosso exemplo da seguinte maneira: 
lógico testaTermoFibonacci() { inteiro n = 10 inteirorespostaEsperada = 34 
retorna (respostaEsperada == termoFibonacci(n)) } Neste exemplo, o retorno de 
testaTermoFibonacci é um valor lógico (verdadeiro ou falso) que deve ser 
manipulado ou apresentado no trecho de código que invoca o método. Este retorno 
faz justamente a comparação de igualdade entre a resposta esperada e a resposta 
 
 
52 
 
calculada, retornando este valor. Note que aqui não foi utilizada a variável resposta, 
mas o resultado é igualmente válido (Ladeira, 2020). 
Como não há implementação de termoFibonacci, o teste falha, pois é 
necessário implementar o método. Suponha agora que o desenvolvedor, utilizando 
recursividade (chamadas sucessivas da função a ela própria), implementou o 
método termoFibonacci na nossa pseudolinguagem de programação: 
 
inteiro termoFibonacci(inteiro n) { 
 se (n == 1) { 
 retorna 0 
 } 
 
 se (n == 2) { 
 retorna 1 
 } 
 
 retorna termoFibonacci(n-1) + 
 termoFibonacci (n-2) 
} 
 
Agora, ao executar o nosso teste, o estado atingido é o verde, pois temos 
um código implementado que funciona para o nosso teste. Note que, se a entrada 
for 1, ou seja, deseja-se o primeiro termo, a saída será zero, pois o primeiro valor 
da série é zero. Se a entrada for dois, a saída será um, pois um é o segundo valor 
da série. Se a entrada for três, cai-se no caso da recursão, chamando 
termoFibonacci(3-1) e termoFibonacci(3-2), ou seja, chama-se recursivamente 
novamente a função duas vezes, uma com o valor 2, outra com o valor 1, e soma-
se o resultado de ambas. Neste caso, 0 + 1 = 1, ou seja, o terceiro termo é também 
o valor 1. Cabe citar que, em uma situação real, um conjunto de dados de teste mais 
 
 
53 
 
volumoso seria utilizado e testado de forma automatizada, não apenas um teste 
com a entrada 10 (Ladeira, 2020). 
O próximo estado previsto no TDD é refatorar. Para atingir esse estado é 
necessário verificar a possibilidade de realizar melhorias internas no método 
termoFibonacci. Isso é possível? 
Entre várias ações possíveis, eliminar redundâncias e padronizar o código, 
caso a empresa de desenvolvimento utilize algum padrão, são algumas das ações 
necessárias. Não havendo a necessidade de realizar estas ações, precisamos 
pensar na sequência de instruções do método. O primeiro teste realizado é sempre 
a verificação se o número é um. No entanto, o comando de retorno deste teste só 
será executado quando o valor de n for um. Para todos os outros números aceitos 
na entrada, um dos testes de parada será n == 2. Por exemplo, ao chamar 
termoFibonacci(2), o teste n == 1 resultará falso, mas o teste n == 2 resultará 
verdadeiro. Assim, a simples inversão de ordem destas estruturas condicionais já 
configura uma comparação a menos, representando uma pequena melhoria no 
código: 
 
inteiro termoFibonacci(inteiro n) { 
 se (n == 2) { 
 retorna 1 
 
 } 
 
 se (n == 1) { 
 retorna 0 } 
 } 
 
 retorna termoFibonacci(n-1) + 
termoFibonacci(n-2) 
 
 
54 
 
 } 
(Ladeira, 2020). 
 
Ainda assim, as diversas chamadas recursivas continuam sendo bastante 
custosas, pois a função chama a si própria diversas vezes. Há ainda a possibilidade 
de juntar os dois testes, economizando linhas de código: 
 
inteiro termoFibonacci(inteiro n) { 
 se (n == 2 ou n == 1) { 
 retorna n-1 
 } 
 
 retorna termoFibonacci(n-1) + 
 termoFibonacci(n-2) 
} 
 
O código ficou pequeno, elegante e não conta com redundâncias, mas 
ainda está custoso em termos de tempo e espaço (memória utilizada). Soluções 
recursivas costumam utilizar muita memória e, conforme entradas grandes são 
utilizadas (ou seja, os maiores valores válidos para n), o tempo de processamento 
passa a ser maior. Em uma situação como essa, é necessário pensar em melhores 
soluções para o consumo desses recursos. Neste caso a solução iterativa, embora 
gere mais código, é a mais eficiente, pois acessa menos vezes a memória e utiliza 
apenas a alocação de um vetor no início do código (Ladeira, 2020). 
 
inteiro termoFibonacci(inteiro n) { 
 n = n – 1 
 
 se (n == 0 ou n == 1) { 
 
 
55 
 
 retorna n 
} 
 inteiro acumulador[50] 
 acumulador [0] = 0 
 acumulador [1] = 1 
 inteiro índice 
 
 para (indice = 2; indice <= n; indice++) faça { 
 acumulador[indice] = acumulador[indice-1] 
 + acumulador[indice-2] 
 } 
 
 return acum[n]; 
 } 
 } 
 
 
Agora, tem-se uma função de cálculo do n-ésimo termo de Fibonacci de 
forma iterativa. Esta implementação utiliza um vetor de 50 posições, pois este será 
o valor máximo para n. O índice do vetor de 50 posições inicia em zero, então, para 
um vetor de n posições, o vetor deverá variar de 0 a n-1, por isso a primeira instrução 
decrementa 1 unidade do valor de n. Com este vetor o espaço de memória 
determinado para resolver a função já está alocado, diferentemente da solução 
recursiva, que gera diversas chamadas à função de forma dinâmica. A função 
recursiva, se implementada em uma linguagem de programação, pode ocasionar 
erros de execução em função das diversas chamadas recursivas, necessitando de 
mais espaço de memória do que o disponível, situação altamente indesejada e que 
deve ser evitada no estado de refatoração previsto no TDD (Ladeira, 2020). 
 
 
56 
 
Podemos supor, ainda, que a empresa exige que existam comentários 
dentro da função, facilitando assim o entendimento de quem precisar manter o 
código. Esta ação também deve ser realizada na etapa de refatoração. Assim, o 
código comentado fica como segue (Ladeira, 2020). 
 
/* Função que recebe um valor n inteiro positivo e 
retorna um valor inteiro positivo que representa o 
n-ésimo termo da Série de Fibonacci */ 
inteiro termoFibonacci(inteiro n) { 
 /* Decrementa n em uma unidade para 
trabalhar com as posições corretas do vetor, 
de 0 até n-1, resultando em n posições */ 
 n = n – 1 
 /* Como os dois primeiros valores são 
conhecidos, retorna-se 0, se n for igual a zero, e 
1, se n for igual a 1 */ 
 se (n == 0 ou n == 1) { 
 retorna n 
 } 
 
 /* Declaração do vetor de tamanho 50, a maior 
entrada possível neste caso */ 
 inteiro acumulador[50] 
 
 /* Atribui às duas primeiras posições do 
vetor os dois valores iniciais da Série de 
Fibonacci. O primeiro elemento recebe o valor zero 
e o segundo elemento recebe o valor um */ 
 acumulador [0] = 0 
 
 
57 
 
 acumulador [0] = 0 
 
 /* Declara o indice para percorrer o vetor */ 
 inteiro índice 
 
 /* Percorre o vetor a partir da posição 2 
(a terceira posição), preenchendo todos os valores 
com a soma dos dois anteriores, conforme manda a 
definição da Série de Fibonacci */ 
 para (indice = 2; indice <= n; indice++) faça 
{ 
 acumulador[indice] = 
 acumulador[indice-1] + acumulador[indice-2] 
} 
 /* Retorna o último valor do vetor, que será 
o n-ésimo termo da Série de Fibonacci */ 
 return acum[n]; 
} 
 
Notou a diferença? O código, agora iterativo, está mais eficiente em 
consumo de recursos e dentro do padrão (hipotético) de comentário da empresa 
(Ladeira, 2020). 
Após concluída a etapa de refatoração, o componente é entregue ou 
incrementado com base em novos testes, que inicialmente falham, e assim inicia-
se o ciclo novamente. No nosso exemplo poderia haver a necessidade de mais um 
incremento na unidade, exigindo também a implementação do método 
fibonacciAteN, para imprimir todos os números daSérie de Fibonacci até o n-ésimo 
termo, passado como parâmetro (Ladeira, 2020). 
 
 
58 
 
Um aspecto importante que podemos discutir é a ausência de qualquer 
diretriz sobre os requisitos. Assume-se que o desenvolvedor compreendeu 
corretamente os requisitos necessários para desenvolver a funcionalidade. Isto se 
materializará diretamente nos códigos dos casos de teste. No entanto, nada o 
impede de, antes, modelar os requisitos com outra técnica, tal como a criação de 
histórias de usuário ou casos de uso (Ladeira, 2020). 
Vimos o exemplo da função termoFibonacci em um pseudocódigo 
estruturado válido. Agora vejamos como isso seria feito em uma linguagem de 
programação, em uma situação prática real. Tomemos como exemplo a linguagem 
C++, utilizando-a também de forma estruturada para facilitar o seu entendimento, 
juntamente com o compilador g++. O código de teste seria como segue (Ladeira, 
2020). 
 
#include <iostream> 
#include "fi bo.h" 
 
using namespace std; 
int main() { 
 long long int respostaEsperada = 34; 
 long long int n; 
 long long int resposta; 
 
 n = 10; 
 resposta = termoFibonacci(n); 
 if (resposta == respostaEsperada) 
 cout << "Passou no teste!" << endl; 
 
 else 
 cout << "Falhou no teste!" << endl; 
 
 
59 
 
 cout << "Entrada informada: " << resposta << 
 endl; 
 cout << "Resposta informada: " << resposta << 
 endl; 
 cout << "Resposta esperada: " << respostaEsperada << endl; 
 return 0; 
 } 
 
Nosso código de teste resolve o mesmo problema que o código que 
construímos na pseudolinguagem, mas note que ele tem algumas diferenças. Ele 
verifica a resposta obtida e a resposta informada. Se forem iguais, informa que 
passou no teste; se forem diferentes, informa que o teste falhou. Depois disso, a 
entrada e as respostas informada e esperada são impressas na tela. Esta é uma 
boa prática, pois assim o arquivo de saída registra mais informações do teste, não 
somente “verdadeiro” ou “falso”. Outra diferença é o uso do tipo long long int, para 
valores grandes. Por uma limitação de arquitetura, o tipo inteiro (int, em C++) não 
seria capaz de receber valores grandes, como ocorre, por exemplo, quando n é 50 
(Ladeira, 2020). 
Agora, para poder sair do estado vermelho, nosso código precisa funcionar. 
Para poder desenvolvê-lo, já incluímos o arquivo fibo.h, portanto devemos criar este 
arquivo e acrescentar a assinatura da função desenvolvida nele (Ladeira, 2020). 
 
 
 
long long int termoFibonacci(long long int n); 
 
 Agora, criamos o nosso código recursivo para passar no teste, no arquivo 
 
fibo.cpp: 
 
 
60 
 
long long int termoFibonacci(long long int n) { 
 if (n == 2 || n == 1) 
 return n - 1; 
 
 return termoFibonacci(n-1) + 
termoFibonacci(n-2); 
} 
 
Para executar e compilar o código, você pode utilizar o comando abaixo: 
 
g++ testaTermosFibonacci.cpp fibo.cpp -o fibo; ./fibo 
 
 
A resposta obtida deve ser: 
 
Passou no teste! 
Entrada informada: 34 
Resposta informada: 34 
Resposta esperada: 34 
 
Assim, como o código funciona, estamos no estado verde. No entanto, 
como já vimos, você pode tentar trocar o valor e executar para n = 50 para ver o 
tempo e a memória sendo consumidos. Para isso, devemos refatorar o código 
conforme realizamos no pseudocódigo. O nosso arquivo fibo.cpp deve ser refeito, 
tal como o código abaixo (Ladeira, 2020). 
 
/* Função que recebe um valor n inteiro positivo e 
retorna um valor inteiro positivo que representa o 
n-ésimo termo da Série de Fibonacci */ 
 
 
61 
 
long long int termoFibonacci(long long int n) { 
 /* Decrementa n em uma unidade para trabalhar 
com as posições corretas do vetor, de 0 até n-1, 
resultando em n posições */ 
 n--; 
 
 /* Como os dois primeiros valores são 
conhecidos, retorna-se 0, se n for igual a zero, 
e 1, se n for igual a 1 */ 
 if (n == 0 || n == 1) 
 return n; 
 
 /* Declaração do vetor de tamanho 50, a maior 
entrada possível neste caso */ 
 long long int acumulador[50]; 
 
 /* Atribui às duas primeiras posições do 
vetor os dois valores iniciais da Série de 
Fibonacci. O primeiro elemento recebe o valor zero 
e o segundo elemento recebe o valor um */ 
 acumulador[0] = 0; 
 acumulador[1] = 1; 
 
 /* Declara o indice para percorrer o vetor*/ 
 int indice; 
 
 /* Percorre o vetor a partir da posição 2 
(a terceira posição), preenchendo todos os valores 
com a soma dos dois anteriores, conforme manda a 
 
 
62 
 
definição da Série de Fibonacci */ 
 for(indice = 2; indice <= n; indice++) 
 acumulador[indice] = acumulador 
 [indice-1] + acumulador[indice-2]; 
 
 /* Retorna o último valor do vetor, que será 
o n-ésimo termo da Série de Fibonacci */ 
 return acumulador[n]; 
} 
 
Novamente, ao compilar e executar o código, a resposta obtida deve ser: 
 
Passou no teste! 
Entrada informada: 34 
Resposta informada: 34 
Resposta esperada: 34 
 
Desta forma, conseguimos transcrever para uma linguagem de 
programação o pseudocódigo inicial, realizando testes automáticos e melhorando a 
implementação inicial da função termoFibonacci (Ladeira, 2020). 
 
11.5 DOCUMENTAÇÃO 
Até este ponto da leitura você pode estar se perguntando se (ou quando) o 
TDD prevê a elaboração de documentação. A resposta a esta pergunta é mais 
simples do que parece: a documentação já está elaborada! No TDD a 
documentação é todo conjunto de testes implementados, pois eles mostram a 
definição do comportamento esperado pelos componentes, sua interface e os tipos 
 
 
63 
 
dos dados definidos. Testes unitários, quando bem escritos, podem especificar o 
trabalho do código funcional (Ladeira, 2020). 
Por menor que seja o software desenvolvido, se a prática adotada for o 
TDD, os testes devem permanecer armazenados, até mesmo porque estes testes, 
enquanto documentos, são trabalhados em todos os estados do TDD. Além disso, 
os testes realizados apoiam os futuros testes de regressão. Lembre-se de que um 
software se diferencia de um programa por conter dados de configuração e 
documentação. Portanto, a documentação é parte do software (Ladeira, 2020). 
No caso do código apresentado, os arquivos que implementam o método 
de teste (testaTermoFibonacci) fazem parte da suíte de testes, bem como fariam os 
métodos que testam os métodos de subtração e de outras operações, se for o caso 
do software em desenvolvimento. Se, futuramente, por algum motivo, o método de 
teste precisar de correções ou alterações em virtude de mudanças de requisitos, 
mantém-se o arquivo anterior e cria-se o novo. Todos os arquivos de teste gerados 
formam a suíte de testes e ajudam a compreender o histórico de desenvolvimento 
do software (Ladeira, 2020). 
 
12 VANTAGENS E DESVANTAGENS DO TEST-DRIVEN DEVELOPMENT 
Todo método de desenvolvimento de software tem suas especificidades. 
Alguns podem ser mais vantajosos em determinadas situações, outros podem 
apresentar limitações. O profissional que lidera as decisões da equipe de 
desenvolvimento de software deve estar ciente das características dos métodos, 
pois esta escolha é vital para o andamento do trabalho (Ladeira, 2020). 
 
 
 
64 
 
12.1 VANTAGENS DA UTILIZAÇÃO DO TEST-DRIVEN DEVELOPMENT 
Como você pode analisar na leitura do capítulo, uma das principais 
características do TDD é a simplicidade. Este método apresenta transições de 
estado bem definidas, não ambíguas e em pouca quantidade,

Continue navegando