Artigo no estilo Mentoring

Mentoring:Neste artigo veremos alguns recursos de programação orientada a objetos com Delphi, como herança, abstração e polimorfismo, aplicados em um exemplo prático. Através do uso de boas práticas, veremos como estes fundamentos podem tornar um software mais fácil de ser mantido e evoluído, usando ainda algumas técnicas de desenvolvimento ágil associada a design patterns, como a refatoração rumo a padrões de projeto.

Veremos como resolver problemas comuns encontrados em código fonte (bad smells, ou “maus cheiros”), usando uma abordagem de desenvolvimento corretiva e evolutiva. Uma introdução ao desenvolvimento ágil evolutivo é apresentada, como forma de unir estas técnicas de orientação a objeto com as técnicas atuais de engenharia de software, demonstradas em um exemplo prático com Delphi XE6.

Metodologias clássicas de engenharia de software são muito burocráticas, focadas em planejamento, dão ênfase em contratos fixos, documentação excessiva, vasto planejamento antecipado (prematuro). Essa abordagem não condiz mais com a realidade dos projetos na área de tecnologia, onde novos requisitos são criados, modificados ou mesmo removidos após um planejamento inicial.

Já as metodologias ágeis de desenvolvimento são evolutivas por natureza, organizam o trabalho de forma interativa, realizado em pequenas partes, com pequenas entregas, ao invés de um único release enorme. Dão maior ênfase na colaboração e comunicação aberta e fluente entre stakeholders, clientes e membros do time, minimizando as chances de insucesso em projetos.

Os princípios básicos da abordagem ágil sugerem que indivíduos e interações são mais importantes que processos e ferramentas, trabalho deve ser feito mais focado no software em si que em uma documentação abrangente, colaboração do cliente mais que negociação de contrato e, principalmente, responder a mudanças mais que seguir um plano.

Em software, estima-se que até 50% de custos são gastos com design e planejamento. Uma metodologia ágil como a Extreme Programming prega cinco valores principais: comunicação, feedback, simplicidade, coragem e respeito, com foco maior em disciplina do que processos.

Já Scrum prega um desenvolvimento ágil baseado em iterações chamadas sprints e reuniões de acompanhamento frequentes (meetings). Aplicações reais precisam continuamente ser evoluídas, novos requisitos implementados, melhorias devem ser feitas no projeto existente (design), algumas vezes é necessário mudar de tecnologia ou plataforma, corrigir bugs, otimizar e melhorar a performance.

Para muitas empresas, o foco na construção de um software é torná-lo fácil de ser mantido ao longo do tempo. Nesse sentido, é necessário tomar cuidado com bons princípios de design, como criar componentes com baixo acoplamento, reutilizáveis, que garantam que alterações em componentes não afetam outros, que objetos tenham responsabilidades únicas, separadas, partes facilmente substituíveis, complexidade encapsulada.

Esses são princípios básicos da programação orientada a objetos que, vistos dentro de um contexto de uma abordagem ágil evolutiva, vão tornar o sistema de software mais fácil de testar, evoluir, manter e entender.

Padrões de Projeto (Design Patterns) ajudam a criar bons designs de software, já o uso de Refatoração contínua garante código claro, limpo e funcional em equipes que programam de forma mais ágil, sem se preocupar em um primeiro momento com muitos aspectos de design.

Padrões de Projeto são soluções reutilizáveis para problemas recorrentes no desenvolvimento orientado a objetos. Aplicar padrões antecipadamente em um projeto requer mais tempo e aumenta custos, ao mesmo tempo em que aumenta sua complexidade.

Requisitos são modificados, criados ou mesmo eliminados conforme projetos evoluem. Tentar aplicar padrões antecipadamente para prever essas mudanças é um problema conhecido como excesso de engenharia. Já projeto em escassez reduz custos, pois o sistema de software é criado rapidamente devido à falta de tempo, conhecimento ou necessidade de se adicionar funcionalidades em curto prazo.

Ao longo do tempo, armazena-se um débito de projeto, que torna o sistema de software muito difícil de ser mantido e evoluído. É nesse contexto que entram as refatorações, como uma forma de melhorar o projeto existente sem alterar seu comportamento externo observável. Refatoração é o aspecto-chave para um projeto evolutivo.

Nesse caso, desenvolvimento ágil, evolutivo, incremental, apoiado em refatorações e testes, é uma excelente receita para garantir o sucesso do projeto, seja ela para um startup ou uma grande corporação.

Este artigo vai mostrar como aplicar estes conceitos em um exemplo prático com Delphi XE6. Serão demonstrados os principais fundamentos da orientação a objetos (ver BOX 1) em uma aplicação que simula notificação de clientes de uma determinada companhia, por exemplo, uma operadora de telefonia, que precisa avisar seus clientes sobre cobranças, promoções e novidades.

Além dos fundamentos da orientação a objetos, são demonstradas importantes técnicas como programação para interfaces, padrões, anti-patterns, bad smells, uso contínuo de refatoração para um desenvolvimento ágil com código sempre limpo e funcional, além do uso de refatoração rumo a padrões de projeto.

BOX 1 - Os quatro pilares da Programação Orientada a Objetos

i) Abstração: capacidade de representar conceitos do domínio do problema, ressaltando apenas o que for relevante para a aplicação em questão. A definição da classe em Delphi atende a esse requisito, pois ela é um modelo limitado de alguma entidade real, que implementa apenas as características que são necessárias para a aplicação sendo desenvolvida em um dado contexto.

ii) Encapsulamento: a linguagem deve permitir a definição de módulos autossuficientes, possibilitando a implementação do conceito de ocultação de informação (information hiding), ou seja, esconder os detalhes internos. O uso dos especificadores de visibilidade (private e protected, por exemplo) e o comportamento dos objetos em Delphi reforçam esse princípio, principalmente se o desenvolvedor usar propriedades nas classes, como forma de acesso aos campos internos.

iii) Herança: mecanismo que permite a definição de uma hierarquia de classes, com o objetivo de reutilizar características já definidas e estendê-las em níveis maiores de detalhes ou especialização. O Delphi implementa um mecanismo eficiente de herança simples (apenas uma classe ancestral – não há suporte para herança múltipla de classes).

iv) Polimorfismo: classes descendentes podem implementar de forma diferente um conjunto de operações comuns.

Criando a aplicação

Quer ler esse conteúdo completo? Tenha acesso completo