Cap. 1 Introdução - Engenharia de Software Moderna
Cap. 1 Introdução - Engenharia de Software Moderna
Cap. 1 Introdução - Engenharia de Software Moderna
html
Veja também os cursos de extensão a distância Engenharia de Software Moderna (48 horas) e
Teste de Software (20 horas), oferecidos pelo DCC/ICEX/UFMG.
Neste primeiro capítulo, vamos definir e contextualizar o que é Engenharia de Software (Seção
1.1) e dar uma visão geral dos principais assuntos estudados nessa área da Computação (Seção
1.2). O objetivo é propiciar ao leitor uma visão horizontal da área de Engenharia de Software,
antes de nos aprofundarmos em temas específicos. Além disso, sendo Engenharia de Software
uma área bastante ampla, vamos caracterizar os tipos de sistemas de software que podem se
beneficiar das técnicas e conceitos apresentados neste livro (Seção 1.3). O objetivo é, logo no
início, evitar falsas expectativas em relação ao conteúdo do trabalho. Por fim, iremos
apresentar a estrutura e os assuntos tratados nos capítulos restantes do livro (Seção 1.4).
1 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
por meio de sistemas de comércio eletrônico, uma gama imensa de produtos, diretamente
para os consumidores. Software está também embarcado em diferentes dispositivos e
produtos de engenharia, incluindo automóveis, aviões, satélites, robôs, etc. Por fim, software
está contribuindo para renovar indústrias e serviços tradicionais, como telecomunicações,
transporte em grandes centros urbanos, hospedagem, lazer e publicidade.
Portanto, devido a sua relevância no nosso mundo, não é surpresa que exista uma área da
Computação destinada a investigar os desafios e propor soluções que permitam desenvolver
sistemas de software — principalmente aqueles mais complexos e de maior tamanho — de
forma produtiva e com qualidade. Essa área é chamada de Engenharia de Software.
Historicamente, a área surgiu no final da década de 60 do século passado. Nas duas décadas
anteriores, os primeiros computadores modernos foram projetados e começaram a ser usados
principalmente para resolução de problemas científicos. Ou seja, nessa época software não era
uma preocupação central, mas sim construir máquinas que pudessem executar alguns poucos
programas. Em resumo, computadores eram usados por poucos e para resolver apenas
problemas científicos.
2 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
Cientistas na conferência da OTAN de 1968 sobre Engenharia de Software. Reprodução gentilmente autorizada pelo
Prof. Robert McClure.
“ “O problema é que certas classes de sistemas estão colocando demandas sobre nós que
estão além das nossas capacidades e das teorias e métodos de projeto que conhecemos
no presente tempo. Em algumas aplicações não existe uma crise, como rotinas de
ordenação e folhas de pagamento, por exemplo. Porém, estamos tendo dificuldades
com grandes aplicações. Não podemos esperar que a produção de tais sistemas seja
fácil.”
3 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
por usuários, mas também para garantir que os sistemas continuem fáceis de manter e
entender, mesmo com o passar dos anos.
Daí a menção à bala de prata no título do ensaio. Diz a lenda que uma bala de prata é a única
maneira de matar um lobisomem, desde que usada em uma noite de lua cheia. Ou seja, por
causa das dificuldades essenciais, não podemos esperar soluções milagrosas em Engenharia de
Software, na forma de balas de prata. O interessante é que, mesmo conhecendo o ensaio de
Brooks, sempre surgem novas tecnologias que são vendidas como se fossem balas de prata.
2. Conformidade: pela sua natureza software tem que se adaptar ao seu ambiente, que
muda a todo momento no mundo moderno. Por exemplo, se as leis para recolhimento de
impostos mudam, normalmente espera-se que os sistemas sejam rapidamente adaptados
à nova legislação. Brooks comenta que isso não ocorre, por exemplo, na Física, pois as leis
da natureza não mudam de acordo com os caprichos dos homens.
As dificuldades (2), (3) e (4) são específicas de sistemas de software, isto é, elas não ocorrem
em outros produtos de Engenharia, pelo menos na mesma intensidade. Por exemplo, quando a
legislação ambiental muda, os fabricantes de automóveis têm anos para se conformar às novas
leis. Adicionalmente, carros não são alterados, pelo menos de forma essencial, com novas
4 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
funcionalidades, após serem vendidos. Por fim, um carro é um produto físico, com peso, altura,
largura, assentos, forma geométrica, etc., o que facilita sua avaliação e precificação por
consumidores finais.
1. Engenharia de Requisitos
2. Projeto de Software
3. Construção de Software
4. Testes de Software
5. Manutenção de Software
6. Gerência de Configuração
7. Gerência de Projetos
5 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
8. Processos de Software
9. Modelos de Software
No restante desta seção, vamos brevemente discutir e comentar sobre cada uma das 12 áreas
listadas acima. O nosso objetivo é propiciar ao leitor um panorama do conhecimento que se
adquiriu ao longo dos anos em Engenharia de Software e, assim, informá-lo sobre o que se
estuda nessa área.
Requisitos funcionais definem o que um sistema deve fazer; isto é, quais funcionalidades ou
serviços ele deve implementar.
Já os requisitos não-funcionais definem como um sistema deve operar, sob quais restrições e
com qual qualidade de serviço. São exemplos de requisitos não-funcionais: desempenho,
disponibilidade, tolerância a falhas, segurança, privacidade, interoperabilidade, capacidade,
manutenibilidade e usabilidade.
6 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
Por exemplo, durante o projeto de um sistema de home-banking, pode-se propor uma classe
para representar contas bancárias, como a seguinte:
class ContaBancaria {
private Cliente cliente;
private double saldo;
public double getSaldo() { ... }
public String getNomeCliente() { ... }
public String getExtrato (Date inicio) { ... }
...
}
Primeiro, é importante mencionar que a implementação acima é bem simples, pois o nosso
objetivo é didático, isto é, diferenciar projeto de software de sua implementação. Para atingir
esse objetivo, o importante é mencionar que ContaBancaria oferece uma interface para as
demais classes do sistema, na forma de três métodos públicos, que constituem a interface
provida pela classe. Por outro lado, ContaBancaria também depende de uma outra classe,
Cliente ; logo, a interface de Cliente é uma interface requerida por ContaBancaria . Muitas
vezes, interfaces requeridas são chamadas de dependências. Isto é, ContaBancaria possui uma
dependência para Cliente .
Quando o projeto é realizado em um nível mais alto e as unidades de código possuem maior
granularidade — são pacotes, por exemplo — ele é classificado como um projeto arquitetural.
Ou seja, arquitetura de software trata da organização de um sistema em um nível de
abstração mais alto do que aquele que envolve classes ou construções semelhantes.
7 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
Pelo menos três pontos podem ser comentados sobre testes, ainda neste capítulo de
Introdução.
Primeiro, existem diversos tipos de testes. Por exemplo, testes de unidade (quando se testa
uma pequena unidade do código, como uma classe), testes de integração (quando se testa
uma unidade de maior granularidade, como um conjunto de classes), testes de performance
(quando se submete o sistema a uma carga de processamento para verificar seu desempenho),
testes de usabilidade (quando o objetivo é verificar a usabilidade da interface do sistema), etc.
Segundo, testes podem ser usados tanto para verificação como para validação de sistemas.
Verificação tem como o objetivo garantir que um sistema atende à sua especificação. Já com
validação, o objetivo é garantir que um sistema atende às necessidades de seus clientes. A
diferença entre os conceitos só faz sentido porque pode ocorrer de a especificação de um
sistema não expressar as necessidades de seus clientes. Por exemplo, essa diferença pode ser
causada por um erro na fase de levantamento de requisitos; isto é, os desenvolvedores não
entenderam os requisitos do sistema ou o cliente não foi capaz de explicá-los precisamente.
Existem duas frases, muito usadas, que resumem as diferenças entre verificação e validação:
8 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
Assim, quando se realiza um teste de um método, para verificar se ele retorna o resultado
especificado, estamos realizando uma atividade de verificação. Por outro lado, quando
realizamos um teste funcional e de aceitação, ao lado do cliente, isto é, mostrando para ele os
resultados e funcionalidades do sistema, estamos realizando uma atividade de validação.
Terceiro, é importante definir e distinguir três conceitos relacionados a testes: defeitos, bugs e
falhas. Para ilustrar a diferença entre eles, suponha o seguinte código para calcular a área de
um círculo, dependendo de uma determinada condição:
if (condicao)
area = pi * raio * raio * raio;
Esse código possui um defeito, pois a área de um círculo é “pi vezes raio ao quadrado”, e não
ao cubo. Bug é um termo mais informal, usado com objetivos às vezes diversos. Mas o uso
mais comum é como sinônimo de defeito. Por fim, uma falha ocorre quando um código com
defeito for executado — por exemplo, a condição do if do programa acima for verdadeira —
e, com isso, levar o programa a apresentar um resultado incorreto. Portanto, nem todo defeito
ou bug ocasiona falhas, pois pode ser que o código defeituoso nunca seja executado.
Resumindo: código defeituoso é aquele que não está de acordo com a sua especificação. Se
esse código for executado e de fato levar o programa a apresentar um resultado incorreto,
dizemos que ocorreu uma falha.
Aprofundamento: Na literatura sobre testes, às vezes são mencionados os termos erro e falta
(fault). Quando isso ocorre, o significado é o mesmo daquele que adotamos para defeito neste
livro. Por exemplo, o IEEE Standard Glossary of Software Engineering Terminology (link) define
que falta é um “passo, processo ou definição de dados incorretos em um programa de
computador; os termos erro e bug são [também] usados para expressar esse significado”.
Resumindo, defeito, erro, falta e bug são sinônimos.
Mundo Real: Existe uma lista enorme de falhas de software, com consequências graves, tanto
em termos financeiros como de vidas humanas. Um dos exemplos mais famosos é a explosão
do foguete francês Ariane 5, lançado em 1996, de Kourou, na Guiana Francesa. Cerca de 30
segundos após o lançamento, o foguete explodiu devido a um comportamento inesperado de
um dos sistemas de bordo, causando um prejuízo de cerca de meio bilhão de dólares.
Interessante, o defeito que causou a falha no sistema de bordo do Ariane 5 foi bem específico,
relativamente simples e restrito a poucas linhas de código, implementadas na linguagem de
programação ADA, até hoje muito usada no desenvolvimento de software militar e espacial.
Essas linhas eram responsáveis pela conversão de um número real, em ponto flutuante, com 64
bits, para um número inteiro, com 16 bits. Durante os testes e, provavelmente, lançamentos
anteriores do foguete, essa conversão sempre foi bem sucedida: o número real sempre “cabia”
em um inteiro. Porém, na data da explosão, alguma situação nunca testada previamente exigiu
9 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
a conversão de um número maior do que o maior inteiro que pode ser representado em 16
bits. Com isso, gerou-se um resultado espúrio, que fez com que o sistema de controle do
foguete funcionasse de forma errática, causando a explosão.
Manutenção corretiva tem como objetivo corrigir bugs reportados por usuários ou outros
desenvolvedores.
Por sua vez, manutenção preventiva tem como objetivo corrigir bugs latentes no código, que
ainda não causaram falhas junto aos usuários do sistema.
Manutenção adaptativa tem como objetivo adaptar um sistema a uma mudança em seu
ambiente, incluindo tecnologia, legislação, regras de integração com outros sistemas ou
demandas de novos clientes. Como exemplos de manutenção adaptativa podemos citar:
10 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
Manutenção evolutiva é aquela realizada para incluir uma nova funcionalidade ou introduzir
aperfeiçoamentos importantes em funcionalidades existentes. Sistemas de software podem ser
usados por décadas exatamente porque eles sofrem manutenções evolutivas, que preservam o
seu valor para os clientes. Por exemplo, diversos sistemas bancários usados hoje em dia foram
criados nas décadas de 70 e 80, em linguagens como COBOL. No entanto, eles já sofreram
diversas evoluções e melhorias. Hoje, esses sistemas possuem interfaces Web e para celulares,
que se integram aos módulos principais, implementados há dezenas de anos.
No entanto, gerência de configuração é mais do que apenas usar um sistema como git. Ela
inclui a definição de um conjunto de políticas para gerenciar as diversas versões de um
sistema. Por exemplo, preocupa-se com o esquema usado para identificar as releases de um
software; isto é, as versões de um sistema que serão liberadas para seus clientes finais. Um
time de desenvolvedores pode definir que as releases de uma determinada biblioteca que eles
estão desenvolvendo serão identificadas no formato x.y.z, onde x, y e z são inteiros. Um
incremento em z ocorre quando se lança uma nova release com apenas correções de bugs
(normalmente, chamada de patch); um incremento em y ocorre quando se lança uma release
da biblioteca com pequenas funcionalidades (normalmente, chamada de versão minor); por
11 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
fim, um incremento em x ocorre quando se lança uma release com funcionalidades muito
diferentes daquelas da última release (normalmente, chamada de versão major). Esse esquema
de numeração de releases é conhecido como versionamento semântico.
Existe uma frase muito conhecida, também de Frederick Brooks, que captura uma
peculiaridade de projetos de software. Segundo Brooks:
Essa frase ficou tão famosa que ela é hoje conhecida como Lei de Brooks. Basicamente, esse
efeito acontece porque os novos desenvolvedores terão primeiro que entender e compreender
todo o sistema, sua arquitetura e seu projeto (design), antes de começarem a produzir código
útil. Além disso, equipes maiores exigem um maior esforço de comunicação e coordenação
para tomar e explicar decisões. Por exemplo, se um time tem 3 desenvolvedores (d1, d2, d3),
existem 3 canais de comunicação possíveis (d1-d2, d1-d3 e d2-d3); se ele cresce para 4
desenvolvedores, o número de canais duplica, para 6 canais. Se ele cresce para 10
desenvolvedores, passam a existir 45 canais de comunicação. Por isso, modernamente,
software é desenvolvido em times pequenos, com uma dezena de engenheiros, se tanto.
Tradução: Em português, a palavra projeto pode se referir tanto a design como a project. Por
exemplo, em uma subseção anterior introduzimos questões de projeto de software, isto é,
software design, tratando de conceitos como interfaces, dependências, arquitetura, etc. Na
presente seção, acabamos de discutir questões de gerência de projetos de software, isto é,
software project management, tais como prazos, contratos, Lei de Brooks, etc. No restante
deste livro, iremos traduzir apenas o uso mais comum em cada capítulo e manter o uso menos
12 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
Historicamente, existem dois grandes tipos de processos que podem ser adotados na
construção de sistemas de software:
Processos Waterfall foram os primeiros a serem propostos, ainda na década de 70, quando a
Engenharia de Software começava a ganhar envergadura. De forma compreensível, eles foram
inspirados nos processos usados em engenharias tradicionais, os quais são largamente
sequenciais, como ilustrado no exemplo do prédio, usado no parágrafo inicial desta seção.
Processos Waterfall foram muito usados até a década de 1990 e grande parte desse sucesso
deve-se a uma padronização lançada pelo Departamento de Defesa Norte-Americano, em
1985. Basicamente, eles estabeleceram que todo software comprado ou contratado pelo
Departamento de Defesa deveria ser construído usando Waterfall.
13 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
No entanto, processos Waterfall, a partir do final da década de 90, passaram a ser muito
criticados, devido aos atrasos e problemas recorrentes em projetos de software, que ocorriam
com frequência nessa época. O principal problema é que Waterfall pressupõe um
levantamento completo de requisitos, depois um projeto detalhado, depois uma
implementação completa, etc. Para só então validar o sistema com os usuários, o que pode
acontecer anos após o início do projeto. No entanto, nesse período, o mundo pode ter
mudado, bem como as necessidades dos clientes, que podem não mais precisar do sistema
que ajudaram a especificar anos antes. Assim, reunidos em uma cidade de Utah, Estados
Unidos, em fevereiro de 2001, um grupo de 17 Engenheiros de Software propôs um modo
alternativo para construção de software, que eles chamaram de Ágil — nome do manifesto que
eles produziram nessa reunião (link). Contrastando com processos Waterfall, a ideia de
processos ágeis é que um sistema deve ser construído de forma incremental e iterativa.
Pequenos incrementos de funcionalidade são produzidos, em intervalos de cerca de um mês e,
logo em seguida, validados pelos usuários. Uma vez que o incremento produzido seja
aprovado, o ciclo se repete.
Processos ágeis tiveram um profundo impacto na indústria de software. Hoje, eles são usados
pelas mais diferentes organizações que produzem software, desde pequenas empresas até as
grandes companhias da Internet. Diversos métodos que concretizam os princípios ágeis foram
propostos, tais como XP, Scrum, Kanban e Lean Development.
14 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
Frequentemente, modelos de software são baseados em notações gráficas. Por exemplo, UML
(Unified Modelling Language) é uma notação que define mais de uma dezena de diagramas
gráficos para representar propriedades estruturais e comportamentais de um sistema. Na
próxima figura, mostra-se um diagrama UML — chamado Diagrama de Classes — para o
exemplo de código usado na seção sobre Projeto de Software. Nesse diagrama, as caixas
retangulares representam classes do sistema, incluindo seus atributos e métodos. As setas são
usadas para denotar relacionamentos entre as classes. Existem editores para criar diagramas
UML, que podem ser usados, por exemplo, em um cenário de Engenharia Avante.
15 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
celulares, computadores, empresas de construção civil, etc., todos almejam e dizem que
possuem produtos de qualidade. Esse contexto não é diferente quando o produto é um
software. Segundo uma classificação proposta por Bertrand Meyer (link), qualidade de software
pode ser avaliada em duas dimensões: qualidade externa ou qualidade interna.
Qualidade externa considera fatores que podem ser aferidos sem analisar o código. Assim, a
qualidade externa de um software pode ser avaliada mesmo por usuários comuns, que não são
especialistas em Engenharia de Software. Como exemplo, temos os seguintes fatores (ou
atributos) de qualidade externa:
• Correção: o software atende à sua especificação? Nas situações normais, ele funciona
como esperado?
• Facilidade de Uso: o software possui uma interface amigável, mensagens de erro claras,
suporta mais de uma língua, etc? Pode ser também usado por pessoas com alguma
deficiência, como visual ou auditiva?
Por outro lado, qualidade interna considera propriedades e características relacionadas com a
implementação de um sistema. Portanto, a qualidade interna de um sistema somente pode ser
avaliada por um especialista em Engenharia de Software e não por usuários leigos. São
exemplos de fatores (ou atributos) de qualidade interna: modularidade, legibilidade do código,
manutenibilidade e testabilidade.
Para garantir qualidade de software, diversas estratégias podem ser usadas. Primeiro, métricas
podem ser usadas para acompanhar o desenvolvimento de um produto de software, incluindo
métricas de código fonte e métricas de processo. Um exemplo de métrica de código é o
número de linhas de um programa, que pode ser usado para dar uma ideia de seu tamanho.
Métricas de processo incluem, por exemplo, o número de defeitos reportados em produção
por usuários finais em um certo intervalo de tempo.
16 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
Existem ainda práticas que podem ser adotadas para garantir a produção de software com
qualidade. Modernamente, por exemplo, diversas organizações usam revisões de código, isto
é, o código produzido por um desenvolvedor somente entra em produção depois de ser
revisado e inspecionado por um outro desenvolvedor do time. O objetivo é detectar bugs
antecipadamente, antes de o sistema entrar em produção. Além disso, revisões de código
servem para garantir a qualidade interna do código — isto é, sua manutenibilidade,
legibilidade, modularidade, etc. — e para disseminar boas práticas de Engenharia de Software
entre os membros de um time de desenvolvimento.
17 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
Por fim, mas muito atual e relevante, existem questionamentos sobre o papel e a
responsabilidade ética dos profissionais formados em Computação, em uma sociedade na
qual os relacionamentos humanos são cada vez mais mediados por algoritmos e sistemas de
software. Neste sentido, as principais sociedades científicas da área possuem códigos que
procuram ajudar os profissionais de Computação — não necessariamente apenas Engenheiros
de Software — a exercer seu ofício de forma ética. Como exemplos, temos o Código de Ética
da ACM (link) e da IEEE Computer Society (link). Esse último é interessante porque é específico
para a prática de Engenharia de Software. Por exemplo, ele recomenda que:
No Brasil, existe o Código de Ética da Sociedade Brasileira de Computação (SBC), que por ser
sintético e bastante claro resolvemos reproduzir a seguir:
Art. 1o: Contribuir para o bem-estar social, promovendo, sempre que possível, a
inclusão de todos os setores da sociedade.
“ Art. 4o: Atuar dentro dos limites de sua competência profissional e orientar-se por
elevado espírito público.
Art. 5o: Guardar sigilo profissional das informações a que tiver acesso em decorrência
das atividades exercidas.
Art. 6o: Conduzir as atividades profissionais sem discriminação, seja de raça, sexo,
religião, nacionalidade, cor da pele, idade, estado civil ou qualquer outra condição
humana.
18 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
Art. 9o: Pautar sua relação com os colegas de profissão nos princípios de consideração,
respeito, apreço, solidariedade e da harmonia da classe.
Art. 10o: Não praticar atos que possam comprometer a honra, a dignidade e
privacidade de qualquer pessoa.
Mundo Real: O Stack Overflow realiza anualmente uma pesquisa com usuários da plataforma
de perguntas e respostas. Em 2018, esse survey foi respondido por mais de 100 mil
desenvolvedores, dos mais variados países. Dentre as perguntas, um grupo se referia a
questões éticas (link). Uma delas perguntava se desenvolvedores têm a obrigação de
considerar as implicações éticas do código que produzem. Quase 80% dos respondentes
disseram que sim. Uma outra pergunta foi a seguinte: Quem, em última análise, é responsável
por um código que colabora para um comportamento antiético? Nesse caso, 57,5%
responderam que é a alta gerência da organização ou empresa, enquanto 23% disseram que é
o próprio desenvolvedor. Quando perguntados se concordariam em escrever um código com
dúvidas éticas, 58% responderam que não e 37% responderam que dependeria do código
requisitado.
Para discutir um caso mais concreto, em economia existe uma preocupação frequente com os
custos de oportunidade de uma decisão. Isto é, toda decisão possui um custo de
oportunidade, que são as oportunidades preteridas quando se descartou uma das decisões
alternativas. Em outras palavras, quando se descarta uma decisão Y e, no seu lugar, toma-se
uma decisão X, os eventuais benefícios de Y passaram a ser oportunidades perdidas. Por
exemplo, suponha que o principal sistema de sua empresa tenha uma lista de bugs B para ser
19 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
corrigida. Existem benefícios em corrigir B? Claro, isso vai deixar os clientes atuais mais
satisfeitos; eles não vão pensar em migrar para sistemas concorrentes, etc. Porém, existe
também um custo de oportunidade nessa decisão. Especificamente, em vez de corrigir B, a
empresa poderia investir em novas funcionalidades F, que poderiam ajudar a ampliar a base de
clientes. O que é melhor? Corrigir os bugs ou implementar novas funcionalidades? No fundo,
essa é uma decisão econômica.
Uma classificação proposta por Bertrand Meyer (link) ajuda a distinguir e entender os
diferentes sistemas de software que podem ser construídos e os princípios de Engenharia de
Software mais recomendados para cada uma das categorias propostas. Segundo essa
classificação, existem três tipos principais de software:
• Sistemas A (Acute)
• Sistemas B (Business)
• Sistemas C (Casuais)
Sistemas C (Casuais) não sofrem pressão para terem níveis altos de qualidade. São sistemas
que podem ter alguns bugs, os quais não vão comprometer fundamentalmente o seu
funcionamento. Como exemplo, podemos citar um script feito para um trabalho acadêmico,
um programa de conversão de dados (que vai ser usado uma única vez, para converter os
dados para um novo banco de dados que está sendo comprado pela empresa), um sistema
para controlar os sócios do Diretório Acadêmico da universidade, um sistema para gerenciar as
salas disponíveis para reuniões em uma empresa, etc. Por isso, Sistemas C não precisam ter
níveis altos de qualidade interna; por exemplo, podem ter parte do código duplicado. Também
não precisam ter desempenho ou uma boa interface. Em geral, são desenvolvidos por 1-2
programadores; ou seja, são sistemas pequenos e não críticos. Por tudo isso, eles não se
beneficiam tanto das práticas, técnicas e processos estudados neste livro. Pelo contrário, no
caso de Sistemas C, o maior risco é over-engineering, ou seja, o uso de recursos mais
sofisticados em um contexto que não demanda tanta preocupação. Como se diz
20 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
coloquialmente, Engenharia de Software nesse contexto equivale a “usar uma bala de canhão
para matar formigas”.
No outro extremo, temos os Sistemas A (de acute, ou de missão crítica). São sistemas nos quais
qualquer falha pode causar um imenso prejuízo, incluindo a perda de vidas humanas. São
sistemas para controlar um carro autônomo, uma usina nuclear, um avião, os equipamentos de
uma UTI, um trem de metrô, etc. O exemplo do sistema de controle do foguete Ariane 5, usado
na seção sobre Testes de Software, é um exemplo de Sistema A. O desenvolvimento desses
sistemas deve ser feito de acordo com processos rígidos, incluindo rigorosa revisão de código
e certificação por organizações externas. É comum exigir redundância não apenas em
hardware, mas também no próprio software. Por exemplo, o sistema roda de forma paralela
em duas máquinas e uma decisão somente é tomada caso ambas as instâncias cheguem ao
mesmo resultado. Por fim, sistemas A muitas vezes são especificados em uma linguagem
formal, baseada em teoria de conjuntos ou lógica.
Aviso: Por tudo que foi afirmado no parágrafo anterior, sistemas A (isto é, de missão crítica)
não serão tratados neste livro.
Sobram os sistemas B (Business), que são exatamente aqueles que vão se beneficiar dos
conceitos estudados neste livro. Esses sistemas incluem as mais variadas aplicações
corporativas (financeiras, recursos humanos, logística, vendas, contabilidade, etc.), sistemas
Web dos mais variados tipos, desde sistemas com poucas páginas até grandes redes sociais ou
sistemas de busca. Outras aplicações incluem bibliotecas e frameworks de software, aplicações
de uso geral (como editores de texto, planilhas, editores de imagens, etc.) e sistemas de
software básico (como compiladores, gerenciadores de bancos de dados, IDEs, etc.). Nesses
sistemas, os princípios e práticas de Engenharia de Software estudados neste livro podem
contribuir com dois benefícios principais: (1) eles podem tornar mais produtivo o
desenvolvimento de Sistemas B; (2) eles podem propiciar a construção de Sistemas B com
melhor qualidade, tanto interna (por exemplo, sistemas mais fáceis de serem mantidos) como
externa (por exemplo, sistemas com menor quantidade de bugs em produção).
Capítulo 3: Requisitos, que inicia com uma discussão sobre a importância de requisitos e os
21 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
Capítulo 4: Modelos, que tem foco no uso de UML para elaboração de esboços (sketches) de
software. Modernamente, concordamos que UML não é mais usada para os fins que ela foi
concebida na década de 90, ou seja, para criação de modelos detalhados de software.
Praticamente, não existem mais casos de empresas que investem meses — ou anos — na
elaboração de diagramas gráficos antes de começar a implementar qualquer linha de código.
Porém, se não tratássemos de UML no livro ficaríamos com a sensação de que “após o banho,
jogamos o bebê fora, junto com a água da bacia”. Se por um lado não faz sentido estudar
todos os diagramas da UML em detalhes, por outro lado existem elementos importantes em
alguns desses diagramas. Além disso, desenvolvedores, com frequência, elaboram pequenos
esboços de software, por exemplo, para comunicar e discutir ideias de design com outros
desenvolvedores. Assim, conhecimento básico de UML pode ser interessante para desenhar
esses esboços, inclusive para evitar a criação de uma nova linguagem de modelagem.
Capítulo 5: Princípios de Projeto, que trata de dois temas que devem ser do conhecimento
de todo projetista de software. São eles: (1) propriedades (ou considerações) importantes em
projeto de software, incluindo integridade conceitual, ocultamento de informação, coesão e
acoplamento; (2) princípios de projeto, os quais constituem recomendações mais específicas
para construção de bons projetos de software, tais como responsabilidade única, prefira
composição a herança, aberto/fechado, Demeter, etc.
Capítulo 7: Arquitetura, que inicia com uma apresentação e discussão sobre Arquitetura de
Software. O objetivo é deixar claro que arquitetura deve ser vista como projeto em alto nível,
envolvendo pacotes, camadas ou serviços, em vez de classes individuais. Em seguida,
discutimos cinco padrões arquiteturais: arquitetura em camadas (incluindo 3-camadas),
arquitetura MVC (incluindo single-page applications), microsserviços, arquiteturas orientadas
22 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
por filas de mensagens e arquiteturas publish/subscribe. Essas duas últimas são comuns na
construção de sistemas distribuídos fracamente acoplados. Por fim, apresentamos um anti-
padrão arquitetural, chamado big ball of mud, que é um termo usado para designar sistemas
sem organização arquitetural. Esses sistemas poderiam até possuir uma arquitetura no seu
início, mas depois o projeto arquitetural deles foi sendo abandonado, transformando-os em
um espaguete de dependências entre os seus módulos.
Capítulo 8: Testes, com ênfase em testes de unidade, usando frameworks como JUnit. O
capítulo inclui dezenas de exemplos de testes de unidade e discute diversos aspectos desses
testes. Por exemplo, discutimos bons princípios para escrita de testes de unidade e também
test smells, isto é, padrões de testes que não são recomendados. Em seguida, tratamos de
testabilidade, isto é, discutimos a importância de escrever código que possa ser facilmente
testado. O capítulo inclui uma seção inteira sobre mocks e stubs, os quais são objetos que
viabilizam o teste de unidade de código com dependências mais complexas, como
dependências para bancos de dados e outros sistemas externos. Finalizada a discussão sobre
testes de unidade, também discutimos, porém de forma mais resumida, dois outros tipos de
testes: testes de integração e testes de sistema. Esses testes verificam propriedades de
unidades maiores de código, como as classes responsáveis por um determinado serviço ou
funcionalidade (testes de integração) ou mesmo todas as classes de um sistema (testes de
sistema). Para terminar, incluímos uma discussão sobre outros testes, como testes caixa-preta
(ou testes funcionais), testes caixa-branca (ou testes estruturais), testes de aceitação e também
testes para verificar requisitos não-funcionais, como desempenho, falhas e usabilidade.
Capítulo 10: DevOps, que é um movimento que tenta aproximar os times de desenvolvimento
(Devs) e de operações (Ops) de uma empresa desenvolvedora de software. O time de
operações é responsável por manter o software em funcionamento, sendo formado por
administradores de rede, administradores de bancos de dados, técnicos de suporte, etc. Em
uma cultura tradicional, esses dois times tendem a atuar de forma independente. Ou seja, o
time de desenvolvimento desenvolve o sistema e depois “joga ele por cima da parede” (throw
it over the wall) que separa o departamento de desenvolvimento do departamento de
operações. Assim, os dois times não conversam nem no momento da “passagem de bastão”
(hand-off) de uma área para outra. Para resolver esse problema, DevOps propõe uma interação
23 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
constante entre as áreas Devs e Ops, desde os primeiros dias do desenvolvimento. O objetivo é
acelerar a entrada em produção de um sistema. Além de uma introdução a DevOps, vamos
estudar algumas práticas essenciais quando uma empresa adota essa cultura, incluindo
Controle de Versões, Integração Contínua e Deployment/Entrega Contínua.
Apêndice A: Git, que apresenta e mostra exemplos de uso dos principais comandos do
sistema git. Atualmente, é inconcebível não usar controle de versões em qualquer sistema,
mesmo naqueles mais simples. Por isso, fizemos questão de acrescentar esse apêndice no livro.
Git é o sistema de controle de versões mais usado atualmente.
Bibliografia �
Pierre Bourque, Richard Fairley. Guide to the Software Engineering Body of Knowledge, Version
3.0, IEEE Computer Society, 2014.
Armando Fox, David Patterson. Construindo Software como Serviço: Uma Abordagem Ágil
Usando Computação em Nuvem. Strawberry Canyon LLC. 1a edição, 2014.
Frederick Brooks. O Mítico Homem-Mês. Ensaios Sobre Engenharia de Software. Alta Books, 1a
edição, 2018.
Exercícios de Fixação �
1. Segundo Frederick Brooks, desenvolvimento de software enfrenta dificuldades essenciais
(para as quais não há bala de prata) e acidentais (para as quais existe uma solução melhor). Dê
um exemplo de dificuldade acidental que já tenha experimentado ao desenvolver programas,
mesmo que pequenos. Sugestão: elas podem estar relacionadas a ferramentas que tenha
usado, como compiladores, IDEs, bancos de dados, sistemas operacionais, etc.
3. Explique por que testes podem ser considerados tanto uma atividade de verificação como
de validação de software. Qual tipo de teste é mais adequado se o objetivo for verificação?
Qual tipo de teste é mais adequado se o objetivo for validar um sistema de software?
5. Suponha um programa que tenha uma única entrada: um inteiro de 64 bits. Em um teste
exaustivo, temos que testar esse programa com todos os possíveis inteiros (logo, 264). Se cada
teste levar 1 nanossegundo (10-9 segundos), quanto tempo levará esse teste exaustivo?
6. Se considerarmos o contexto histórico, por que foi natural que os primeiros processos de
desenvolvimento de software tivessem características sequenciais e fossem baseados em
planejamento e documentação detalhados?
7. Alguns estudos mostram que os custos com manutenção e evolução podem alcançar 80%
ou mais dos custos totais alocados a um sistema de software, durante todo o seu ciclo de vida.
24 of 25 02/09/2022 07:40
Cap. 1: Introdução – Engenharia de Software Moderna https://engsoftmoderna.info/cap1.html
11. Em 2015, descobriu-se que mais de 11 milhões de carros da Volkswagen emitiam poluentes
dentro das normas legais apenas quando eles estavam sendo testados em um laboratório de
certificação. Fora do laboratório, os carros emitiam mais poluentes, para melhorar o
desempenho. Ou seja, o código incluía uma estrutura de decisão como a seguinte (meramente
Direitos autorais
ilustrativa, reservados.
para Versão
fins deste para uso pessoal. Para reportar quaisquer erros, incluindo pequenos erros de
exercício):
ortografia, use este formulário.
if "Carro sendo testado em um laboratório"
"Emita poluentes dentro das normas"
else
"Emita poluentes fora das normas"
O que você faria se seu chefe pedisse para escrever um if como o acima? Para mais
informações sobre esse episódio, consulte essa página da Wikipedia.
Modo noturno
25 of 25 02/09/2022 07:40