Carlos Brando

Nome do Jogo

Todos os métodos devem ser públicos? Definitivamente não!

Recentemente fiz a seguinte pergunta no Twitter:

As respostas que recebi apenas confirmaram o que eu já imaginava.

O motivo da pesquisa é que recentemente eu estava lendo um artigo onde o autor argumentava que o ideal seria criarmos classes somente com métodos públicos, evitando ao máximo métodos privados ou protegidos. E entre outros argumentos, um dos motivos para se fazer isto era simplificar a criação de testes.

Uma coisa que me preocupa no Ruby é que é muito comum encontrar programadores que não estão nem um pouco preocupados se os seus métodos são públicos, protegidos ou privados. Pior ainda, quando tomam decisões apoiando-se em argumentos como o acima.

Um clássico exemplo são os métodos de callback de validações do Active Record, que em praticamente 99% dos casos deveriam ser privados ou protegidos, mas é normal encontrá-los entre os métodos públicos de um modelo na maioria dos projetos Rails. Acredito que isto aconteça porque programadores iniciantes entusiasmados com as facilidades do Active Record apenas saem incluindo seus códigos sem pensar muito no que estão fazendo.

Eu também não tenho o hábito de testar métodos privados, pelas mesmas razões mencionadas pelos amigos do Twitter. Mas no Ruby, se você realmente desejar, é trivial realizar uma chamada em um método privado de um objeto. Uma das técnicas mais usadas por “testadores de métodos privados” é se valer das características dinâmicas da linguagem para transformar todos os métodos privados de uma classe em métodos públicos durante os testes. Diferente de outras linguagens, como C# por exemplo, onde você tem uma barreira formal para impedi-lo de acessar métodos privados, no Ruby é ridiculamente simples ultrapassar esta barreira.

Pensando desta maneira, definir um método como privado no Ruby pode não significar muita coisa, já que outro programador pode alterar esta característica com facilidade. Mas ainda assim, definir um método como privado é como dizer aos outros programadores que aquele método faz parte do funcionamento interno daquela classe e que o programador original quer se manter no direito de realizar qualquer tipo de alteração necessária sem se preocupar se alguém está usando ou não aquele método. Isto tem tudo a ver com encapsulamento, e pode fazer toda a diferença quando surgir a necessidade de alterar algum comportamento do objeto.

Toda vez que você constrói um novo objeto, você está construindo uma nova API. Cabe a você então decidir o que deve ser exposto e o que faz parte dos mecanismos internos deste objeto. Desta forma, quando surgir a necessidade de alterar alguma coisa, você não precisará se preocupar tanto com quantas classes serão afetadas pela mudança. Ao marcar um método como privado, você está se resguardando e garantindo que não causará danos ao restante do sistema, já que você está dentro da fronteira do encapsulamento, podendo assim refatorar seu código sem dor na consciência.

Por favor, não saia simplesmente injetando código em suas classes. Pense!

Comments