quinta-feira, 6 de agosto de 2015

O absurdo da notação húngara nos dias atuais

Define-se por notação húngara a prática de prefixar variáveis com letras que indiquem o seu tipo. Por exemplo i para inteiros, d para datas, f para floats. 

     As variáveis data de nascimento e nome em notação húngara seriam ddatanascimento e snome, no pior dos casos, ou dDataDeNascimento e sNome se o "programador" resolveu usar camelCase. 

     Como mencionei nos meus artigos anteriores, e como mencionado nos livros "Código Limpo" e qualquer livro sobre XP, essa prática caiu em desuso. 

     Ela foi útil um dia para identificar o tipo das variáveis, e de fato identificava. Hoje damos nomes significativos para as variáveis e deixamos que sua declaração e as facilidades da IDE identifiquem o seu tipo. Além disso hoje podemos mudar o tipo de uma variável mantendo o seu nome e o seu uso, coisa que no passado geraria alguma inconsistência semântica na hora de ler e dar manutenção no código. 

     Soma-se a isso o fato de no passado não existirem, nas linguagens comumente usadas, tipos de dados dinâmicos (variants se aproximavam disso) ou definidos em tempo de execução, tampouco tipos anônimos. 

     Num contexto orientado a objetos o uso de notação húngara, além de ser um overhead, é ridículo e chega a ser prejudicial. 

     Já vi, em várias empresas, classes em C# ou Java prefixadas com "cls". Qual o propósito disso? A notação húngara foi criada para se prefixar variáveis, e nunca tipos ou records. Uma classe é um tipo definido pelo programador, um tipo estruturado, uma classe é um tipo, portanto nunca deveria ser prefixado com a abreviação de um tipo. 

     Qual o propósito de prefixar as classes com cls se TODAS as classes sem exceção forem prefixadas com cls? No que cls as distingue das outras? 

     Pense na diferença entre dizer que todos os animais são do tipo animal, e todos os tipos são do tipo tipo. Redundância. Sempre é prejudicial. 

     Prefixar classes com cls não as distinguem umas das outras, mas o pior é prefixar objetos dessas classes, que podem ser inúmeras e com inúmeros significados, com a letra "o", só porque são objetos.   É afirmar erroneamente e categoricamente que os objetos oUsuario e oProduto são do mesmo tipo, quando suas classes sequer tem algum grau de parentesco. 

     Usar notação húngara em programas modernos e linguagens orientadas a objetos é sinal de acomodação profissional, falta de atualização, porquice ou até mesmo estupidez. 

     Linguagens como Object Pascal e as IDE's Delphi e Lazarus te obrigam a usar notação húngara na criação de classes por um motivo "legado": o código nestas linguagens tem dois níveis de encapsulamento, a unit e a classe/type. Isso faz com que a própria unit seja um "tipo" e seu nome faz parte do namespace total das classes que estão dentro dela. Como o pascal permite variáveis (públicas ou privadas) estáticas fora das classes (globais), não é permitido que a unit tenha o mesmo nome de sua classe, pois isso geraria dois "tipos" com o mesmo nome. 

     Veja que é uma limitação do Delphi / Lazarus: mesmo que você obedeça a orientação e boa prática de ter uma única classe por unit/arquivo, uma classe não pode ter o mesmo nome do arquivo físico onde está contida. E o arquivo físico deve ter o mesmo nome que seu nome "lógico" de unidade. 

     Em contraste com isso linguagens como C# e Java permitem ter classes com o mesmo nome que o arquivo onde elas estão contidas, e isso não te impede de criar outras classes com outros nomes dentro do mesmo arquivo embora isso não seja uma boa prática. 

     Embora o uso de notação húngara seja  justificado no caso do Delphi e do Lazarus, eu acredito que prefixar ou sufixar os arquivos com a letra u (de unit) é melhor do que prefixar os tipos. Assim você tem os tipos de dados, as suas classes, os seus objetos de negócio ( o seu domínio ) com nomes significativos, sem problemas de semântica e com um dicionário padrão do domínio. Isso traria um padrão de nomenclatura mais moderno para quem programa nessas linguagens. Mas nem tudo são flores...

     Por padrão das units de sistema e dos frameworks que acompanham as ferramentas todas as classes (e tipos, records etc) são prefixadas com a letra T (de type) . Então todas as classes de sistema já existem e são prefixadas com T. Não faz sentido você criar uma classe Produto, mas na hora de colocar vários produtos numa lista precisar de uma TList<Produto>. O uso de prefixo de um lado e não do outro pode gerar um gap semântico. 

     Além disso tem o problema das interfaces. As modernas técnicas de POO e DDD e os princípios  SOLID nos ensinam a programar orientado a interfaces, e grandes nomes do projeto e desenvolvimento de software, como Kent beck, Robert Martin, Martin Fowler afirmam categoricamente que: 
  1. Você deve usar as modernas técnicas de POO, padrões de projeto e DDD e 
  2. Você deve usar padrões de nomenclatura, codificação e formatação para nivelar a sua equipe com um mesmo estilo de codificação e todos progredirem rápido. 
     O problema disso é que os melhores padrões de nomenclatura encontrados na literatura hoje afirmam que as interfaces devem ser prefixadas com I .... olha a notação húngara aí geeeeeente!. 

     Acredito que não dá para ser dogmático a ponto de não prefixar as interfaces com I. Se você ver uma interface chamada "Pessoa" é meio difícil saber que é uma interface sem olhar na sua declaração, seus métodos "pelados" e falta de implementação. Ainda assim ela pode ser confundida com uma classe abstrata. Até na UML existem estereótipos e símbolos diferentes para definir as interfaces. 

     Mas, se você não estiver escrevendo uma interface e nem usando Object Pascal, Pelo amor de Deus, não usem mais notação húngara.

Postagens populares

Marcadores

delphi (60) C# (31) poo (21) Lazarus (19) Site aos Pedaços (15) sql (13) Reflexões (10) .Net (9) Humor (9) javascript (9) ASp.Net (8) api (8) Básico (6) Programação (6) ms sql server (5) Web (4) banco de dados (4) HTML (3) PHP (3) Python (3) design patterns (3) jQuery (3) livros (3) metaprogramação (3) Ajax (2) Debug (2) Dicas Básicas Windows (2) Pascal (2) games (2) linguagem (2) música (2) singleton (2) tecnologia (2) Anime (1) Api do Windows (1) Assembly (1) Eventos (1) Experts (1) GNU (1) Inglês (1) JSON (1) SO (1) datas (1) developers (1) dicas (1) easter egg (1) firebird (1) interfaces (1) introspecção (1) memo (1) oracle (1) reflexão (1)