O uso racional de recursos só é possível se você conhece bem o sistema para o qual está programando. Conhecer bem o sistema não quer dizer que você precise entrar nos detalhes do kernel. Basta, para isso, entender quais são os recursos que estão disponíveis e como fazer para gerenciá-los.
O uso de recursos em computação exige mais do que o simples conhecimento da plataforma. Também exige conhecimentos específicos como algoritmos e estruturas de dados. Os algoritmos são essenciais para minimizar o uso de processamento e as estruturas de dados são essenciais para descrever a informação de maneira mínima e racional.
Eu sempre bato nesta mesma tecla: algoritmos e estruturas de dados. Os estudantes de computação são levados a crer que é importante conhecer uma linguagem de programação em detrimento do conhecimento de algoritmos e estruturas de dados. Infelizmente, não poderiam estar mais enganados. Sem o bom conhecimento de algoritmos e estruturas de dados o resultado sempre é um programa excessivo: excesso de consumo de recursos, excesso de código desnecessário, etc.
Sou de opinião que a programação deve sempre orientar-se ao uso racional de recursos, ou seja, nunca partir da suposição que os recursos necessários estarão sempre disponíveis. Essa forma de pensar leva ao desenvolvimento de aplicações eficientes. Não basta apenas ser bonitinha: a aplicação precisa, também, ser rápida e responder prontamente ao usuário. Quanto mais uma aplicação demora, menor será a possibilidade de permanecer em uso. Afinal, o principal motivo das aplicações existirem são os usuários.
Os design patterns são, sem dúvida, uma das ferramentas mais poderosas na caixa de ferramentas do programador. Porém, como toda ferramenta é preciso saber usá-las adequadamente para que sejam realmente úteis e não se tornem uma bela dor-de-cabeça.
Com alguma frequência vejo alguns design patterns utilizados de maneira inadequada. Singletons são os mais usados de maneira incorreta. O façade, objeto deste artigo, também. Normalmente, o façade acaba tornando-se um tipo de classe “sacola” na qual tudo o que não se consegue modelar como objeto acaba indo parar.
Basta lembrar-se para o que o façade serve: para unificar uma API esparsa em um único ponto. Ou seja, a ideia do façade é servir como entry point em uma API complexa, criando uma interface mais simples de ser utilizada. Isso é bem diferente de socar toda e qualquer funcionalidade que não se sabe bem onde deveria ficar.
O efeito negativo de transformar o façade em uma classe sacola é a criação de uma classe enorme, com métodos igualmente grandes e que é programada basicamente como se fosse um conjunto de funções e não um conjunto de métodos pela disjunção funcional que acaba existindo entre cada um dos métodos introduzidos.
Eu bato muito na tecla da manutenção pois é com ela que se gasta mais tempo nos ciclos de desenvolvimento de software.
Você precisa desenvolver uma aplicação com uma série de funcionalidades. Você tem a brilhante ideia de usar bibliotecas de código aberto que achou no Google para agilizar o seu trabalho, cortando o seu tempo de desenvolvimento quase pela metade. Você já viu essa estória.
Introduzir código pronto, de terceiros, introduz no seu sistema uma variável descontrolada que irá atingir em cheio a manutenção do seu código. O que as pessoas não conseguem entender é que usar uma biblioteca de código aberto aumenta o trabalho de manutenção do código. Por que? Por que o código introduzido no seu sistema agora faz parte do seu sistema. E como este código foi escrito por seres humanos é certo que contém defeitos. Quem vai consertá-los?
A postura correta é consertar os defeitos e publicar as correções para a comunidade que mantém o código. Afinal, você abraçou a causa depois que resolveu introduzir o código no seu projeto. Agora o filho é seu também. Assim, ao introduzir código aberto no seu sistema você também tornou-se um mantenedor deste mesmo código. O problema, que poucos enxergam, é o custo que isso gera para os projetos da empresa. Afinal, alguém terá de dedicar horas de trabalho para manter código aberto, gratuito, e cada hora de trabalho custa dinheiro à empresa. Seu salário vem no fim do mês, não é mesmo?
O uso indiscriminado de código aberto dentro de projetos nas empresas gera prejuízos não por que o código aberto é ruim, mas pela falta de planejamento na utilização deste código. Empresas como a IBM, por exemplo, financiam projetos de código aberto para poder usufruir dos mesmos. Há um planejamento e envolvimento empresarial consciente nestes projetos. Porém, um programador introduzir à revelia uma biblioteca de código aberto em um projeto irá gerar prejuízos para a empresa pois a falta de planejamento na utilização deste código custará horas de manutenção em código de terceiros.
Desenvolver aplicações, as famosas apps, para dispositivos móveis está na moda. Muita gente desenvolve aplicações para as plataformas móveis sem ter um mínimo de conhecimento de programação de computadores, como se isso fosse descartável. O resultado são aplicações lentas, pesadas e que consomem muito mais recursos do que deveriam.
As aplicações para dispositivos móveis são sistemas de informação. Não basta fazer uma interface bonita. É preciso ter um projeto sério de engenharia de software para que a aplicação torne-se um sucesso nas lojas on-line. Isso significa dizer que é essencial conhecer-se algoritmos, estruturas de dados, design patterns e outras matérias específicas de computação.
Canso de dizer e repito: um designer não tem a menor condição de implementar uma aplicação de sucesso apenas por fazer o design. O recheio, o código, precisa de modelos matemáticos de dados para suportarem a funcionalidade pretendida pela aplicação. Além do modelo, é preciso ter código que manipule o modelo matemático de maneira eficiente e eficaz.
Não quero desmerecer o trabalho do designer. Eu desenvolvo software e entendo o quanto o bom design é importante e essencial para a criação de uma aplicação. No entanto, da mesma forma que um programador normalmente não tem condições de fazer um bom design de UI, o designer não tem condições de fazer um código para a aplicação. É como pedir para um matemático pintar um quadro ou um pintor resolver uma equação.
Eu tenho visto bastante disso aqui na nossa terrinha: designers acreditando que podem escrever aplicações para dispositivos móveis. O resultado são aplicações belíssimas, mas cheias de defeitos, desde problemas básicos de navegação até problemas mais sérios como consumo de bateria, crashes inesperados e falhas graves de manutenção de dados. Por que isso? Pelo simples fato de que são aplicações desenvolvidas por quem sabe fazer UI mas não tem a mínima ideia de como modelar os dados, as relações entre eles e em como produzir informações através de processamento eficiente e eficaz.
O desenvolvimento de aplicações para dispositivos móveis é desafiador pois os recursos disponíveis são reduzidos e podem exaurir-se muito facilmente, ao contrário do que ocorre com os desktops ou servidores nos quais os recursos são abundantes. Os paradigmas são outros o que traz ao código final uma complexidade que não existe em máquinas com recursos.
A expressão lambda, também conhecida como função lambda, é uma função que não tem um identificador associado à ela. Várias linguagens de programação permitem a sintaxe de funções sem identificação, como Objective C, javascript e Lisp. Mas qual é a vantagem de escrever uma função sem identificação?
As expressões lambda são ótimas para a criação de pequenas rotinas que precisam ser implementadas in place. A principal vantagem de utilizá-las é permitir que pequenos trechos de código, de escopo bem definido, sejam organizados em blocos de código bem destacados. O Objective C, por exemplo, faz uso corriqueiro das expressões lambda para a implementação de uma série de métodos em diversos objetos.
Como todo recurso poderoso de uma linguagem de programação, é preciso ter consciência em usar uma expressão lambda. Esse negócio existe para facilitar a escrita de pequenos trechos de código e não para que você escreva uma encíclica papal contando a História do Mundo desde a Criação.
A expressão lambda é útil, também, para criar uma hierarquia de funções, coisa que é suportada na linguagem Pascal, por exemplo. Em Pascal é possível declarar-se uma função ou procedimento dentro de uma função ou procedimento e assim sucessivamente. Em algumas circunstâncias é muito interessante limitar o escopo de uma determinada funcionalidade do seu código, criando hierarquias de definições.
O Objective C ainda permite que as funções lambda sejam atribuídas a variáveis, algo como um ponteiro para funções mas com estrutura totalmente variável. Isso dá à linguagem uma flexibilidade enorme para a criação de algoritmos adaptativos e polimórficos, dando ao programador uma tremenda ferramenta para criar rotinas simples e poderosas.
