Você está na página 1de 41

Fundamentos Design Patterns e Além

Conteudista: Prof. Me. Artur Marques


Revisão Textual: Esp. Jéssica Dante

Objetivo da Unidade:

Fundamentar e entender a necessidade de padrões de desenvolvimento de


software no mundo atual.

ʪ Material Teórico

ʪ Material Complementar

ʪ Referências
1 /3

ʪ Material Teórico

Planning Poker
O Planning Poker é uma técnica de estimativa ágil que se tornou muito popular nos últimos anos.
É baseado em uma técnica de estimativa conhecida como Wideband Delphi, que foi criada pela
RAND Corporation na década de 1968.

A técnica foi aprimorada por James Grenning em 2002. Tornou-se muito mais popular quando
foi incluída no livro “Agile Estimating and Planning” de Mike Cohn. Embora os fundamentos da
técnica já existam há muitos anos, os refinamentos de Grenning a tornaram utilizável por
equipes ágeis e eles tiraram o máximo proveito.

Há muita mitologia envolvendo o jogo do planejamento, o primeiro deles é o chamado storypoint.

Trata-se de um número que reflete a complexidade ou a quantidade de trabalho envolvida no


desenvolvimento de uma história de usuário. Por exemplo, uma equipe pode atribuir 1 ponto a
uma história de usuário simples (em nosso projeto pode ser, por exemplo: Fazer Login), 2-3
pontos para uma história moderadamente complexa (por exemplo: Desenvolver o Carrinho de
Compras em nosso projeto) e 4-5 pontos para uma grande história (por exemplo: A
funcionalidade de Logística Reversa em caso de devolução de mercadorias), com base na
compreensão do trabalho envolvido.

Então, quanto tempo uma história de usuário deve levar para se desenvolver, assumindo zero
interrupções.

Além disso, no início de um projeto, há muitos itens pendentes para estimar para que o Planning
Poker seja eficaz.
Nesses casos, a avaliação de massa relativa funciona bem.

Nunca ouviu falar?! Sem problemas.

Usando essa técnica, a equipe SCRUM primeiro organiza as histórias de usuário em ordem de seu
tamanho relativo, do pequeno ao grande nível de esforço e, em seguida, atribui pontos de
história a cada um usando uma sequência de Fibonacci modificada (aqui entra o Planning
Poker).

O resultado é uma lista de pendências inicial totalmente estimada do produto, que permitirá ao
proprietário do produto criar um plano de lançamento.

O pôquer de planejamento ou planning poker, como é conhecido, é um jogo de estimativa usado


por equipes ágeis.

Vários membros da equipe são solicitados a estimar uma história de usuário desenhando uma
carta de jogo com uma série de pontos de história e colocando-a voltada para baixo na mesa.

Em seguida, os cartões são virados para cima e, se houver discrepâncias – por exemplo, um
membro da equipe estimou 1 ponto e outros estimaram 4 ou 5, eles podem discutir e chegar a
um consenso.

Vamos fazer isso passo a passo?

Creio que seja o momento ideal de você não ter mais dúvidas a este respeito porque, afinal,
estamos desenvolvendo a parte escritural de um projeto.

Estas são as seguintes regras básicas:


"Cada participante recebe um baralho de cartas de estimativa representando
uma sequência de números. As sequências mais populares envolvem a
duplicação de cada cartão (0, ½, 1, 2, 4, 8, 16, etc.) ou a sequência de Fibonacci
(1, 2, 3, 5, 8, 13, 21, etc.). A sequência de Fibonacci é geralmente mais popular;

O moderador apresenta uma história de usuário por vez para a equipe. São as
histórias daquela sprint ou no máximo 2 sprints;

O Product Owner responde a quaisquer perguntas que a equipe possa ter sobre a
história;

Cada participante seleciona em particular um cartão que representa sua


estimativa do “tamanho” da história do usuário. Normalmente, o tamanho
representa um valor que leva em consideração o tempo, risco, complexidade e
quaisquer outros fatores relevantes. Claro que todos os participantes
desenvolvedores devem ter ciência de desenvolvimento, o que é simples e o
que é complexo, não se trata de um jogo de adivinhação e nem chute;

Quando todos estão prontos com um “orçamento” (sim, você está estimando,
orçando quando lança uma carta), todos os cartões são apresentados
simultaneamente;

Se houver consenso sobre um determinado número, o tamanho é registrado e


a equipe avança para a próxima história;

No caso (muito provável) de que as estimativas sejam diferentes, os


estimadores alto e baixo defendem suas estimativas para o resto da equipe.

O grupo debate brevemente os argumentos;

Uma nova rodada de estimativa é feita (etapas 4 e 5);

Continue até que o consenso seja alcançado e o moderador registre a


estimativa;

Repita para todas as histórias."

- HARTMAN, 2009, p. 1
Por que esse “jogo” se tornou tão útil:

Promove a colaboração envolvendo toda a equipe;

Cria uma estimativa de consenso em vez de ter uma única pessoa conduzindo a
estimativa;

Expõe problemas no início por meio da discussão de cada história de usuário.

Aqueles que realmente poderiam fazer o trabalho são os que votam. Muitas vezes, as equipes
ágeis fazem com que todos votem, mesmo que não tenham ideia do trabalho envolvido na
história. Eu particularmente sou extremamente contra isso. Vota quem pode fazer o trabalho de
verdade e sim, tem que ser mais que um, os motivos são óbvios e seguem os princípios dos
times ágeis autogerenciáveis e com experiência. Além disso, há uma velha máxima na área de
tecnologia da informação que diz respeito a: backup, redundância e contingência. Nunca se
esqueça disso, você pode ficar “na mão” de uma hora para outra.

Quando houver empate na votação entre dois tamanhos consecutivos, basta escolher o tamanho
maior e seguir em frente.

Lembre-se de que os tamanhos consecutivos podem ser 5 e 8 se você estiver usando a sequência
de Fibonacci para dimensionamento (1, 2, 3, 5, 8, 13…). Ninguém deve reclamar de usar o
número mais alto, e uma divisão igual geralmente leva muito tempo para ser resolvida.
Geralmente também resulta no número mais alto, pelo menos na minha experiência, então
vamos usar esses fatos a nosso favor e seguir em frente.

Pare as discussões de implementação antes que elas se aprofundem demais; afinal, as equipes
costumam ir até os detalhes técnicos quando estão discutindo uma história de usuário. Isso é
bom até certo ponto, mas deve ser severamente limitado. Não mais do que uma discussão de um
minuto. As pessoas que fazem o dimensionamento devem determinar em sua mente a solução
mais simples possível e escolher um tamanho com base nesse cenário.
Use algum tipo de cronômetro para limitar a discussão, normalmente se limita as discussões a
não mais do que 1 minuto. Trata-se da questão de você criar uma cultura de ser eficaz.

Também é importante limitar o número de rodadas quando não se tem consenso, normalmente
eu limito nos projetos até a terceira rodada, de tal forma que se exceder eu escolho o maior
tamanho e sigo em frente para a próxima história.

Jogo de planejamento não é um amontoado de adultos brincando com cartas, trata-se de uma
técnica mundialmente utilizada para estimativa de desenvolvimento, otimize o tempo da sua
equipe de desenvolvimento, sugiro uma boa prática aqui: faça com que a pessoa que está criando
as histórias de usuário (pode ser o product owner ou outro) se reúna com os líderes de controle
de qualidade e desenvolvimento antes de ir jogar o planning poker com o time scrum. Recomendo
isso para garantir que as histórias de usuário tenham respostas para as perguntas mais óbvias
que a equipe fará durante esse processo.

Por fim, é importante lembrarmos e mantermos a linha de base de uma história de usuário, ela
deve ser e se manter consistente durante e para cada iteração (sprint). Então, o que quer que a
equipe escolha como linha de base precisa ser consistente de sprint para sprint. Se um dia ideal
tiver tamanho 1, todas as sprints precisam usar esse ponto de referência. Se uma determinada
história de usuário for de tamanho 1 ou 3, então isso precisa permanecer consistente nas sprints.

Ao final você deve sair com uma lista de história de usuários mais bem estruturada e com as
observações que o time de desenvolvimento colocar, melhor se traduzir os story points em horas,
veja na tabela a seguir:

Tabela 1 – Histórias do usuário após o Planning Poker do e-commerce do café gourmet

Story Card 2 Tarefas


Story Card 2 Tarefas

"Como consumidor, eu gostaria


Fazer breve texto sobre
de uma descrição do produto,
características básicas do
para eu saber especificamente
produto.
as características do produto."

Observações: características Fazer texto sobre características


gerais e características técnicas. técnicas do produto.

Restrição: nas características Criar “aba” para características


gerais, no máximo 3 linhas de básicas.
texto. (cor, o que vem no kit, sabor).

Criar “aba” para características


técnicas

Restrição: nas características (tipo de grão, material dos


técnicas, até 10 linhas de texto. produtos (cerâmica, plástico
etc.), embalagem.
Horas: 2/4.

Gráficos Burndown e Burnup

Burndown
O Gráfico de Burndown é uma ferramenta de medição visual que mostra o trabalho concluído por
dia em relação à taxa de conclusão projetada para a versão atual do projeto. Seu objetivo é
permitir que o projeto esteja no caminho certo para fornecer a solução esperada dentro do
cronograma desejado.

Nós vimos que a taxa de progresso de uma equipe Scrum é chamada de velocidade. Ele expressa a
quantidade de trabalho ou, dependendo do tipo de equipe que estiver construindo, pontos da
história medidos por iteração.

Uma regra de importação para calcular a velocidade é que apenas as histórias concluídas no final
da iteração são contadas. A contagem do trabalho parcialmente finalizado é estritamente
proibida. Trabalho de software sem teste ou que tem pendência de teste não é aceito para
computar isso, portanto além de proibido no Scrum não deve ser computado, mesmo!

Após algumas Sprints, a velocidade de uma equipe Scrum provavelmente será previsível e
permitiria uma estimativa bastante precisa sobre o tempo necessário até que todas as entradas
no Backlog do produto Scrum sejam concluídas.

No entanto, na realidade, as entradas no Backlog do produto Scrum serão alteradas ao longo da


duração do projeto. Novas histórias são adicionadas e outras são alteradas ou mesmo excluídas.
No gráfico de Burndown simples, a velocidade da equipe Scrum e a mudança no escopo não
podem ser distinguidas.

Veja este exemplo:


Figura 1 – Exemplo de Gráfico de Burndown

#ParaTodosVerem: Figura exemplo de um gráfico de burndown. Figura em cores


utilizando diversos tons de azul para mostrar um gráfico de barras descendentes
conforme o número de iterações aumenta, ou seja, o projeto se aproxima de seu
final. O eixo vertical no lado esquerdo mostra o esforço total, enquanto o lado direito
possui o outro eixo que mostra a velocidade da equipe. Este gráfico também fornece
as seguintes informações: trabalho finalizado durante cada iteração; trabalho que
ainda precisa ser feito e o período em que a equipe espera que o projeto seja
finalizado. Embora este gráfico seja muito claro e fácil de seguir, não é
necessariamente realista. Por isso o exemplo aplicado aqui é idealista, porque um
verdadeiro gráfico de burndown não teria linhas direitas para mostrar períodos (linha
diagonal descendente), porque a equipe nunca vai completar as suas tarefas na
mesma velocidade ou no mesmo período. Fim da descrição.

“Os gráficos de Burndown são altamente efetivos e têm muitos pontos fortes.

Embora, usar um gráfico também tenha os seus contras ou pontos fracos.


Os prós em usar um burndown são:

São representações simples e fáceis de seguir;

Mostram claramente as conquistas de uma equipe Ágil;

Nitidamente mostram o que a equipe ainda precisa conquistar;

Informa as equipes se estão cumprindo os prazos;

Rapidamente, alerta a equipe para potenciais problemas ou situações de


bloqueio;

Mostra a inatividade de um projeto;

As equipes podem ver onde precisam de concentrar os seus esforços para “se
encontrarem” novamente;

Motivam a equipe;

Mostram à equipe onde esta foi bem sucedida e quanto trabalho ainda
precisam realizar.

Os contras de usar um burndown incluem:

São limitadores: os gráficos apenas mostram parte da imagem total;

Não mostram que tarefas ainda estão em progresso;

Não mostram quão perto uma equipe está de completar o seu trabalho;

Podem dar origem a expectativas exacerbadas.

As equipes que têm projetos agressivos, baseados em períodos irrealistas ou super


inflacionados, podem ficar facilmente desapontadas, ou perder a sua motivação,
quando o projeto não corre da melhor forma.

A equipe também pode desmoralizar, se sentir que está a ser micro gerida (estão
ingerindo na autonomia) e isso em ágil normalmente é mortal (o time deixa que
está micro gerenciando ou tentando influenciar falando sozinho).

Qualquer informação que não seja contemplada no gráfico de burndown deve ser
abordada numa reunião SCRUM, para a equipe ter uma imagem clara de como o
projeto está avançando.”

- GONÇALVES, 2020, p. 3

Gráficos de Burndown são simples, afinal, é uma única linha correndo para encontrar zero ao
final do tempo (última data) quando o projeto é concluído, não me parece ser difícil de entender
e construir. Qualquer um pode entender, ele é tão intuitivo que quase não merece sequer
explicação. No entanto, pode ocultar informações importantes, por exemplo, os efeitos da
alteração do escopo.

Chamamos em ágil de mudança de escopo, quando o trabalho é adicionado ou removido de um


projeto. Estamos todos familiarizados com a alteração do escopo, o cliente exige recursos extras
repentinamente ou o trabalho é removido de um projeto para cumprir um prazo ou baixar um
valor. Um gráfico de burndown não mostra essas informações tão claramente quanto um gráfico
de burnup, por exemplo.

Burnup
Um gráfico de burnup rastreia o trabalho concluído e o trabalho total com duas linhas separadas,
ao contrário de um gráfico de gravação que os combina em uma única linha. A linha de um
gráfico de burnup mostra o trabalho concluído e comunica informações importantes, por
exemplo, se o projeto ainda não está concluído porque o trabalho é lento para ser realizado ou há
muito trabalho novo sendo adicionado. Essas informações podem ser cruciais para diagnosticar
e corrigir problemas em um projeto.

Portanto, um gráfico de Burnup rastreia o progresso em direção à conclusão de um projeto. Na


forma mais simples desse gráfico, existem duas linhas: a primeira, a linha de trabalho total
mostra a linha de escopo do projeto e, a segunda mostra o trabalho concluído.

Figura 2 – Exemplo de gráfico de Burnup


Fonte: Reprodução

#ParaTodosVerem: Exemplo de gráfico de burnup. Gráfico em imagem colorida


com duas linhas, uma na cor azul escuro que representa o trabalho em histórias
do usuário e as tarefas adicionadas pelo cliente e a outra linha em azul claro que
representa o trabalho retirado/realizado pelo time de desenvolvimento para
atingir a data final do projeto. O eixo vertical representa o volume de histórias ou
tasks em unidades e o eixo horizontal representa o trabalho diário feito na
resolução/entregas dessas tarefas feitas pela equipe de desenvolvimento do
projeto. Fim da descrição.

Esse gráfico mostra claramente o trabalho concluído contra o escopo do projeto. O projeto será
concluído quando as linhas se encontrarem. Simples assim!

O eixo vertical é a quantidade de trabalho e é medido em unidades personalizadas; algumas


unidades comuns são o número de tarefas, horas estimadas, histórias ou pontos de história. O
eixo horizontal é o tempo, geralmente medido em dias (é muito difícil ver isso em horas). A cada
dia no gráfico, você pode ver a quantidade de trabalho concluído e a quantidade total de trabalho.
A distância entre as duas linhas é, portanto, a quantidade de trabalho restante. Quando as duas
linhas se encontrarem, o projeto estará completo.

Podemos ver que a vantagem do Burnup sobre o Burndown é a inclusão da linha de escopo. Ela
rastreia claramente quando o trabalho foi adicionado ou removido do projeto. Também permite
visualizar uma data de conclusão mais realista para o projeto, estendendo uma linha de
tendência do escopo e da linha de conclusão. Onde as duas linhas de tendência se encontram é o
tempo estimado de conclusão.

A seguir ofereço a narrativa de um caso prático de uso de gráfico de burnup.

“Product Owners e Agile Coaches projetam cenários baseados em três perspectivas:

Pior caso: projetar a performance futura da equipe com base no menor


Throughput (Taxa de transferência) histórica;

Melhor caso: considerar que a equipe atuará no futuro com base no maior
Throughput histórica;

Caso mais provável: considerar que a equipe terá no futuro um


comportamento semelhante ao Throughput “médio” (recomendo a leitura do
artigo que escrevi sobre o motivo pelo qual você deve ter cuidado ao usar a
média como medida).

Em nosso contexto, o gráfico de Burnup está nos ajudando a responder perguntas


como:

O escopo do projeto está crescendo de forma saudável?

Quando a equipe terminará o escopo atual do projeto?


O exemplo abaixo (nas próximas Figuras) aconteceu com um cliente da
Plataformatec e as circunstâncias eram as seguintes:

Duração do projeto: 23 semanas (quase seis meses);

Expectativa do cliente: ter uma solução para resolver um problema de


processo interno (projeto do zero, sem código legado);

Roadmap do produto: após a sessão inicial de story mapping, a equipe e o


cliente reduziram o escopo da entrega;

Desafio do projeto: assegurar que o software estivesse disponível para uso na


data acordada.

Neste projeto, usamos o gráfico de Burnup como ferramenta para comunicar o


progresso do projeto. O gráfico foi desenvolvido para exibir:

O número de itens de trabalho planejado para a entrega (escopo);

O número de itens entregues;

Cenários para possíveis datas de entrega do projeto.

Os próximos três gráficos representam o projeto no início (primeiras 6 semanas),


no meio (12 semanas) e no fim (semana 23).
Analisando o início do projeto, tivemos um cenário de aumento do escopo e
algumas entregas.
Em relação ao escopo, o aumento aconteceu devido ao refinamento de um conjunto
de histórias de usuário criadas após o story mapping (mapa de histórias dos
usuários).

Um indicador útil para analisar o crescimento do backlog é calcular a taxa de


aumento semanal de novas histórias de usuários (no exemplo, 7 histórias de
usuário foram criadas por semana no início do projeto).
Aqui na Plataformac, usamos esse indicador como ferramenta para manter o
aumento do escopo previsível.

No meio do projeto, houve crescimento contínuo do escopo (seis novas histórias


de usuário criadas por semana). Neste momento, tivemos que sentar-nos com o
cliente para alinharmos formas de simplificar o escopo, porque, caso ele
continuasse a crescer, dificilmente entregaríamos uma versão do software no final
do contrato. O gráfico de Burnup foi útil para definir estratégias para melhorar o
Throughput com base nos resultados das entregas realizadas.

A técnica de projeção utilizada foi importante para chegar ao final do projeto


entregando todas as funcionalidades necessárias para o software.
Na conclusão do projeto, realizamos uma sessão de lições aprendidas e a equipe
destacou que o gráfico de Burnup foi útil, pois:

Trouxemos visibilidade ao processo do desenvolvimento garantindo que o


cliente estava alinhado com o progresso e o prazo de entrega;

Mostramos visualmente como o aumento do escopo influencia o prazo de


entrega, sendo assim, uma boa ferramenta de negociação."

- ALBINO, 2017, p. 3-4


Figura 3– Projeto exemplo levando em consideração
(melhor cenário de data, na linha vertical verde, e pior
cenário de data, a linha vertical vermelha), usando o
controle com gráfico de burnup

#ParaTodosVerem: Um gráfico com projeções de término utilizando a técnica


visual de acompanhamento de entregas chamada Burnup. Figuras coloridas em
tons de azul representando gráficos superpostos em fundo branco com duas
linhas verticais, uma verde (indicando a data mais otimista para terminar o
projeto) e outra mais a frente em vermelho (indicando a data mais pessimista
para o término). A distancia horizontal entre a linha vertical (verde) e a linha
vertical (vermelha) e de aproximadamente 1 semana de diferença entre a data
otimista e a data pessimista de entrega. Fim da descrição.

Refatoração de Código
A maioria dos clientes deseja que seus aplicativos sejam desenvolvidos de forma rápida,
econômica e confiável. No entanto, na busca por economia de tempo e dinheiro, a qualidade é
muitas vezes deixada de lado e algumas atividades de melhoria de qualidade são colocadas em
um depósito que muitas vezes fica esquecido, portanto, nunca ocorrerá, e isso é péssimo.
Refatoração é algo muito próximo dos sistemas de qualidade de montadoras como a Toyota. Sim,
trata-se de melhoria contínua, porém sem alterar a essência, ou seja, o objetivo da
funcionalidade do software.

Em linhas gerais, podemos definir a refatoração de código como um processo de edição e


limpeza do código da aplicação que otimiza sua estrutura interna, mas sem alterar seu
comportamento e funcionalidades externas.

O interessante é que a necessidade de refatoração de código pode não ser realmente óbvia para
observadores externos.

Tornar o código mais sustentável e extensível. Atualizações e upgrades adicionados ao aplicativo


são um processo contínuo e essencial. Portanto, o código existente deve tornar esse processo
possível. Por exemplo, a integração de algumas funcionalidades pode não ser levada em
consideração ao projetar a arquitetura inicial, portanto, novos recursos podem exigir essas
mudanças na abordagem geral de desenvolvimento e no código também.

Em geral, olhar para trás e organizar o código atual antes de adicionar novas funcionalidades
não apenas melhorará a qualidade do aplicativo em si, mas também tornará mais fácil para
futuros desenvolvedores construir/melhorar o código-fonte.

Além disso, quando a base de código é desestruturada e construída de forma ineficiente, os


desenvolvedores passam a ter “medo” em fazer qualquer alteração. Por sua vez, um código
bem-organizado e limpo “motiva” os desenvolvedores a manter a ordem e adicionar melhorias.

Não refatorar gerará ao longo do tempo do projeto de software algo que é perigoso e que é
chamado de: dívida técnica.

A falta de refatoração pode resultar no acúmulo dessa dívida técnica, ou seja, os resultados
quando as equipes de desenvolvimento tomam ações para agilizar a entrega de uma
funcionalidade ou projeto que posteriormente precisa ser refatorado.

Em outras palavras, é o resultado de priorizar a entrega rápida sobre o código perfeito, podemos
dizer que isso gera a dívida técnica.
Portanto, quanto mais tempo demoramos para nos importar com os problemas menores ao
longo do caminho, maior a probabilidade de eles se transformarem em grandes complexidades
mais à frente.

As principais consequências em alto nível causadas pela dívida técnica acumulada no sistema
são:

Novos recursos desenvolvidos e entregues muito mais lentamente;

A transferência de conhecimento para novos desenvolvedores que ingressam no


projeto é mais ineficiente;

As estimativas são imprecisas, o que resulta em prazos perdidos.

Assim, mais cedo ou mais tarde, a “dívida deverá ser quitada”, para que se prossiga com o
trabalho de desenvolvimento e melhoria.

Os seguintes pontos podem desencadear atividades de refatoração:

O código é difícil de ler e muito volumoso após/durante a execução/término do


desenvolvimento do software;

A duplicação de partes de código é frequentemente usada em um aplicativo o que


causa redundância e ineficiência e, claro, dificuldade em manutenção;

Muitos operadores condicionais de destaque são usados em um código, há


necessidade de verificação para otimizar e fazer ajustes “finos” o que se
convenciona chamar na área de tecnologia de “Tunning” (sintonia).

Por outro lado, consideramos um código limpo com as seguintes características:

A lógica do código é direta, o que dificulta a ocultação de bugs;


As dependências são mínimas, o que simplifica a manutenção do software;

O desempenho está próximo do ideal sem otimizações desnecessárias;

Não contém duplicação e minimiza o número de entidades, como: classes, métodos,


funções e assim por diante.

Reuso de Código
A reutilização de código pode resolver os problemas de crescimento de software associados a
desafios comerciais e técnicos.

Ao contrário do que se pensa no senso comum, a reutilização de código é a prática de usar o


código existente para uma nova função ou software. Para que um código seja reutilizável ele deve
ser: seguro, protegido e confiável.

Em um ambiente ideal, um desenvolvedor seria capaz de acessar bibliotecas de código estáveis e


confiáveis. Eles poderiam então reutilizar o código dessas bibliotecas como blocos de
construção em seu aplicativo. Assim, pode-se reutilizar o código quando ele for:

Facilmente estendido e adaptado para a nova aplicação;

Portado (transferido) para hardwares diferentes, se necessário;

Mostrar-se livre de defeitos ou problemas que afetam a confiabilidade, segurança


ou proteção do novo aplicativo.

Mas, o ambiente nem sempre é o ideal. Na prática, os desenvolvedores geralmente acabam


reconstruindo o software do zero. Ou eles só podem reutilizar uma pequena fração do código
existente em novos projetos. Portanto reuso de código é desafiador!
Isso é especialmente verdadeiro para organizações com muitos componentes de produtos e
equipes de desenvolvimento distribuídas geograficamente (dispersas em muitos países, por
exemplo).

Porém quando se consegue desenvolver bibliotecas temos muitas vantagens que valem a pena o
esforço:

Tempo total de desenvolvimento significativamente reduzido;

Melhoria do produto a um custo menor;

Melhor experiência do usuário;

Prevenir o inchaço do código.

Segundo Bellairs (2017), existem quatro características principais de qualidade de software que
afetam a reutilização:

“Segurança: Para ser reutilizado, o código precisa ser seguro. Você pode garantir

um código seguro de várias maneiras, inclusive usando uma lista CWE.

Confiabilidade: para ser reutilizado, o código precisa ser confiável. Você pode
garantir um código confiável garantindo disponibilidade, tolerância a falhas e
capacidade de recuperação;

Eficiência de Desempenho: para ser reutilizado, o código precisa ser eficiente.


Você pode garantir a eficiência melhorando os tempos de resposta e
monitorando o processador, a memória e a utilização;

Manutenibilidade: para ser reutilizado, o código precisa ser sustentável. Uma


maneira de garantir que o código seja sustentável é garantir que ele seja
compatível."

- BELLAIRS, 2017, p. 2

Repositório e Controle de Versionamento


O controle de versão, também conhecido como controle de revisão ou controle de origem, é o
gerenciamento de alterações em documentos, programas de computador, grandes sites da Web
e outras coleções de informações. Cada revisão está associada a um carimbo de data e hora e à
pessoa que está fazendo a alteração.

Uma única pessoa raramente é responsável pela codificação de projetos de software de médio ou
grande porte. Hoje, as equipes, tanto locais quanto geograficamente dispersas, fazem a maior
parte do desenvolvimento.

No entanto, em um passado não muito distante, os programadores eram fisicamente


centralizados e quantas vezes gritavam uns com os outros pela sala de desenvolvimento ou
então pairavam sobre o colega perturbando-o com a versão mais recente, esperando sua chance
de adicionar arquivos, assim que ele saísse. E, embora esteja claro que modificações em
documentos para desenvolvimento de software baseado em equipe requerem mais estrutura do
que um único arquivo, implantar um sistema que protege o documento mestre enquanto
fornece produtividade ideal continua a ser um desafio.

Um forte sistema de controle de versão de código pode fornecer clareza ao revisar o software,
esclarecendo o que foi alterado, por quem e quando. Geralmente, essas soluções funcionam para
fornecer um formato lógico para rastrear o progresso do desenvolvimento, mantendo as
alterações detalhadas, e têm a capacidade de reverter para versões anteriores.

O controle de versão permite que você gerencie as alterações nos arquivos ao longo do tempo.
Você pode usar o controle de versão para código de versão, arquivos binários e ativos digitais. Ele
é um componente do gerenciamento de configuração de software, além disso também é a prática
DevOps de garantir que cada tecnologia em um determinado produto esteja usando uma versão
escolhida e confiável da tecnologia que seja compatível com cada componente dentro do
ecossistema do produto.

Hoje, uma equipe de desenvolvedores é responsável pela maioria das compilações de software. A
importância do controle de versão do código é que ele fornece um veículo de comunicação
constante para a equipe, estejam eles na mesma sala ou ao redor do mundo.

O controle de versão fornece um método lógico que preserva as contribuições individuais dos
membros da equipe sem sobrescrever o trabalho de outro desenvolvedor e, a seguir, mescla e
reconcilia as alterações e atualizações. Também é à prova de falhas para localizar e dar suporte a
problemas que estão em conflito. O registro histórico produzido pode ser usado para rastrear as
origens do problema ou arquivar versões para uso posterior, sendo que isso ajuda muito a
interação entre o time de testes e o de desenvolvimento. Mesmo se um desenvolvedor estiver
trabalhando sozinho, o sistema fornece a manutenção de registros defensivos do progresso e
do processo. A preservação de informações valiosas e trabalhos anteriores é possível somente
através do controle de versão.

Claro que fazemos isso através de softwares como GIT ou BITBUCKET, por exemplo. Sim, existem
outros mais sofisticados e caros, mas como exemplo, esses dois servem muito bem para ilustrar
que, os sistemas de controle de versão de software oferecem suporte a um plano geral de
desenvolvimento Ágil, fornecendo um mecanismo de prova de como o código foi construído,
quando foi alterado e por quem.

Quando esses sistemas são bem gerenciados, eles possuem convenções de numeração de versão
que são facilmente identificáveis por toda a equipe.

O sistema gerencia os diretórios, arquivos e alterações individuais feitas ao longo do tempo, o


que permite aos usuários encontrar as causas raiz dos erros ou bugs, ou reverter para uma
versão anterior.

Como vantagem, ter controle de versionamento de software é importante porque:

Melhora a produtividade da equipe e permita a colaboração;


Melhora a comunicação da equipe com uma solução confiável;

Reduz erros e conflitos de desenvolvimento;

Melhora a satisfação do cliente com versões de software confiáveis.

Desenvolvedores, codificadores, designers e engenheiros de software são os principais usuários


de um sistema de controle de versão de software de design e construção. Os gerentes de projeto
envolvidos no desenvolvimento também podem monitorar as práticas de controle de versão.

Ao escolher um sistema de controle de versão, as primeiras etapas incluem saber de qual acesso
você precisa e como a equipe deve colaborar. O modo como o documento é controlado, editado e
mesclado também é de importância central.

A configuração básica inclui os seguintes componentes:

Repositório: o banco de dados principal que armazena os


metadados para os arquivos do projeto (o conjunto de dados
principal é chamado de tronco);

Servidor: o computador que contém o repositório principal;

Cliente: a máquina que o desenvolvedor usa para se conectar ao repositório;

Cópia de trabalho: a cópia do arquivo do projeto que o desenvolvedor edita.

O controle de versão pode ser uma excelente ajuda para correções de emergência, manutenção
de rotina, atualizações e novos recursos com prazos de desenvolvimento potencialmente
sobrepostos.
Quando você precisa solucionar um problema, pode acessar e comparar facilmente o último
arquivo de trabalho com o arquivo com defeito e diminuir o tempo gasto na identificação da
causa de um problema.

Você pode restaurar versões anteriores de um arquivo, ou até mesmo de todo o projeto de forma
eficaz por meio do uso de sistemas de controle de versão, sendo que você pode simplesmente
desfazer tudo que você fez com apenas alguns cliques.

Existem três tipos de controle de versão:

Sistemas de Controle de Versão Local: é um dos mais simples e


possui um banco de dados que mantém todas as alterações dos
arquivos sob controle de revisão. Eles mantêm conjuntos de
patches, ou seja, diferenças entre arquivos em um formato
especial no disco. Ao adicionar todos os patches, ele pode
recriar a aparência de qualquer arquivo em qualquer
momento;

Sistemas de Controle de Versão Centralizados: contêm apenas um repositório e


cada usuário obtém sua própria cópia de trabalho. Você precisa se comprometer a
refletir suas mudanças no repositório. É possível que outras pessoas vejam suas
alterações atualizando. O benefício é que ele favorece a colaboração entre os
desenvolvedores, além de fornecer uma visão, até certo ponto, sobre o que todos os
outros estão fazendo no projeto. Ele permite que os administradores tenham
controle refinado sobre quem pode fazer o quê. Por outro lado, a desvantagem óbvia
é o ponto único de falha que o repositório centralizado representa se ele cair durante
esse período de colaboração e salvar as alterações de versão não for possível. E se o
disco rígido do banco de dados central for corrompido e os backups adequados não
forem mantidos? Você perde absolutamente tudo. Já sei, você pensou em backup,
redundância e contingência. Mas se isso ocorrer durante o dia com uma mudança
maciça, adeus alterações mesmo. Teria que trabalhar com o backup do dia anterior
ou então você pode possuir algum servidor espelhado com um sync a cada 2 horas
por exemplo, mas seriam 2 horas perdidas de alteração. Alguns softwares:
Subversion (SVN) ou Sistema de Versão Concorrente (CVS);
Sistemas de Controle de Versão Distribuída: contêm vários repositórios. Cada
usuário tem seu próprio repositório e sua cópia de trabalho. Apenas confirmar de
suas alterações não darão a outros acessos às suas alterações. Isso ocorre porque o
commit irá refletir essas mudanças em seu repositório local e você precisa
“empurrá-las” para torná-las visíveis no repositório central. Da mesma forma, ao
atualizar, você não obtém as alterações de outros, a menos que primeiro tenha
obtido essas alterações em seu repositório. De forma muito simples:

Você se compromete em mudar o código no seu repositório;

Você empurra essas mudanças atualizando;

Eles puxam as mudanças feitas;

Eles atualizam o repositório central deles e o ciclo reinicia.

Um sistema de controle de versão distribuído é projetado para atuar nos dois sentidos. Ele
armazena todo o histórico do arquivo em cada máquina localmente. Ele também sincroniza as
alterações locais feitas pelo usuário de volta ao servidor sempre que necessário, para que as
alterações possam ser compartilhadas com outras pessoas, proporcionando um ambiente de
trabalho colaborativo.

Código Coletivo
O conceito de Propriedade Coletiva de Código aponta para o fato de que em um processo ágil de
desenvolvimento de software, nenhum membro de toda a equipe possui uma parte específica do
código-fonte.

Portanto, qualquer membro da equipe pode contribuir com uma nova ideia para o projeto que
visa melhorar o design do software e corrigir quaisquer bugs no projeto.

No processo, há uma aplicação consistente de padrões de codificação e cada membro da equipe


contribui de uma forma que pode ser decifrada por qualquer membro de toda a equipe.
Quaisquer novas versões criadas por qualquer membro da equipe que sejam incompreensíveis
são substituídas por versões mais simples que podem ser compreendidas por todos os membros
envolvidos no processo.

Ela viabiliza a programação em pares e a refatoração no processo de construção do software. A


equipe pode concluir a tarefa com qualquer um dos membros ausente por qualquer motivo. Isso
é ativado por cada membro da equipe de desenvolvimento criando um teste de unidade para
garantir que a funcionalidade de seu código não seja adulterada.

Uma vez implementados, os testes de unidade possibilitam que qualquer pessoa que trabalhe na
equipe aplique qualquer alteração no código-fonte sem afetar a funcionalidade geral e com a
confiança de que quaisquer novas alterações feitas por outros membros da equipe não afetarão o
código.

Como a equipe trabalha com prazo, a propriedade coletiva dos códigos, por meio de testes
unitários, garante que as versões incompatíveis com os códigos da equipe sejam corrigidas
assim que forem desenvolvidas. Isso se mostra mais eficiente em comparação com a correção
de toda a base de código à medida que o prazo se aproxima.

Os benefícios associados a essa prática são:

Todos se sentem responsáveis: cada indivíduo se sentirá


responsável e culpado pela qualidade geral do produto de toda
a equipe e, portanto, se esforçará para tornar o projeto um
sucesso;

Reduzir os riscos: Há uma redução significativa no risco associado ao absenteísmo


e indisponibilidade de qualquer membro da equipe para que o projeto não seja
prejudicado;

Julgamentos sólidos: o desenho final do projeto será alcançado com os julgamentos


técnicos corretos;
Compartilhando conhecimento: haverá uma boa transferência e compartilhamento
de conhecimento técnico entre os membros da equipe.

Família de Design Patterns


No desenvolvimento de software, um padrão ou padrão de projeto é um documento escrito que
descreve uma solução geral para um problema de projeto de software que se repete em muitos
projetos. Os designers de software adaptam a solução padrão ao seu projeto específico e com isso
ganham desempenho, manutenabilidade e componentização, além de facilitar a refatoração.

DAO
O padrão Data Access Object (DAO) é um padrão estrutural que nos permite isolar a camada de
aplicativo/negócio da camada de persistência (geralmente um banco de dados relacional, mas
pode ser qualquer outro mecanismo de persistência) usando uma API abstrata.

Quais são os tipos de padrão de projetos?

Criacional: Esses padrões são projetados para instanciamento


de classes;

Estrutural: Esses padrões são projetados em relação à estrutura e composição de


uma classe;

Comportamental: Esses padrões são projetados dependendo de como uma classe se


comunica com outras.

Bem, talvez você pergunte, o que é API?

Os produtos de software trocam dados e funcionalidades por meio de interfaces legíveis por
máquina chamadas de APIs (interfaces de programação de aplicativos).
Portanto, trata-se de um conjunto de códigos de programação que permite a transmissão de
dados entre um produto de software e outro. Ele também contém os termos dessa troca de dados.

As interfaces de programação de aplicativos consistem em dois componentes:

Especificação técnica descrevendo as opções de troca de dados entre soluções com a


especificação feita na forma de solicitação de protocolos de processamento e
entrega de dados;

Interface de software escrita na especificação que a representa.

Então temos ao menos dois cenários:

No primeiro temos um software que precisa acessar informações ou funcionalidade


de um outro software. Então, ele “chama” sua API enquanto especifica os requisitos
de como os dados/funcionalidades devem ser fornecidos;

O segundo software retorna os dados/funcionalidades solicitados pelo aplicativo do


primeiro software.

A interface pela qual esses dois aplicativos se comunicam é o que a API especifica.

Dando prosseguimento à explicação, agora que você já sabe o que é uma API, está oculta do
aplicativo toda a complexidade de realizar operações CRUD (acrônimo para: Criar, ler, atualizar e
apagar, ou seja, é a mesma coisa que uma rotina de controle cadastra, onde temos sempre as
rotinas de: inclusão, alteração, consulta e exclusão de dados), no mecanismo de
armazenamento subjacente. Isso permite que ambas as camadas evoluam separadamente sem
saber nada uma da outra (isso impede acessos indevidos a todos os dados que podem ser
roubados. Usando essa técnica, apenas o que é estritamente necessário será utilizado).

DAO – Data Access Objects significa Objeto de Acesso a Dados. É usado para separar a lógica de
persistência de dados (armazenagem de dados) em uma camada separada. Dessa forma, o
serviço permanece completamente no “escuro” sobre como são feitas as operações de baixo
nível para acessar o banco de dados. Isso é conhecido como o princípio da Separação da Lógica.

Leitura
Implementando o Data Access Object no Java EE
Vamos entender mais profundamente o DAO lendo o seguinte artigo
contendo exemplos que você poderá rodar em JAVA para testar.

Clique no botão para conferir o conteúdo.

ACESSE

MVC
O padrão de projeto MVC também é conhecido como Model-View-Controller. É um padrão de
arquitetura comum usado para projetar e criar interfaces e a estrutura de um aplicativo. Esse
padrão divide o aplicativo em três partes que são dependentes e conectadas entre si. Esses
designs são usados para distinguir a apresentação de dados de como os dados são aceitos pelo
usuário para os dados mostrados. Esses padrões de projeto se tornaram comuns no uso de
aplicativos da Web e no desenvolvimento de GUIs – Interfaces Gráficas de Usuário.

Vamos conhecer essas três camadas:


Modelo/Model: Esta parte do padrão de design é a parte
principal e contém apenas informações do aplicativo. Ele não
contém nenhuma informação sobre como mostrar os dados ao
usuário. É independente da interface do usuário. Ele controla a
lógica e as regras de aplicação;

Visualizar/View: Esta parte ajuda o usuário a ver os dados do modelo. A principal


preocupação é acessar os dados. Para isso se lança mão de um gráfico, tabela ou
diagrama para representar as informações. Ou seja, é uma visualização das
informações que o aplicativo contém;

Controlador/Control: A maior parte do trabalho é feito pelo controlador. Ele fornece


o suporte para entrada e a converte em comandos para o aplicativo. É usado entre o
modelo e visualizar.

Leitura
Padrões de Projeto: o Modelo MVC – Model View Controller
Vamos aprofundar os estudos com o artigo a seguir.

Clique no botão para conferir o conteúdo.

ACESSE

GOF
A vantagem de usar Padrões é que eles foram testados e refinados em vários contextos e,
portanto, são tipicamente soluções robustas para problemas comuns.

O padrão conhecido como GOF – Gang Of Four em tradução livre: gangue dos quatro, porque
foram quatro criadores no início. Trata-se de um grupo de vinte e três Design Patterns
originalmente publicados em um livro seminal intitulado Design Patterns: Elements of Reusable
Object-Oriented Software que em português é algo como: Padrões de Desenvolvimento:
Elementos e Reuso em Orientação a Objetos.

Eles são apresentados da seguinte forma levando em consideração suas três grandes divisões:

“Padrões de Design de Criação

Esses padrões de projeto são sobre instanciação de classe. Esse padrão pode ser
dividido em padrões de criação de classes e padrões de criação de objetos.
Enquanto os padrões de criação de classes usam a herança de forma eficaz no
processo de instanciação, os padrões de criação de objetos usam a delegação de
forma eficaz para realizar o trabalho. São eles:

Abstract Factory: cria uma instância de várias famílias de classes;

Builder: separa a construção do objeto de sua representação;

Factory Method: cria uma instância de várias classes derivadas;

Object Pool: evita a aquisição e liberação caras de recursos reciclando


objetos que não estão mais em uso;

Prototype: uma instância totalmente inicializada a ser copiada ou


clonada;

Singleton: Uma classe da qual apenas uma única instância pode existir.
Padrões de Projeto Estrutural

Esses padrões de design são sobre composição de classe e objeto. Padrões


estruturais de criação de classes usam herança para compor interfaces. Padrões de
objetos estruturais definem maneiras de compor objetos para obter novas
funcionalidades.

Adapter: faz a correspondência de interfaces de diferentes classes;

Bridge: separa a interface de um objeto de sua implementação;

Composite: uma estrutura em árvore de objetos simples e compostos;

Decorator: adiciona responsabilidades aos objetos dinamicamente;

Facade: uma única classe que representa um subsistema inteiro;

Flyweight: uma instância refinada usada para compartilhamento eficiente;

Private Class Data: restringe o acesso do acessador/modificador;

Proxy: um objeto que representa outro objeto.

Padrões de Design Comportamental

Esses padrões de design são todos sobre a comunicação de objetos da classe.


Padrões comportamentais são aqueles padrões que estão mais especificamente
preocupados com a comunicação entre objetos.

Chain of responsability: uma maneira de passar uma solicitação entre uma


cadeia de objetos;

Command: encapsular uma solicitação de comando como um objeto;

Interpreter: uma maneira de incluir elementos de linguagem em um programa;

Iterator: acessar sequencialmente os elementos de uma coleção;

Mediator: define a comunicação simplificada entre as classes;


Memento: capture e restaure o estado interno de um objeto;

Null Object: projetado para atuar como um valor padrão de um objeto;

Observer: uma maneira de notificar mudanças em um número de classes;

Estate: altera o comportamento de um objeto quando seu estado muda;

Estrategy: encapsula um algoritmo dentro de uma classe;

Template Method: adiar as etapas exatas de um algoritmo para uma subclasse;

Visitor: define uma nova operação para uma classe sem alteração."

- SOURCEMAKING, 2020, p. 2

GRASP
GRASP – General Responsibility Assignment Software Patterns, ou em português Padrões de
Software de Atribuição de Responsabilidade Geral, é um padrão no desenvolvimento de software
orientado a objetos usado para atribuir responsabilidades a diferentes módulos de código.

É necessária a diferenciação entre GRASP e GOF, muita gente confunde os termos. Para tanto
precisamos definir ou ao menos recordar os Princípios de Desenvolvimento Orientados a
Objetos:

Abstração;

Encapsulamento (ocultação de informações);

Hierarquia (herança, agregação);

Modularidade (alta coesão e acoplamento fraco).


Todos os princípios e padrões subsequentes, ou seja, os design patterns que estamos
descrevendo, estão relacionados a esses princípios principais citados e tentam apoiá-los e
melhorá-los. A partir daí temos as tentativas em apoiar e melhorar os Princípios Principais de
Orientação a Objetos. GRASP é uma delas.

Existe uma outra camada abaixo desta em que a iniciativa do GOF persiste, sendo que nesse caso
há uma proximidade do código, enquanto no GRASP a aproximação é mais filosófica e são,
portanto, abstratos. GRASP são princípios e não estão vinculados a nenhum domínio de
problema específico, portanto, verdadeiro em qualquer cenário.

GRASP ajuda a orientar o design orientado a objetos, delineando claramente quem faz o quê: qual
objeto ou classe é responsável por qual ação ou função. Ele também nos ajuda a definir como as
classes funcionam umas com as outras. O ponto chave é ter um código eficiente, limpo e
compreensível. Dentro do GRASP existem nove princípios:

Creator;

Information expert;

Low coupling;

Controller;

High cohesion;

Indirection;

Polymorphism;

Protected variations;

Pure fabrication.
Leitura
Padrões GRASP — Padrões de Atribuir Responsabilidades

Clique no botão para conferir o conteúdo.

ACESSE

SOLID
SOLID é um padrão de codificação que todos os desenvolvedores devem ter um conceito claro
para desenvolver softwares corretamente para evitar um design ruim. Foi promovido por Robert
C. Martin e é usado em todo o espectro de design orientado a objetos. Quando aplicado
corretamente, torna seu código mais extensível, lógico e mais fácil de ler. De forma geral, SOLID
é um acrônimo que pode ser descrito da seguinte forma, levando em conta os princípios gerais
da orientação a objetos:

Single Responsability Principle ou Princípio da Responsabilidade


Única;

Open/Closed Principle ou Princípio Aberto/Fechado;

Liskov Substitution Principle ou Princípio da substituição de Liskov;

Interface Segregation Principle ou Princípio da Segregação de Interface;

Dependency Inversion Principle ou Princípio da Inversão de Dependência.


Leitura
O que é SOLID: o Guia Completo para Você Entender os 5 Princípios da
POO

Clique no botão para conferir o conteúdo.

ACESSE

Manutenção de Software
A fase de manutenção do software ocorre após o produto estar em pleno funcionamento. A
manutenção do software pode incluir atualizações de software, reparos e correções do software
caso fique disfuncional. Os aplicativos de software geralmente precisam ser atualizados ou
integrados a novos sistemas implantados pelo cliente e, portanto, geram manutenção.

O software está sempre mudando e, enquanto estiver sendo usado, deve ser monitorado e
mantido adequadamente. Isso é em parte para se ajustar às mudanças dentro de uma
organização, mas é ainda mais importante porque a tecnologia continua mudando.

Software precisa de manutenção por vários motivos, para mantê-lo funcionando, aprimorar
recursos, retrabalhar o sistema para alterações no futuro, migrar para a nuvem ou qualquer
outra alteração. Qualquer que seja a motivação para a manutenção de software, ela é vital para o
sucesso do seu negócio. Então você a essa altura já deve ter percebido que a manutenção de
software é mais do que simplesmente encontrar e corrigir bugs. É manter o coração do seu
negócio funcionando!

Vamos conhecer os quatro tipos de manutenção de software:

Manutenção Corretiva de Software: é o que normalmente se


associa à manutenção de qualquer tipo. A manutenção correta
do software aborda os erros e falhas nos aplicativos que podem
afetar várias partes do software, incluindo o design, a lógica e o
código. Essas correções geralmente vêm de relatórios de bugs
que foram criados por usuários ou clientes;

Manutenção de Software Adaptativa: torna-se importante quando o ambiente do seu


software muda. Isso pode ser causado por alterações no sistema operacional,
hardware, outras dependências de software, armazenamento em nuvem ou até
mesmo alterações no sistema operacional como, por exemplo: mudanças de
versões. Às vezes, a manutenção adaptativa de software também reflete políticas ou
regras organizacionais. Atualizar serviços, fazer modificações em fornecedores ou
alterar processadores de pagamento podem exigir essa categoria de manutenção;

Manutenção de Software Perfectiva: foca na evolução dos requisitos e


funcionalidades existentes no sistema. À medida que os usuários interagem com
seus aplicativos, eles podem notar coisas que não percebemos ou sugerir novos
recursos que gostariam que fizessem parte do software, que podem se tornar
projetos ou aprimoramentos futuros. A manutenção de software perfectiva assume
parte do trabalho, adicionando recursos que podem melhorar a experiência do
usuário e removendo recursos que não são eficazes ou funcionais;

Manutenção Preventiva de Software: ajuda a fazer alterações e adaptações no


software para que ele funcione por mais tempo. O foco do tipo de manutenção é
evitar a deterioração do seu software à medida que ele continua se adaptando e
mudando. Esses serviços podem incluir a otimização do código e a atualização da
documentação conforme necessário. A manutenção preventiva de software ajuda a
reduzir o risco associado à operação do software por um longo tempo, ajudando-o a
se tornar mais estável, compreensível e sustentável.
2/3

ʪ Material Complementar

Indicações para saber mais sobre os assuntos abordados nesta Unidade:

Vídeos

User Story Mapping

User Story Mapping - Miguel Fernandes


Criando um Mapa de Histórias de Usuário

Creando un mapa de historias de usuario

Controle de Versão - Versionamento Centralizado e


Distribuído

Controle de versão - Versionamento Centralizado e Distribuído


Leitura

Os Princípios SOLID da Programação Orientada a Objetos


Explicados em Bom Português

Clique no botão para conferir o conteúdo.

ACESSE
3/3

ʪ Referências

ALBINO, R. Métricas ágeis: Throughput e gráfico de Burnup. iMasters, 12/09/2017. Disponível em:
<https://imasters.com.br/agile/metricas-ageis-throughput-e-grafico-de-burnup>. Acesso
em: 18/09/2022.

BELLAIRS, R. What is code reuse? Code reuse best practices. Perforce, 07/07/2017. Disponível em:
<https://www.perforce.com/blog/qac/what-code-reuse-code-reuse-best-practices>. Acesso
em: 18/09/2022.

FREITAS, D. T. M. Análise comparativa entre sistemas de controle de versões. 2010. Trabalho de


Conclusão de Curso (Bacharel em Ciência da Informação) - Instituto de Ciências Exatas,
Universidade Federal de Juiz de Fora, Juiz de Fora, MG, 2010. Disponível em:
<https://www.ufjf.br/getcomp/files/2013/03/An%c3%a1lise-Comparativa-entre-Sistemas-de-
Controle-de-Vers%c3%b5es-Daniel-Tannure-Menandro-de-Freitas.pdf>. Acesso em:
18/09/2022.

GONÇALVES, L. Burndown chart: o guia oficial para qualquer scrum masters. Adapt methodology,
03/09/2020. Disponível em: <https://adaptmethodology.com/pt-pt/burndown-chart/>. Acesso
em: 18/09/2022.

HARTMAN, B. An introduction to planning poker. DZone, 11/09/2009. Disponível em:


<https://dzone.com/articles/introduction-planning-poker>. Acesso em: 18/09/2022.

SOUCEMAKING. Design Patterns. 2020. Disponível em:


<https://sourcemaking.com/design_patterns>. Acesso em: 18/09/2022.

Você também pode gostar