A ideia do reuso é evitar retrabalho no desenvolvimento de um novo projeto, sempre levando em consideração trabalhos anteriores, fazendo com que soluções previamente desenvolvidas sejam aproveitadas e implementadas em novos contextos.

Neste artigo, apresentaremos o conceito de reutilização de software, principais benefícios e desafios encontrados na prática do reuso, alguns tipos de reutilização e seu impacto no contexto da Engenharia de Software.

O desenvolvimento de sistemas de informação é tipicamente conhecido como um processo caro e lento. A pressão que acompanha esse processo, bem como a busca constante por redução significativa de custos e alcance de ganhos incomparáveis em qualidade do produto, associados à redução do tempo de desenvolvimento fazem com que o resultado final e a excelência fiquem aquém do desejado. Uma possível solução, que pode não resolver todos os problemas, mas pode ajudar a lidar com esse processo é a reutilização.

A reutilização de software se baseia no uso de conceitos, produtos ou soluções previamente elaboradas ou adquiridas para criação de um novo software, visando melhorar significativamente a qualidade e a produtividade. Reusar um produto significa poder reusar partes de um sistema desenvolvido anteriormente como: especificações, módulos de um projeto, arquitetura e código fonte. A principal motivação para a reutilização está relacionada ao aumento dos níveis de qualidade e produtividade no desenvolvimento de software. Neste sentido, este artigo apresentará o conceito de reutilização de software, principais benefícios e desafios encontrados na prática do reuso, alguns tipos de reutilização e seu impacto no contexto da Engenharia de Software.

No contexto social, a imitação ou reutilização de ideias são vistas como falta de originalidade, porém em desenvolvimento de software isso pode resultar em um aumento significativo na produtividade e uma redução considerável no tempo de execução das tarefas.

As primeiras ideias sobre reutilização de software são do ano de 1968, quando Doug McIlroy mostrou a sua motivação por software que funcionasse como "Circuitos Integrados" (CI) e que estes pudessem ser fabricados em massa. Além disso, ele examinou os tipos de variabilidade necessárias aos CIs e os possíveis tipos de CIs que poderiam ser padronizados desta forma. A visão de McIlroy era baseada na indústria de componentes eletrônicos que podiam ser selecionados em catálogos de diferentes fabricantes, apresentando propriedades configuráveis e diferentes níveis de confiabilidade.

Apesar de os primeiros conceitos sobre reutilização de software terem sido idealizados no final da década de 1960, eles não receberam muita atenção da indústria e das universidades até os anos 80, quando a complexidade dos sistemas começou a aumentar e as empresas foram forçadas a procurar por métodos mais eficientes de construção de sistemas para refletir as necessidades do mercado.

Em 1980 foi estabelecido o primeiro projeto de pesquisa universitário no tema de reutilização, na Universidade da Califórnia, coordenado por Peter Freeman. Atualmente, existem duas principais conferências sobre reutilização, a ICSR – International Conference on Software Reuse e o SSR – Symposium on Software Reusability.

É notório que a reutilização, quando feita de forma intencional, planejada e controlada, os benefícios alcançados são relevantes. Redução de custos e esforço, melhoria de qualidade, potencial para abranger o leque de produtos, atingir novos mercados, ganhar espaço da concorrência são alguns dos principais chamarizes da reutilização. Tudo isso só é possível, pois a técnica simplifica a tarefa de aquisição de conhecimento. Diversos estudos mostram que muito do software que estamos começando a construir já foi feito e que apenas algo em torno de 15% dele é realmente a contribuição do nosso negócio. Todavia, embora todos acreditem nos benefícios dessa técnica, a reutilização ainda não é uma prática frequente.

Reutilização

A reutilização de software se baseia no uso de conceitos, produtos ou soluções previamente elaboradas ou adquiridas para criação de um novo software, visando melhorar significativamente a qualidade e a produtividade. Reusar um produto significa poder reusar partes de um sistema desenvolvido anteriormente como: especificações, módulos de um projeto, arquitetura e código fonte. É a reaplicação de informações e artefatos de um sistema já definido, em outros sistemas semelhantes. O termo reuso pode ser considerado uma denominação genérica para uma série de técnicas utilizadas, que vão desde a etapa de modelagem de um projeto até a implementação.

A principal motivação para a reutilização está relacionada ao aumento dos níveis de qualidade e produtividade no desenvolvimento de software. O aumento de qualidade é uma consequência da reutilização de componentes que foram previamente documentados, testados e aprovados. O aumento da produtividade é resultado de uma redução no tempo de desenvolvimento, evitando a reconstrução de partes do sistema que já existem.

A reutilização pode ser introduzida em diferentes fases e níveis do desenvolvimento de software: requisitos, design, código. É mais comum a reutilização de porções de código, design e testes, do que a reutilização de requisitos. A reutilização em fases com maior nível de abstração aumenta os benefícios da mesma e facilita a reutilização em fases mais avançadas do ciclo de vida do produto. Embora já se tenha chegado a essa conclusão, a reutilização de requisitos tem merecido pouca atenção dos investigadores. É necessário mobilizar o estabelecimento de um processo gradativo e coordenado de reutilização, não só no código, mas em todo o processo de desenvolvimento de software.

Atualmente existem várias técnicas de reuso como frameworks, arquiteturas orientadas a serviços (SOA), engenharia de software baseada em componentes, entre outras.

Fases iniciais do desenvolvimento de software voltados à reutilização

Análise do Domínio

A análise do domínio consiste em estudar o domínio de forma a identificar, formalizar e classificar as características elementares (objeto, regras e limitações). É mais fácil reutilizar componentes numa aplicação que seja do mesmo domínio da que foi originalmente desenvolvida por refletirem os mesmos conceitos e relações.

Uma das maiores dificuldades da licitação de requisitos é a falta de compreensão do domínio. Essa fase é facilitada quando se tem o conhecimento do domínio da aplicação em um formato reutilizável.

O custo da investigação inicial para analisar e formalizar um domínio, segundo os autores Loucopoulos e Karakostas (1995), é rapidamente amortizado com o aumento da produtividade e qualidade do projeto de software onde são reutilizados.

Engenharia de Requisitos

A reutilização de requisitos é o processo de eliciar, analisar, e gerir requisitos com um certo nível de abstração, de tal forma que eles sejam reutilizados em novos sistemas.

Atualmente, a reutilização de requisitos é praticada informalmente pelos engenheiros de requisitos, que especificam novos requisitos baseando-se em produtos idênticos desenvolvidos anteriormente. A sua experiência ajuda-os a reutilizar informalmente os requisitos. Embora amplamente praticada, não existe uma aproximação sistemática que aumentaria os benefícios em grande escala.

Os autores Kotonya e Sommerville (1998) afirmam que 50% dos requisitos normalmente são os mesmos para sistemas e domínios semelhantes. O fato de os sistemas serem diferentes conceitualmente e de terem diferentes stakeholders não significa que não têm requisitos comuns.

Existem muitas situações onde é possível fazer a reutilização de requisitos:

  • Requisitos relativos ao domínio de aplicação. Muitos requisitos não dizem respeito a funcionalidades do sistema, mas especificam objetos, regras e limitações do domínio.
  • Requisitos que especificam características da interface do utilizador podem ser reutilizados para todos os sistemas da organização. Faz todo o sentido a existência de consistência na aparência da interface. Os erros que os utilizadores cometem diminuem quando mudam de um sistema para outro.
  • Requisitos que refletem as políticas da empresa, como políticas de segurança, podem ser reutilizados em todos os sistemas.

Para que a reutilização seja possível, os artefatos precisam ser construídos e armazenados de tal forma que quando precisarmos podemos facilmente ter acesso a eles. Sendo assim, as atividades envolvidas na reutilização de requisitos encontram-se divididas em dois grandes processos: desenvolvimento para reuso, que é o processo de construção dos artefatos, e desenvolvimento com reuso, que se caracteriza pelo processo de utilização efetiva dos artefatos reutilizáveis no desenvolvimento de novos sistemas ou na atualização de sistemas existentes.

Desenvolvimento para reuso em três passos

Um dos processos mais críticos da reutilização é a aquisição de componentes reutilizáveis. Tal processo envolve três questões importantes, são elas:

  1. Definir as propriedades que caracterizam um componente reutilizável;
  2. Determinar como se constrói esse tipo de componente com as propriedades definidas;
  3. Inserir o novo componente no repositório levando-se em conta os mecanismos de classificação do mesmo.

Passo 1: Identificando componentes reutilizáveis

Essa identificação é feita recorrendo-se a várias técnicas, como:

  • Análise do domínio, que consiste na identificação de objetos, regras e limitações comuns a sistemas semelhantes. A análise do domínio e a de requisitos são semelhantes; a diferença reside no fato da primeira considerar requisitos de várias aplicações e não apenas de uma em particular. Dessa forma a licitação de requisitos pode utilizar os resultados da análise do domínio e poupar muito esforço.
  • Engenharia Reversa, que consiste em analisar um sistema de forma que seja possível identificar os seus componentes e relações, criando representações desse sistema em um nível mais alto de abstração. Baseia-se na obtenção de informações de alto nível (especificações) a partir de informações de baixo nível (código). O resultado dessa técnica é um modelo de requisitos que pode ser utilizado na licitação de requisitos de outros sistemas.
  • Experiência, que nada mais é senão a habilidade de reutilizar requisitos. Essa estratégia, comumente praticada por analistas experientes, faz toda a diferença no processo de identificação de componentes reutilizáveis.

Uma vez identificados os artefatos, é necessário proceder à sua compreensão e representação em um formalismo que reflita a sua funcionalidade e semântica.

Passo 2: Generalização

Um artefato deve ser generalizado para aumentar a sua reutilização, ou seja, o nome do componente precisa ser generalizado de forma a não refletir a aplicação para a qual foi originalmente desenvolvida. É também necessário adicionar operações que fornecem funcionalidades extras ao componente, e remover aqueles que são específicos da aplicação original.

Passo 3: Classificação

Antes de armazenar um artefato em um repositório, ele deve ser classificado (indexado) numa taxionomia de conceitos baseada em suas propriedades. Essa classificação determina o sucesso da pesquisa. Em outras palavras, a recuperação do artefato desejado é satisfatória. A classificação normalmente é feita baseando-se em hierarquias ou características. A primeira faz uma classificação geral dos componentes e refina-os sucessivamente de forma a permitir a pesquisa de artefatos através da hierarquia de abstrações. A segunda identifica as características mais importantes do componente que serão utilizadas posteriormente.

A classificação hierárquica é usada em domínios bem estabelecidos, com vocabulários bem definidos e conhecidos e com definições e semânticas geralmente aceitas. Nos repositórios é utilizado esse tipo de classificação por domínios e subdomínios.

A classificação por características [Prieto-Díaz] é mais flexível e aplicável a domínios dinâmicos e em expansão. Permite classificar um artefato segundo vários pontos de vista denominados facetas. Cada faceta corresponde a uma característica relevante que identifica a entidade classificada e é representada por um conjunto de termos chamado espaço de termos.

Existem ainda outras formas de classificação, como o clustering (que agrupa os conceitos semelhantes), a indexação manual e automática, as bases de conhecimento, dentre outras. A documentação associada aos componentes reutilizados é pré-requisito para todo o processo.

Desenvolvimento com reuso em três passos

Da mesma forma que devemos ter algumas preocupações ao efetuar o desenvolvimento para reuso, o mesmo deve ser feito ao se desenvolver softwares com reuso. Vejamos agora alguns passos essenciais nesse processo.

Passo 1: Pesquisa e Recuperação

A reutilização de um artefato inicia-se pela pesquisa e recuperação de um artefato que satisfaça o requisito do analista ou desenvolvedor. Após a seleção dos artefatos é necessário proceder ao refinamento dos mais aceitáveis para a resolução do problema. Esse passo requer informação que permita estabelecer a relação entre o candidato à recuperação (retrieved) e o desejado.

Passo 2: Adaptação

Nem sempre o artefato pode ser utilizado como está no momento (AS-IS). Muitas vezes é necessário proceder a sua modificação ou adaptação para que seja possível encaixar no problema. Quando isso acontece, esse novo componente deve ser disponibilizado para novas reutilizações. Esse passo requer informação acerca da estrutura do componente e da relação com outros artefatos.

Saiba mais sobre Engenharia de Software:
  • Engenharia de Software para programadores: Ter boas noções sobre engenharia de Software pode alavancar muito sua carreira e a sua forma de programar. Descubra nesse guia tudo o que um programador precisa saber sobre a ciência que existe por trás dos códigos.
  • Guia Completo de Gestão de Projeto: Neste guia você encontrará o conteúdo que precisa para saber como gerenciar projetos de software. Confira abaixo a sequência de posts que te guiarão do básico ao avançado em Gestão de Projetos.
  • Guia Completo de Testes de Software: Neste guia completo você encontrará diversos artigos e vídeos que podem ser usados ao longo dos seus estudos sobre Testes de Software, abordando diversas técnica e ferramentas.
  • Guia Completo de Scrum: Com o aumento das exigências dos clientes e prazos cada vez mais curtos, encontrar opções para possibilitar o projeto, implementação e implantação de um sistema com mais qualidade e em menos tempo é fundamental.

Passo 3: Composição

A composição de um componente consiste na ligação de vários componentes reutilizáveis com o objetivo de construir um artefato com maior complexidade. Essa ligação pode ser horizontal, ou seja, componentes estão no mesmo nível de abstração (ex.: ligação entre o componente Cliente e o componente Produto para construir o componente Venda de Produto), ou vertical que consiste na ligação de componentes de baixo nível para a implementação de componentes de alto nível (ex.: uma estrutura Lista pode ser utilizada para implementar uma estrutura grafo). Finalmente, o artefato é integrado ao projeto em desenvolvimento. A reutilização só é efetiva (alta precisão) e eficiente (baixo tempo de pesquisa) se todas as etapas forem bem executadas.

Tipos de Reuso

No processo de desenvolvimento de um sistema, pode se aplicar o reuso de software em vários momentos. Existe a possibilidade de se reusar ideias, especificações, projetos, códigos-fonte e outros produtos (artefatos) nas diversas fases do processo de desenvolvimento. A Figura 1 ilustra alguns dos tipos de reuso possíveis.

Tipos de Reuso
Figura 1. Tipos de Reuso

Reuso Vertical

Reuso vertical é o que ocorre dentro de um mesmo domínio de aplicação. O objetivo é derivar um modelo genérico para ser usados dentro de um único domínio de aplicação na criação de novos sistemas. Este tipo de reuso é o que ocorre em fábricas de software.

Reuso Horizontal

O reuso horizontal tem como meta a utilização de partes dentro de diferentes domínios de aplicação. Como exemplo, temos bibliotecas de funções matemáticas e manipulação de string, bibliotecas para construção de interfaces gráficas, entre outras. A característica principal é a sua utilização em diferentes domínios, diferente do que ocorre no reuso vertical.

Reuso planejado

O reuso planejado é a prática sistemática e formal do reuso onde diretrizes e procedimentos são definidos e seguidos. Requer um alto grau de investimento e comprometimento gerencial, exigindo uma mudança significativa no processo de desenvolvimento de software. O exemplo que caracteriza este reuso são os modelos de maturidade de software que algumas fábricas de software buscam visando uma “prova” de qualidade de seus softwares produzidos.

Reuso Composicional

O reuso composicional é a utilização de componentes existentes como blocos para a construção de um novo sistema. A característica principal é que um novo sistema é construído a partir da composição de componentes existentes, como exemplo, temos os frameworks de componentes como Java Server Faces que apresentam um conjunto de componentes para construção de interfaces com o usuário e a tecnologia de componentes EJB para sistemas distribuídos.

Reuso Baseado em Geradores de Código

Esta abordagem consiste do reuso no nível de especificação de um sistema, através do emprego de geradores de código ou de aplicações. Como exemplos, temos as ferramentas CASE e ferramentas UML.

Reuso Caixa Branca

No reuso caixa branca existe a necessidade de que a implementação do componente de software a ser reusado seja exposta de alguma forma. Em linguagens orientadas a objetos como Java e C++, é muito comum o uso de herança para se atingir o reuso, modificando e adaptando o componente. Neste tipo de reuso é preciso conhecer a implementação de algum componente de software que fará parte do reuso.

Reuso Caixa Preta

O reuso caixa-preta visa eliminar a necessidade do desenvolvedor de um conhecimento da implementação de algum componente de software que fará parte do processo de reuso. Em vez disso, o reuso caixa-preta se dá através da descrição de interfaces ou contratos bem definidos que devem ser respeitados pela implementação a ser elaborada. O esforço sempre é usado na nova implementação e nunca ocorre um desperdício tentando entender implementações de terceiros.

Reuso de Códigos Fonte

Este é o tipo de reuso mais utilizado na prática, o reuso de código. A maioria das ferramentas de reuso e métodos são voltados para este tipo de reuso.

Reuso de Projetos

Reuso de projetos oferecem um retorno maior que o reuso de código. Quanto maior o nível do componente, maior ganho se obtém, dado que os subprodutos gerados também serão componentes. Neste sentido, ao se reusar projetos, o reuso de código ou de módulos executáveis é uma consequência direta. O reuso de projetos é realizado com bastante frequência em orientação a objetos, os vários trabalhos de padrões de projetos refletem a praticidade deste reuso.

Reuso de Especificação

Da mesma maneira que ocorre com projetos, quando se reutiliza uma especificação, tem-se como consequência direta, o reuso de projeto e do código fonte.

Vantagens e benefícios da reutilização

A reutilização otimiza as quatro variáveis que determinam o sucesso dos projetos de software: qualidade, custo, tempo e produtividade.

A prática da reutilização resulta na retenção do conhecimento na empresa e a coloca numa posição de maior competitividade na medida em que ela passa a conseguir desenvolver projetos de qualidade, no tempo acordado e com menores custos.

Um software que incorpora componentes reutilizados apresenta uma estrutura mais flexível o que facilita a manutenção e a evolução.

Os principais benefícios da reutilização, aceita pela maioria dos autores, são citados a seguir:

  • Aumento da produção com a redução no esforço do desenvolvimento.
  • Redução dos custos e do prazo de entrega, pois se o esforço de desenvolvimento diminui logo o tempo de entrega também diminui e a quantidade de homens hora necessária a ser paga também.
  • Como as soluções aplicadas foram anteriormente testadas e validadas, a probabilidade de que esteja correta é ainda maior, portanto temos um aumento da qualidade do produto final.
  • Padronização dos produtos desenvolvidos pela empresa, pois como as soluções reusáveis foram desenvolvidas segundo uma padronização pré-definida, o reuso em um sistema provoca consequente padronização e agilidade na manutenção das aplicações devido a esta padronização da arquitetura.

Desafios e problemas da reutilização

Muitos são os desafios encontrados na adoção do reuso, como por exemplo:

  • A implantação de práticas de reuso requer mudança de mentalidade das pessoas. Com relação ao processo de desenvolvimento deve-se desenvolver para o reuso e com o reuso. A indiferença com relação a reutilizar tem origem em razões como falta de incentivo, dúvida com relação aos benefícios da reutilização, falta de apoio por parte da gestão, entre outros. Modificar uma cultura não é tarefa fácil;
  • O fato da não existência de partes previamente elaboradas para a reutilização ou não é um dos principais fatores para o impedimento;
  • Dificuldade em compreender uma parte reciclada, seja pela falta de documentação ou complexidade do mesmo, é também um fator para desconsideração do reuso.

As organizações reconhecem teoricamente os benefícios que a reutilização sistemática traz. Na prática, muitos fatores conspiram para tornar complicado o processo, particularmente em empresas com muitos desenvolvedores e sistemas herdados.

Manter um repositório de componentes não é um processo fácil porque as técnicas atuais de classificação, catalogação e pesquisa de componentes são imaturas. Por essas razões e devido à falta de padronização, o custo de encontrar componentes flexíveis que suprem as necessidades do projeto pode ser elevado.

A maioria das ferramentas CASE não suportam a reutilização, não podem ser integrados a uma biblioteca de componentes. São ainda recentes os estudos de técnicas que permitam uma implementação bem sucedida da reutilização. O que falta é o desenvolvimento de um processo sistemático e formal para a realização da reutilização. Para além dos obstáculos técnicos existem outros de natureza psicológica. Alguns engenheiros de software preferem reescrever do que reutilizar componentes.

Além disso, quando se reutilizam componentes num contexto diferente daquele em que foram construídos, podem surgir alguns problemas [Kotonya e Sommerville]:

  • Interações inesperadas entre os componentes reutilizados e os novos componentes;
  • Embora os componentes reutilizados já tenham sido analisados e testados, quando utilizados no contexto de um novo projeto deve-se testar ou analisar a sua integração. Evita-se assim problemas em fases mais avançadas do projeto.

Existem dois fatores que geram alguma tensão na reutilização de componentes de software: Granularidade e Nível de Abstração. Granularidade é o tamanho do componente reutilizável. Nível de Abstração pode ser compreendido no exemplo: o código tem um baixo nível de abstração, enquanto que os requisitos têm um alto nível de abstração.

Quanto maior for o tamanho do componente, menores são os custos. Porém, é mais fácil a reutilização de componentes de menores dimensões porque apresentam maiores possibilidades de encapsulamento. Esta relação é apresentada na Figura 2. À medida em que as duas opções estão em extremos opostos, é necessário fazer uma análise cuidadosa para encontrar um tamanho aceitável do componente que satisfaça a ambos os objetivos: custo razoável e facilidade de reutilização.

De igual forma, a reutilização de requisitos tem um custo maior do que a reutilização de código.

Relação entre tamanho e custo
Figura 2. Relação entre tamanho e custo

Conclusão

O objetivo do reuso de software é o aumento da produtividade e redução no esforço de desenvolvimento de novos produtos, por parte dos analistas e desenvolvedores. Entretanto, apesar de ser um objetivo de fácil entendimento, fatores como desconhecimento de técnicas de reuso, falta de ferramentas especializadas, infraestrutura para reuso e fatores humanos são problemas adicionais que tornam complexa a realização de um processo de desenvolvimento com base em reuso.


Saiu na DevMedia!

  • .NET Class Libraries: Utilizando bibliotecas de classes: Neste curso você aprenderá a criar e utilizar bibliotecas de classes (class libraries) em .NET. Essa é uma prática que visa facilitar o compartilhamento de código, promover seu reuso e otimizar a organização de soluções que tendem a crescer e dar origem a vários projetos no Visual Studio.
  • Conheça o MySQL Fabric:Neste artigo iremos conhecer e entender o que é o MySQL Fabric e em qual situações podemos utilizá-lo. Também falaremos sobre as melhores práticas na configuração, instalação e monitoramento do MySQL com o MySQL Fabric.
  • Principais atividades para administração do Oracle RAC: Neste artigo serão apresentados os principais conceitos sobre o Oracle Real Application Cluster (RAC) e os principais comandos para administração e manutenção destes ambientes.
  • Inno Setup: Instalando e distribuindo o SQL Server Express: Veremos neste artigo como é possível distribuir e instalar aplicativos que utilizam como base de dados o SQL Server Express utilizando o Inno Setup.

Referências:

  • Proposta de Padrões de Software para a Reutilização Sistemática em Sistemas de Software Orientados a Objetos
  • Técnicas de Reuso de Software aplicados na elaboração de Arquiteturas Corporativas
  • Prieto-Diaz, R. Reuse as a New Paradigm for Software Development
  • Proceedings of the International Workshop on Systematic Reuse, 1996
  • Ambrosio, P. and Ruggia, R., “Applying Reuse to Conceptual Modeling: an analysis of existing techniques”. Prieto-Diaz, R. "Reuse in Engineering vs. Reuse in Software: Are They Incompatible?", SSR, 2001 Symposium on Software Reusability, Toronto, Canada.
  • Frakes, W., R. Prieto-Diaz and C. Fox, "DARE: Domain Analysis and Reuse Environment." Annals of Software Engineering, September 1998.
  • Jacobsom et al, Software Reuse, 1997
  • Kotonya, G. and Sommerville, I., Requirements Engineering: Processes and Techniques, 2002
  • Loucopoulos, P. and Karakostas, V., System Requirements Engineering”
  • WERNER, C.M.L., BRAGA, R.M.M., “Desenvolvimento baseado em Componentes”. In: Anais do Simpósio Brasileiro de Engenharia de Software, Minicursos, João Pessoa, PB, Brasil, outubro, 2000, pp. 297-329.