1 de junho de 2010

e-T.I.queta

Regras de etiqueta para o profissional de T.I. (Tecnologia da Informação)

Você já teve um professor de T.I. que parecia explicar o assunto para quem já soubesse do assunto?

Já foi a alguma palestra de T.I. em que o palestrante passou a imagem de ser um expert - mas você não entendeu nada do que ele disse?

Infelizmente, isto acontece com muita frequência, especialmente em nossa área de tecnologia.

Talvez o professor e o palestrante acima precisassem saber de algumas regras, como as listadas a seguir.

Se você é um profissional de T.I. e vai apresentar uma aula, ou uma palestra, precisa entender que:

1) Você vai ser bem sucedido em sua apresentação apenas se os espectadores entenderem com clareza o que você apresentou! Se eles ficarem com a impressão de que você deve conhecer muito bem o assunto, mas não entenderem nada do que você apresentou, acredite: você falhou em seu propósito!

2) Falar muitas siglas deve impressionar algumas pessoas, e na área de T.I. é quase impossível não utilizá-las: JEE, EJB, SOA... Mas se você vai, por exemplo, apresentar uma palestra sobre SOA, considere a possibilidade das pessoas não saberem o quê significa SOA. Faça uma breve introdução e esclareça o significado das principais siglas que você vai utilizar. A propósito: SOA significa "Service-oriented architecture" (Arquitetura Orientada a Serviços).

3) Se você se propôs a proferir uma palestra, assuma a missão de esclarecer, e não complicar, o assunto. O palco da apresentação não é o lugar mais apropriado para você demonstrar suas habilidades em falar difícil. Se o seu propósito é apenas exibir seus conhecimentos, inscreva-se numa maratona.

4) Não confunda "Marketing Pessoal" com "Exibicionismo Vazio". Você fará um excelente marketing de si mesmo ao demonstrar que possui boa didática e que consegue esclarecer um assunto complicado. Quem vai assistir a sua palestra, ou a sua aula, tem a intenção (mínima que seja) de aprender sobre o tema.

5) Ao preparar o material da sua apresentação (como slides, etc) procure manter o máximo de simplicidade. Seja objetivo, e elimine tudo o que não for estritamente necessário. Por exemplo: se você já disse que "o sistema funciona como se fossem 3 módulos se comunicando" então o gráfico abaixo é inteiramente inútil:


Ele se torna mais inútil ainda se estiver desenhado em 3 dimensões, com 32 cores. Não precisa passar a impressão de que você é um grande conhecedor de ferramentas gráficas.

6) Se você tem receio de que, ao apresentar sua palestra, alguém possa roubar a sua idéia genial sobre o tema, então não se ofereça a dar uma palestra sobre o tema. Seja um palestrante somente se você estiver disposto a explicar com clareza o assunto em questão.

7) Depois da sua apresentação, procure obter opiniões dos espectadores. Seu endereço de e-mail para contato, escrito no último slide da apresentação, é uma ótima idéia. Diga que você aceita sugestões para a melhoria constante da sua aula ou palestra.

8) Leia os e-mails com as sugestões enviadas pelos espectadores. Procure assimilar, com senso crítico, aquilo que costuma aparecer repetidamente como sugestão.


Acredito que desta forma, com estas regras simples, possamos tornar a área de T.I. melhor a cada dia, com melhores profissionais, dispostos a compartilhar o conhecimento entre si. Fique à vontade para enviar o link deste post ao seu professor que complica mais do que explica. Fique à vontade para me enviar mais regras de etiqueta que você gostaria de acrescentar aqui. E, por fim, fique à vontade para me enviar críticas ou sugestões sobre qualquer assunto deste blog.

Um abraço e até o próximo post!

IF bom é IF morto!

O título deste post se refere a uma boa prática em programação Orientada a Objetos. Nossa equipe de desenvolvimento já adotou este lema, e sempre que chega um colega novato, fazemos questão de apresentá-lo a esta lei: "É proibido utilizar IFs negociais", ou, melhor ainda: "IF BOM É IF MORTO".

Ao ouvir esta lei, a primeira pergunta óbvia que escutamos é: - "Se não posso utilizar IF, então vou utilizar o quê? Switch-Case?"

A resposta é: Não!

Na verdade, não devemos utilizar nem IFs, nem Switch-Case, nem qualquer outra estrutura condicional em nosso código!

Aqui, vamos chamar toda e qualquer estrutura de decisão - seja IF, Switch-Case, ou qualquer outra - apenas como IF pra facilitar.

E por quê não podemos utilizar IF em nosso código?

Pelo seguinte motivo: queremos nos beneficiar das inúmeras vantagens da Orientação a Objetos, e o IF nos remete à velha e ultrapassada programação estruturada. Aliás, o IF é a própria estruturação do código que desejamos evitar:

SE isso 
       FAÇA aquilo
SENÃO
       FAÇA aquilo outro

SWITCH(numero)
       CASO 1: faça aquilo
       CASO 2: faça aquilo outro
       etc etc
Ou seja, é a própria essência da estruturação, ou pelo menos, a característica mais engessada da programação estruturada! Ela demanda várias manutenções no código, sempre que um novo Caso for identificado. Ora, mas dentre outras coisas, não queremos utilizar a OO para minimizar o impacto das alterações?

Então, tome nota desta Lei: IF BOM É IF MORTO.

O questionamento que escutamos em seguida pelos programadores novatos é: - "Mas se não posso usar nem IF, nem Switch-Case, nem nada parecido, COMO é que vou tratar isso?"

É o que veremos a seguir. A regra do nosso exemplo diz que: o programa deverá receber do usuário uma informação "PF" ou "PJ", indicando se vai tratar de Pessoa Física ou Pessoa Jurídica.

SE for pessoa física, o sistema imprime na tela "Pessoa Física", consulta e grava dados num banco Oracle, envia um e-mail automático para a Empresa X, gera um LOG numa pasta específica, e imprime um Relatório de PF.

SE for pessoa jurídica, o sistema imprime na tela "Pessoa Jurídica", consulta e grava dados num banco DB2, envia 3 e-mails automáticos para a Empresa X, Y, Z, gera um LOG em outra pasta específica, e imprime 2 Relatórios de PJ.

Implementando da maneira estruturada, teríamos o seguinte:
public class  Executavel{
  public static void main(String[] args){
      String tipo = args[0];
      if(tipo.equals("PF")){
          System.out.println("Pessoa Física");
          System.out.println("Consultando Oracle...");
      }
      if(tipo.equals("PJ")){
          System.out.println("Pessoa Jurídica");
          System.out.println("Consultando DB2...");
      }
      GeraMail.trataTipo(tipo);
      TrataLog.grava(tipo);
      Relatorio.imprime(tipo);
  }
}
Um exemplo simples, que recebe o parâmetro do usuário na linha de comando, sem muito tratamento, apenas para ilustrar os malefícios da abordagem estruturada com IFs.

O "arquiteto" que projetou a solução acima, baseou toda a solução nos IFs. Note que, na chamada a GeraMail.trata(tipo), ele precisa enviar a informação do usuário (PF ou PJ), e dentro desta classe vamos ter outra estrutura de IFs para tratar o envio de e-mail. O mesmo acontece com TrataLog e Relatorio, replicando a estrutura de IFs por diversas partes do código.

Ao projetar a "brilhante" solução acima, o "arquiteto genial" pensou: - "Bem, os 2 únicos tipos possíveis neste caso para pessoa é Física ou Jurídica. Então, vou fazer com IFs mesmo". Aí então, 4 meses de trabalho depois, com toda a "arquitetura" pronta e faltando 1 semana para o prazo final da entrega do projeto, ele recebe um telefonema do Cliente, que diz: - "Preciso tratar mais um tipo! Se refere à PJS - Pessoa Jurídica optante pelo Simples, que, no meu requisito, vai possuir regras completamente diferentes dos outros tipos".

Pânico! Desespero! Ele precisa alterar o método main() acima para inserir mais um tratamento, e precisa alterar a classe GeraMail para tratar mais um IF, e precisa dar manutenção também na classe TrataLog, e também na Relatorio, e em mais 7.586 classes do sistema... :-) [...geralmente é o que acontece na prática, além de ter que testar tudo novamente...] Ou seja, muitas noites sem dormir, trabalho no sábado e domingo, aumento enorme da probabilidade de falhas no sistema, e muito provavelmente, mais um projeto que vai estourar custo e prazo!

Tudo porque ele negligenciou o nosso lema: IF BOM É IF MORTO.

Como fazer sem usar IFs? Assim:

Vou criar a interface Pessoa:
 public interface Pessoa{
        public void imprime();
 }
Vou criar a classe PessoaFisica, que vai conter todos os tratamentos que são de responsabilidade de PF (gravar no Oracle, enviar e-mail para X, etc), e a classe PessoaJuridica, que vai tratar regras de PJ (grava no DB2, etc, etc). Ambas as classes vão implementar a interface Pessoa.

Apenas para que possamos rodar o nosso exemplo, e ver a solução funcionando na prática, vou fazer com que as classes PF e PJ exibam na tela suas informações, sem tratar acesso a banco nem como gerar logs, etc (não é assunto deste post).

A classe PessoaFisica.java ficaria assim:
public class PessoaFisica implements Pessoa{
   public void imprime(){
      System.out.println("Pessoa Física");
      System.out.println("Consultando Oracle...");
   }
}
A classe PessoaJuridica.java ficaria assim:
public class PessoaJuridica implements Pessoa{
   public void imprime(){
      System.out.println("Pessoa Jurídica");
      System.out.println("Consultando DB2...");
   }
}
Agora, sem os malditos IFs, a mesma classe Executavel.java do início do exemplo:
public class Executavel{
  public static void main(String[] args){
     Map mapaDePessoas = new HashMap();
     mapaDePessoas.put("PF", new PessoaFisica());
     mapaDePessoas.put("PJ", new PessoaJuridica());
     String tipo = args[0];
     Pessoa pessoa = (Pessoa) mapaDePessoas.get(tipo);
     pessoa.imprime();
  }
}
Compile, rode e ateste a eficácia da solução:

/> java Executavel PF
Pessoa Física
Consultando Oracle...

/> java Executavel PJ
Pessoa Jurídica
Consultando DB2...

Pronto! De acordo com a informação dada pelo usuário, executei regras diferentes sem utilizar 1 único IF (nem Switch-Case...)

E se eu precisar de um novo tipo para Pessoa Jurídica optante pelo Simples - PJS? Aí então eu vou criar esta nova classe PJS, com suas regras específicas, e adicionar uma entrada no Mapa:

mapaDePessoas.put("PJS", new PJS());

E só! Nenhum outro ponto em todo o Projeto precisaria ser alterado!

Por fim, vale ressaltar que a desvantagem do IF é esta propagação de manutenções que ele demanda em caso de alteração. Entretanto, para utilizar o mecanismo da inicialização tardia, podemos fazer o trecho abaixo sem problemas:
public Conexao  getConexao(){
   if(this.conexao == null){
        this.conexao = new Conexao();
   }
   return this.conexao;
}
Você pode estar pensando: - "Mas você disse que é proibido utilizar IFs". Não, eu não disse isso!

O que eu disse foi: é proibido usar IFs negociais! Este não é um IF negocial, ele apenas testa o valor nulo. Ou, como diz a nossa Lei: "IF BOM É IF MORTO". Exatamente! Este IF acima está morto! Ou seja, não há a menor possibilidade de ele vir sofrer alterações futuramente. Na inicialização tardia, eu testo se o valor é nulo, e isto nunca vai ser alterado. O Cliente pode mudar todos os seus requisitos que, ainda assim, o método getConexao() acima vai continuar como está!

O exemplo aqui apresentado é uma implementação do GoF Pattern Strategy. As classes PessoaFisica e PessoaJuridica podem ser entendidas como estratégias que encapsulam seus algoritmos. Pretendo abordar o Strategy em outro post, específico sobre este padrão, para que possamos ver outros exemplos e discutir as abordagens do GoF. Até lá!

(*PS: não deixe de enviar seu comentário, dúvida, crítica, sugestões, discordâncias, perguntas, reclamações...)