Programando defensivamente

August 24, 2008

(0) Comments

Muitos são os casos de softwares mal-sucedidos e prontos para o insucesso em sistemas desenvolvidos sem um estudo e planejamento inicial. Até mesmo a forma como ele é desenvolvido durante a duração desse ciclo determina seu fracasso. O que realmente acontece quando estamos frente-a-frente com essa situação todos sabemos. A sensação de insegurança é predominante. Não temos nenhuma confiança em utilizar muitos objetos do projeto. Não temos confiança por não termos um contrato definido. Isso acontece, primeiramente, porque temos um sequência de códigos legados mal-escritos. Onde o profissional que projetou determinado objeto do software não se preocupou em como iremos usar determinado resultado de um método por exemplo. Afinal, em muitos casos, pela falta de conhecimento no domínio do negócio não saberemos lidar com uma informação nula. E como não sabemos se isso realmente poderá acontecer, estabelecemos aquela sequência de testes verificando a nulabilidade de determinada ação. Sem nem realmente sabermos onde queremos chegar com aquilo. Querendo apenas evitar uma exceção de sistema.

Podemos evitar essa situação, criando um projeto de software realmente confiável em termos de codificação, que cá pra nós é a parte mais importante do projeto. Faremos isso programando defensivamente, buscando utilizar práticas de codificação defensiva, já que não temos contratos pré-estabelicidos. Evitando assim, o mal uso deles pelos demais desenvolvedores. Afinal, se alguma coisa pode dar errado, ela indiscutivelmente dará errado. É a lei.

Como não temos um contrato pré-estabelicido em nosso projeto em andamento, utilizamos a programação defensiva para evitarmos mais dor de cabeça. Com ela garantimos que quem utilizará nossos objetos obtenham um resposta segura, não importando o que realmente ele quer que aconteça. Ou seja, sempre procuraremos por todas as coisas que podem dar errado e executaremos uma quantidade excessiva de testes para evitarmos situações embaraçosas no nosso software.

A prática mais utilizada na programação defensiva é a utilização de exceções para casos que precisamos evitar a continuidade do fluxo para determinado valor do objeto. Normalmente utiliza-se exceções checadas. Lembrando que existem casos e casos, e a verdade absoluta é algo que realmente não existe. Então se você pensa que uma exeção não checada é a melhor saída: vá em frente, pois uma exeção checada trará sempre mais código para quem reaproveitará o código. Dependendo do caso, o retorno de um objeto vazio pode significar muito mais que o retorno de um objeto nulo.

Outro prática que podemos adotar em uma programação defensiva é dar a devida importância aos dados de entrada em nossos sistema. Sabemos que apartir de um dado errado, muitos outros se perpetuarão no nosso sistema. Então, seja qual for a fronteira: sistema externo, cadastro básico, rotina de movimentação, não interessa. Todos os dados devem ser válidados. Jamais pense na camada de visão para isso. Toda e qualquer validação de dados nunca deverá ser garantida aí. Afinal cada objeto com sua responsabilidade.

Acredito que a melhor forma de garantirmos segurança e confiabiliade no desenvolvimento de um software são os testes. Use e abuse deles. Crie scripts de testes que testem todos os seus componentes e a saída experada por eles. Qualquer modificação errada no código de seu software devem ser inválidadas nos seus scripts de testes. A grande sacada para isso chama-se desenvolvimento dirigido por testes, o famoso TDD. Vale a pena aprofundarmos nesse assunto.

Um sistema de logs bem construído também nos ajuda a encontrar os principais pontos de falhas do nosso sistema. Nunca ignore esse item na elaboração da arquitetura do seu projeto. Você realmente precisará dele para não perder algumas noites de sono.

Uma coisa que vejo periódicamente é o uso dos famosos “domains”, algo que se originou da programação estrutural. Então vemos aqueles testes absurdos com atributos do tipo String. E os erros são inevitáveis. Por favor, conheça a linguagem de programação que você está utilizando no seu projeto. Para esses casos use e brigue pelo uso de enumeradores. Outra pedida é: documente seu código. É importante. Mas nada de desenhar balões e aquelas coisas bizarras, ok? Seja simples e direto.

Reduzir a complexidade do nosso código e atacarmos o menor ponto de funcionalidade de cada caso de uso  separando qualquer algoritmo no menor tamanho possível é outra prática a ser adotada no desenvolvimento. E cada vez que você divide a sua aplicação, você começa a se repetir. Isso gera mais análise e mais projeto pra cada tomada de decisão, aumentando as chances de termos um código coeso e levemente ligado.

Lembre-se que o cliente não liga pra diagramas bem desenhados, uma lista de requisitos em um documento bem elaborado. O que realmente interessa para o cliente é software fazendo alguma coisa concreta. De preferência com a maior qualidade e confiabilidade possível. O desenvolvimento de um software consiste em repetição. Nada de etapas separadas. Na verdade nada de etapas. Quanto mais específico for nosso caso de uso melhor. Iterações curtas até o resultado esperado pelo cliente. E não tenha medo de ser chamado de retranqueiro.

Popularity: 17% [?]

Daniel Tamiosso

,

Usando objetos de acordo com sua responsabilidade

August 3, 2008

(0) Comments

O paradigma orientado a objetos, como o próprio nome deixa claro, parte do principio que o foco de quem irá analisar/projetar/desenvolver… deve ser totalmente direcionado para os objetos. Parece ser muito simples e na verdade eu acredito que seja, pelo menos até que me provem o contrário. Sim, pois acredito – e muito – na idéia básica de que um projeto de um sistema de informação deve sempre buscar a simplicidade. Penso nisso com base em um pensamento de Da Vince: “A simplicidade é o último grau de sofisticação”, que meu amigo Wagner Andrade gosta, e muito, de citar.

Mas a bem da verdade, a maioria dos projetos que encontramos e participamos no nosso dia-a-dia não seguem essa premissa básica. Desde a escolha das tecnologias até aos processos (ou a escolha pela falta deles) que serão empregados no gerenciamento do mesmo.

Quando utilizamos orientação a objetos, não podemos ficar presos apenas a conceitos acadêmicos, como: os objetos normalmente são definidos com métodos e assim por diante. Tudo bem, até pode ser uma afirmativa verdadeira. Mas essa é uma visão um tanto quanto limitada para definirmos uma visão concreta para um objeto.

Podemos dizer que um objeto é algo - qualquer coisa, envolvida no nosso domínio de negócios – e que tem apenas uma responsabilidade: a sua. E é essa responsabilidade que determinará comportamentos ao objeto. Essa é uma definição que nos ajuda em pensar o que os objetos provavelmente irão fazer e não apenas em como o implementar.

No desenvolvimento orientado a objetos podemos usufruir de alguns princípios para nos auxiliar no projeto de um sistema de informação. Um dos mais conhecidos deles, por incrível que pareça não é o POG, mas sim o SRP – que traduzido para o português, significa: princípio da responsabilidade única. Ou seja toda e qualquer classe deve possuir apenas uma razão de ser, estar e existir. Vale lembrar que todos os seus serviços devem estar preparados para externalizar somente essa única responsabilidade. Nada além do que se vê.

Como exemplo, podemos utilizar uma classe Automóvel para entendermos a aplicabilidade do princípio. Um automóvel tem a responsabilidade básica de locomoção. Então o mesmo poderá realizar ações como: andar, parar e receber gasolina. Mas jamais poderá ele mesmo trocar os pneus, dirigir, trocar o óleo e assim por diante. Essas são tarefas, respectivamente, do mecânico, do motoristo e do frentista. E não do carro. Tudo bem que até poderia ser uma boa idéia, mas infelizmente não é o que acontece.

Com esse princípio aplicado de maneira correta, estaremos dando um grande passo pra evitarmos o acoplamento de classes, aumentando, também, as chances de termos um domínio de modelos com alta coesão. Essa idéia nos permite desenvolver o software em dois passos: fazer um projeto preliminar sem se preocupar com todos os detalhes envolvidos; e implementar o projeto alcançado anteriormente.

Uma observação: desculpa pela demora pelos posts, estou na Indonésia, trabalhando na implantação de um importante projeto a dois meses e completamente sem tempo. Prometo ser mais assíduo no meu blog de agora em diante.

Abraço a todos.

Popularity: 24% [?]

Daniel Tamiosso

,