Skip to content

Latest commit

 

History

History
144 lines (94 loc) · 21.5 KB

Artigo.md

File metadata and controls

144 lines (94 loc) · 21.5 KB

Software

Software é um conjunto de instruções, dados ou programas usados para operar computadores e executar tarefas específicas. Ao contrário do hardware, que descreve os aspectos físicos de um computador, software é um termo genérico usado para se referir a aplicativos, scripts e programas executados em um dispositivo. O software pode ser considerado a parte variável de um computador e o hardware a parte invariável.

Existem basicamente três tipos de Software:

  • Software de Sistema para fornecer funções essenciais, como sistemas operacionais, gerenciamento de disco, utilitários, gerenciamento de hardware e outras necessidades operacionais.
  • Software de Programação para fornecer aos programadores ferramentas como editores de texto, compiladores, linkers, debuggers e outras ferramentas para criar código.
  • Software de Aplicativo (aplicativos ou apps) para ajudar os usuários a executar tarefas. Conjuntos de produtividade de Escritório, software de gerenciamento de dados, players de mídia e programas de segurança são exemplos. Os aplicativos também se referem a aplicativos da Web e móveis, como aqueles usados para fazer compras como Amazon, socializar como o Facebook ou postar fotos como o Instagram.

Um quarto tipo possível é o Software Incorporado (Embedded System Software). O software de sistemas embarcados, como também é conhecido, é usado para controlar máquinas e dispositivos que normalmente não são considerados computadores - redes de telecomunicações, carros, robôs industriais e muito mais. Esses dispositivos e seus softwares podem ser conectados como parte da Internet of Things(IoT).

Desenvolvimento de Software

O desenvolvimento de software é conduzido principalmente por programadores, engenheiros de software e desenvolvedores de software. Essas funções interagem e se sobrepõem, e a dinâmica entre elas varia muito entre departamentos e comunidades de desenvolvimento.

No nível mais baixo de programação, o código executável consiste em instruções de linguagem de máquina suportadas por um processador individual - geralmente uma unidade central de processamento (CPU) ou uma unidade de processamento gráfico (GPU). Uma linguagem de máquina consiste em grupos de valores binários, significando instruções do processador que alteram o estado do computador do estado anterior. Por exemplo, uma instrução pode alterar o valor armazenado em um determinado local de armazenamento no computador - um efeito que não é diretamente observável pelo usuário. Uma instrução também pode chamar uma das muitas operações de entrada ou saída, por exemplo, exibindo algum texto na tela do computador; causando mudanças de estado que devem estar visíveis para o usuário. O processador executa as instruções na ordem em que são fornecidas, a menos que seja instruído a "pular" para uma instrução diferente ou seja interrompido pelo sistema operacional.

A maioria dos softwares é escrita em linguagens de programação de alto nível. Eles são mais fáceis e mais eficientes para os programadores porque estão mais próximos das linguagens naturais do que das linguagens de máquina. Os idiomas de alto nível são traduzidos para o idioma da máquina usando um compilador ou interpretador ou uma combinação dos dois.

Exemplos de Software

A tabela abaixo apresenta exemplos de Softwares em diferentes categorias de uso

Software Exemplos
Antivirus AVG, Avast, Kaspersky
Audio/Music iTunes, Winamp, Rhythmbox
Communication Discord, Skype, Ventrilo
Databases SQLite, MySQL, PostgreSQL
Device Drivers Computer Drivers
Email Gmail, Outlook, YahooMail
Games Diablo, Warcraft, Tibia
Internet Browser Firefox, Google Chrome, Brave
Video Player VLC, Windows Media Player, Celluloid
Operating Systems Ubuntu, Debian, Android, Windows, iOS
Photo/Graphics Photoshop, GIMP, Krita, Gravit Designer
Presentation PowerPoint, LibreOffice Impress
Programming Language C, C++, Javascript, Python, PHP
Simulation SimCity, The Sims, Flight Simulator
Spreadsheet Microsoft Excel, LibreOffice Calc
Utility WinRar, CCleaner, ScreenCapture
Word Processor Microsoft Word, LibreOffice Writer

Breve Histórico

Um esboço (algoritmo) para o que teria sido o primeiro software foi escrito por Ada Lovelace no século 19, para o planejado Analytical Engine. Ela criou provas para mostrar como o mecanismo calcularia os números de Bernoulli. Por causa das provas e do algoritmo, ela é considerada a primeira programadora de computador.

A primeira teoria sobre software - antes da criação dos computadores como os conhecemos hoje - foi proposta por Alan Turing em seu ensaio "On Computable Numbers, with an Application to the Entscheidungsproblem".

Isso acabou levando à criação dos campos acadêmicos da ciência da computação e engenharia de software; Ambos os campos estudam o software e sua criação. A ciência da computação é o estudo teórico do computador e do software (o ensaio de Turing é um exemplo da ciência da computação), enquanto a engenharia de software é a aplicação da engenharia e o desenvolvimento de software.

Quando os primeiros computadores digitais apareceram no início dos anos 40, as instruções para fazê-los operar eram conectadas à máquina. Os profissionais rapidamente perceberam que esse design não era flexível e criaram a "arquitetura de programa armazenado", também conhecida como arquitetura von Neumann. Assim, a divisão entre "hardware" e "software" começou com a abstração sendo usada para lidar com a complexidade da computação.

As linguagens de programação começaram a aparecer no início dos anos 50 e esse também foi outro grande passo na abstração. As principais linguagens, como Fortran, ALGOL, PL/I e COBOL, foram lançadas no final dos anos 1950 e 1960 para lidar com problemas científicos, algorítmicos e comerciais, respectivamente. David Parnas introduziu o conceito-chave de modularidade e ocultação de informações em 1972 para ajudar os programadores a lidar com a crescente complexidade dos sistemas de software.

As origens do termo "engenharia de software" foram atribuídas a várias fontes. O termo "engenharia de software" apareceu em uma lista de serviços oferecidos por empresas na edição de junho de 1965 da COMPUTERS and AUTOMATION e foi usado mais formalmente na edição de agosto de 1966 da Communications of the ACM (Volume 9, número 8) “carta ao Membro da ACM” pelo presidente da ACM Anthony A. Oettinger.

Também está associado ao título de uma conferência da OTAN em 1968 pelo professor Friedrich L. Bauer, a primeira conferência sobre engenharia de software. Independentemente, Margaret Hamilton nomeou a disciplina "engenharia de software" durante as missões da Apollo para dar legitimidade ao que eles estavam fazendo. Na época, havia uma "crise de software". A 40ª Conferência Internacional de Engenharia de Software (ICSE 2018) comemora 50 anos de "Engenharia de Software" com as palestras das sessões plenárias de Frederick Brooks e Margaret Hamilton.

Em 1984, o Software Engineering Institute(SEI) foi estabelecido como um centro de pesquisa e desenvolvimento financiado pelo governo federal, com sede no campus da Universidade Carnegie Mellon, em Pittsburgh, Pensilvânia, Estados Unidos. Watts Humphrey fundou o SEI Software Process Program, destinado a entender e gerenciar o processo de engenharia de software. Os Níveis de Maturidade do Processo introduzidos se tornariam o CMMI-DEV (Capability Maturity Model Integration), que definiu como o governo dos EUA avalia as habilidades de uma equipe de desenvolvimento de software.

As práticas recomendadas modernas e geralmente aceitas para engenharia de software foram coletadas pelo subcomitê ISO/IEC JTC 1/SC 7 e publicadas como o Software Engineering Body of Knowledge(SWEBOK).

Engenharia de Software

Engenharia de software é a aplicação sistemática de abordagens de engenharia para o desenvolvimento de software.

As mais notáveis definições sobre o que é a Engenharia de Software incluem:

  • "A aplicação sistemática de conhecimentos científicos e tecnológicos, métodos e experiência ao design, implementação, teste e documentação de software". — The Bureau of Labor Statistics—IEEE Systems and software engineering
  • "A aplicação de uma abordagem sistemática, disciplinada e quantificável para o desenvolvimento, operação e manutenção de software". — IEEE Standard Glossary of Software Engineering Terminology
  • "Uma disciplina de engenharia que se preocupa com todos os aspectos da produção de software" — Ian Sommerville
  • "O estabelecimento e o uso de princípios sólidos de engenharia para obter software economicamente confiável e que funcione eficientemente em máquinas reais". — Fritz Bauer
  • "Um ramo da ciência da computação que lida com o design, implementação e manutenção de programas de computador complexos". — Merriam-Webster

Campos

A Engenharia de Software pode ser dividida nos seguintes campos:

  • Software Requirements: A engenharia de requisitos trata da obtenção, análise, especificação e validação de requisitos para software.
  • Software Design: O design de software trata do processo de definição da arquitetura, componentes, interfaces e outras características de um sistema ou componente. Isso também é chamado de arquitetura de software.
  • Software Development: Desenvolvimento de software, a principal atividade de construção de software: É a combinação de programação (também conhecida como codificação), verificação, teste de software e debugging. Um processo de desenvolvimento de software: É a definição, implementação, avaliação, medição, gerenciamento, mudança e melhoria do próprio processo de ciclo de vida do software. Ele usa muito o gerenciamento de configuração de software, que trata de controlar sistematicamente as alterações na configuração e manter a integridade e a rastreabilidade da configuração e do código ao longo do ciclo de vida do sistema. Os processos modernos usam software versioning.
  • Software Testing: É uma investigação técnica empírica realizada para fornecer às partes interessadas informações sobre a qualidade do produto ou serviço em teste, com diferentes abordagens, como unit testing e integration test. É um aspecto essencial da qualidade do software.
  • Software Maintenance: Manutenção de software refere-se às atividades necessárias para fornecer suporte econômico após o envio do produto de software.

Qualidade de Software

A qualidade do software mede se o software atende a seus requisitos, que são classificados como funcionais ou não funcionais.

  • Os requisitos funcionais identificam o que o software deve fazer. Os requisitos funcionais podem ser detalhes técnicos, manipulação e processamento de dados, cálculos ou qualquer outra função específica que especifique o que um aplicativo pretende realizar.
  • Os requisitos não funcionais, também conhecidos como "atributos de qualidade", determinam como o sistema deve funcionar. Os requisitos não funcionais incluem portabilidade, recuperação de desastres, segurança, privacidade e usabilidade.

O Software Testing detecta e resolve problemas técnicos no código-fonte do software e avalia a usabilidade, desempenho, segurança e compatibilidade geral do produto para garantir que ele atenda aos seus requisitos.

As dimensões da qualidade de software incluem:

  • Acessibilidade: O grau em que o software pode ser confortavelmente usado por diversos grupos de pessoas - incluindo indivíduos que exigem tecnologias adaptativas, como reconhecimento de voz e ampliadores de tela.
  • Compatibilidade: A adequação do software para uso em uma variedade de ambientes, como diferentes sistemas operacionais, dispositivos e navegadores.
  • Eficiência: A capacidade do software para ter um bom desempenho, sem desperdiçar energia, recursos, esforço, tempo ou dinheiro.
  • Funcionalidade: A capacidade do software de executar suas funções especificadas ou desejadas.
  • Instalabilidade: A capacidade do software de ser instalado em um ambiente especificado.
  • Localizability: A capacidade do software ser usado em vários idiomas, fusos horários, etc.
  • Manutenção: Com que facilidade o software pode ser modificado para adicionar recursos, melhorar recursos, corrigir bugs etc.
  • Desempenho: Quão rápido o software executa sob uma carga específica.
  • Portabilidade: A capacidade do software de ser facilmente transferido de um local para outro.
  • Confiabilidade: A capacidade do software de executar uma função necessária em condições específicas por um período específico, sem erros.
  • Escalabilidade: A medida da capacidade do software de aumentar ou diminuir o desempenho em resposta a mudanças nas demandas de processamento do software.
  • Segurança: a capacidade do software de proteger contra acesso não autorizado, invasão de privacidade, roubo, perda de dados, etc.
  • Testabilidade: A capacidade do software de ser facilmente testado.
  • Usabilidade: Quão fácil é usar o software.

Princípios de Design de Software

A construção de software é um trabalho de alta complexidade que pode envolver um grande número de pessoas, desenvolver software de qualidade é um grande desafio e para isso existem princípios que podem nos auxiliar a desenvolver melhores softwares e de mais fácil manutenção.

Abstração: Em engenharia de software e ciência da computação, a abstração é uma técnica para organizar a complexidade dos sistemas de computação. Ele funciona estabelecendo um nível de simplicidade no qual uma pessoa interage com o sistema, suprimindo os detalhes mais complexos abaixo do nível atual. O programador trabalha com uma interface idealizada (geralmente bem definida) e pode adicionar níveis adicionais de funcionalidade que, de outra forma, seriam muito complexos para lidar. Por exemplo, um programador que escreve código que envolve operações numéricas pode não estar interessado na maneira como os números são representados no hardware subjacente (por exemplo, se são inteiros de 16 ou 32 bits) e, onde esses detalhes foram suprimidos, pode-se dizer que foram abstraídos, deixando apenas números com os quais o programador pode trabalhar. Da mesma forma, uma tarefa de enviar uma mensagem de email pelos continentes seria extremamente complexa se o programador precisasse começar com um pedaço de cabo de fibra óptica e componentes básicos de hardware. Usando camadas de complexidade criadas para abstrair os cabos físicos e o layout da rede e apresentando ao programador um canal de dados virtual, essa tarefa é gerenciável.

A abstração pode ser aplicada ao controle ou aos dados: a abstração de controle é a abstração de ações, enquanto a abstração de dados é a das estruturas de dados.

Abstração de controle envolve o uso de sub-rotinas e abstrações de fluxo de controle A abstração de dados permite lidar com partes de dados de maneira significativa. Por exemplo, é a motivação básica por trás do tipo de dados.

A noção de um objeto na programação orientada a objetos pode ser vista como uma maneira de combinar abstrações de dados e código.

A mesma definição abstrata pode ser usada como uma interface comum para uma família de objetos com diferentes implementações e comportamentos, mas que compartilham o mesmo significado. O mecanismo de herança na programação orientada a objetos pode ser usado para definir uma classe abstrata como a interface comum.

A recomendação de que os programadores usem abstrações sempre que adequado, a fim de evitar duplicação (geralmente de código) é conhecida como princípio de abstração. O requisito de que uma linguagem de programação forneça abstrações adequadas também é chamado de princípio de abstração.

Por que usar abstração? Isso torna seu software reutilizável e permite que você e outros desenvolvedores se concentrem nos detalhes que realmente importam. Você realmente se importa exatamente como um objeto é gravado em um banco de dados? Não. Você tem coisas maiores para trabalhar.

Separation of Concerns: Na ciência da computação, a Separação de Preocupações(SoC) é um princípio de design para separar um programa de computador em seções distintas, de modo que cada seção aborda uma preocupação separada. Uma preocupação é um conjunto de informações que afeta o código de um programa de computador. Uma preocupação pode ser tão geral quanto "os detalhes do hardware de um aplicativo" ou tão específica quanto "o nome de qual classe instanciar". Um programa que incorpora bem o SoC é chamado de programa modular. A modularidade e, portanto, a separação de preocupações, são alcançadas encapsulando informações dentro de uma seção de código que possui uma interface bem definida. Encapsulamento é um meio de ocultar informações. Projetos em camadas em sistemas de informação são outra modalidade de separação de preocupações (por exemplo, camada de apresentação, camada de lógica de negócios, camada de acesso a dados, camada de persistência).

A separação de preocupações resulta em mais graus de liberdade para alguns aspectos do design, implantação ou uso do programa. Comum entre eles é o aumento da liberdade para simplificação e manutenção de código. Quando as preocupações são bem separadas, há mais oportunidades para atualização, reutilização e desenvolvimento independente de módulos. Ocultar os detalhes de implementação dos módulos atrás de uma interface permite melhorar ou modificar a seção de código de uma única preocupação sem precisar conhecer os detalhes de outras seções e sem fazer as alterações correspondentes nessas outras seções. Os módulos também podem expor versões diferentes de uma interface, o que aumenta a liberdade de atualizar um sistema complexo de maneira fragmentada, sem perda temporária de funcionalidade.

Por que usar SoC? Ao separar o código logicamente, você o torna mais confiável, portátil e flexível. Você reduz as dependências entre suas classes que tornam o debugging um pesadelo. O Tight Coupling pode dificultar significativamente sua vida.

YAGNI - You Aren't Going to Need It: É um princípio de extreme programming(XP) que afirma que um programador não deve adicionar funcionalidades até que seja considerado necessário. Ron Jeffries, co-fundador do XP, escreveu: "Sempre implemente as coisas quando você realmente precisa delas, nunca quando você apenas prevê que precisa delas". Outras formas da frase incluem "Você não precisará disso" e "Você não vai precisar".

KISS - Keep It Simple Stupid: É um princípio de design observado pela Marinha dos EUA em 1960. O princípio do KISS afirma que a maioria dos sistemas funciona melhor se forem mantidos simples e não complicados; portanto, a simplicidade deve ser uma meta fundamental no design e a complexidade desnecessária deve ser evitada. A frase foi associada ao engenheiro de aeronaves Kelly Johnson.

DRY - Don't Repeat Yourself: É um princípio do desenvolvimento de software destinado a reduzir a repetição de padrões de software, substituindo-o por abstrações ou usando a normalização de dados para evitar redundância.

O princípio DRY é declarado como "Todo conhecimento deve ter uma representação única, inequívoca e autoritativa dentro de um sistema". O princípio foi formulado por Andy Hunt e Dave Thomas em seu livro The Pragmatic Programmer. Eles o aplicam amplamente para incluir "esquemas de banco de dados, planos de teste, sistema de construção e até documentação". Quando o princípio DRY é aplicado com sucesso, uma modificação de qualquer elemento único de um sistema não requer uma alteração em outros elementos logicamente não relacionados. Além disso, os elementos logicamente relacionados são alterados de maneira previsível e uniforme e, portanto, são mantidos em sincronia.