Nomenclatura 

Aug/11
20

Pode n√£o parecer, mas a nomenclatura ajuda bastante a manter um c√≥digo limpo, coeso , coerente e de f√°cil entendimento. Nos tempos em que se fala muito de DDD (Domain Driven Development) muitos se esquecem que t√©cnicas como o gloss√°rio de projeto e o uso dos nomes do dom√≠nio nas entidades sempre foram boas pr√°ticas. Estas pr√°ticas forma pedidas no tempo por v√°rias raz√Ķes mas principalmente pela defici√™ncia das linguagens de programa√ß√£o em libertar o programador e deix√°-lo usar os nomes que quisesse. T√©cnicas como a nota√ß√£o h√ļngara muito famosa nos tempos √°ureos de linguagens como VB (pr√© .NET) e Delphi e que √© usada at√© hoje na programa√ß√£o e nomenclatura do Windows, por exemplo, ajudaram a empobrecer e apodrecer essas boas pr√°ticas relacionadas a dar o nome certo √† coisa certa.

O Java, e mais propriamente a Sun no seu compêndio de boas práticas, deixaram claro que a nomenclatura é vital para o sucesso de um API. A nomenclatura tem várias facetas, e todas elas devem ser consideradas.

Tipografia

A tipografia dos nomes é importante. Em java foi criado o padrão de usar nomes em Camel Case. Você deve conhecer o Upper Case ( Caixa Alta) que significa que todas as letras da palavra são maiusculas Рpor exemplo : SERVICODECOBRANCA -, o Lower Case (Caixa Baixa) em que todas as letras das palavras são minusculas Рpor exemplo : servicodecobranca. O Camel Case (Caixa Camelo) é quando todas as letras inicias das palavras são maiusculas e o resto minusculas Рpor exemplo: ServicoDeCobranca. Note como os seus olhos entendem melhor o camel case do que qualquer outro case já que as maiusculas atuam como separadores naturais.

Outras linguagens adotam padr√Ķes diferentes como o uso de underline (por exemplo: servico_de_cobranca) que o java utiliza tamb√©m em certas circunstancias. A tipografia de uma constante √© uma mistura do Upper Case com o uso de underline (SERVICO_DE_COBRANCA).

√Č importante que todo o seu codigo seja escrito com a mesma tipografia. Muitas pessoas se habituaram a usar o eclipse e as suas milhentas formas de pintar texto para separar as coisas, mas usando uma tipografia padronizada ( a que a Sun criou e recomendou por anos) voc√™ n√£o precisa de cores e estilos.

Justaposição

A justaposi√ß√£o √© um dos mecanismos que existe nas l√≠nguas para criar novas palavras. A justaposi√ß√£o se caracteriza por simplesmente justapor (colocar as palavras juntas) sem nenhum tipo de modifica√ß√£o das palavras. Por exemplo, guarda-chuva e passatempo. Note que as palavras n√£o foram modificadas. Enquanto que outras formas de cria√ß√£o de palavras como a aglutina√ß√£o levam √† modifica√ß√£o das palavras originais. Por exemplo , planalto (= plano + alto) em que o ultimo ‘o’ de planalto desaparece.

A justaposição é a forma mais simples de criar nomes para classes, métodos e variáveis já que não é necessário modificar a palavra original, e, no caso, não nos precisamos preocupar com sinais como o hífen já que o Camel Case separa as coisas para nós.

Língua

√Č importante escolher a l√≠ngua do seu c√≥digo. Isto √© mais complexo do que parece. A l√≠ngua inglesa √© mais simples de usar j√° que em ingl√™s a justaposi√ß√£o √© muito natural e soa bem. Em portugu√™s nem sempre soa bem juntar v√°rias palavras juntas. Al√©m disso nomes de padr√Ķes de projeto s√£o em ingl√™s , e como veremos adiante, √© comum usar esses nomes ao compor nossas nomenclaturas. DesktopSingleton (Desktop + Single + ion) soa bem melhor que TopoDeMesaSolteirao (Top da Mesa + Solteiro + i√£o). Poderiamos pensar num DesktopSolteiao ou TopoDeMesaSingleton, mas ai √© misturar o pior de cada parte.¬† Usar ingl√™s tamb√©m tem a vantagem de n√£o usar acentos e outros dilacr√≠licos (√© por isso que se escreve facade e se l√™ fa√ßade), que embora a l√≠ngua inglesa os aceite¬† ( Fa√ßade √© uma palavra inglesa escrita com √ß porque v√™m do franc√™s) n√£o √© comum vermos usar ( porque os teclados as pessoas que falam ingl√™s nativamente, n√£o t√™m o caractere √ß).

A resist√™ncia de muitos a usar o ingl√™s adv√©m de dois problemas : 1) falta de vocabul√°rio e 2) pode violar a regra de que se deve usar um gloss√°rio de projeto. O primeiro motivo √© f√ļtil e qualquer dicionario pode resolver isso. O segundo motivo √© mais s√©rio. Se o cliente fala portugu√™s nativamente e define seus conceitos de negocio em portugu√™s porque ent√£o traduzir isso para ingl√™s? Algumas coisas at√© seriam triviais : produto -> product , cliente -> costumer , mas fatalmente cair√≠amos no Nota fiscal -> ? , Pedido -> ? ou CPF -> ? . Assim muitos preferem usar uma mistura de ingl√™s com portugu√™s, usando o ingl√™s para c√≥digo de infra e padr√Ķes e o portugu√™s para objetos de negocio.

O meu argumento √© que se voc√™ realmente quiser voc√™ consegue usar apenas nomes em ingl√™s. O lance √© utilizar o dom√≠nio em ingl√™s tamb√©m. Por exemplo, a nota fiscal √© um documento que prova que o objeto √© seu, que voc√™ o comprou. Desse ponto de vista ele √© uma “nota de venda”¬† e a tradu√ß√£o seria “bill of safe”(literalmente nota (bill) de (of) venda (sale)).¬† Pedido seria Invoice, embora invoice possa ter significados mais refinados ligeiramente diferentes de pedido, mas cont√©m os mesmos itens b√°sicos: quais os itens, quantos, de quem, para quem. J√° o CPF √© algo pr√≥prio do pais e nem sequer do dom√≠nio do negocio de compra e venda. Est√° mais relacionado a impostos. Contudo poder√≠amos criar um nome que traduzisse o conceito em vez de traduzir o nome, por exemplo Individual Tax Registry Code (ITRC). Rebuscado ? Depende. Para um sistema feito em pais de l√≠ngua oficial portuguesa para pessoas que falam portugu√™s nativamente, definitivamente. Mas para software que ser√° usado no estrangeiro ou que pretende se adequar a v√°rios mercados, ou que se pretende que seja open source, talvez n√£o seja t√£o absurdo.

A moral aqui √© que deve ser considerado o objetivo e o publico alvo do software e do c√≥digo de forma que para os usu√°rios do software o c√≥digo possa fazer sentido. Isto em DDD se chamaria de usar a linguagem ubiqua, mas na realidade estamos adequando o m√°ximo poss√≠vel o c√≥digo ao gloss√°rio.¬† Por outro lado, se voc√™ consegue fazer c√≥digo de infra em ingl√™s por que n√£o c√≥digo de negocio ? A resposta √© que voc√™ conhece o dom√≠nio “infra” muito melhor, e √© natural para si – programador – usar ingl√™s. Apenas isso.

Depois que decidir que língua usar , ou como misturar duas línguas, mantenha-se fiel à escolha.

Substantivos

Vimos v√°rias coisas que ajudam na nomenclatura, mas existem regras para criar os nomes eles mesmos ? Existem.

Classes e Interfaces t√™m nomes simples que refletem diretamente os conceitos do modelo de negocio. Sem prefixos ou sufixos. Se quer modelar um cliente use “Cliente” como nome da classe. Se for uma interface n√£o use “ICliente” por exemplo. A raz√£o disto √© simples : polimorfismo. Se eu digo “Veiculo” voc√™ n√£o sabe se √© uma interface ou uma classe. √ďtimo. √Č assim mesmo que tem que ser. Se eu usar “IVeiculo” automaticamente estou dizendo que √© uma interface, o que viola o proposito do polimorfismo.Al√©m de que aquilo que hoje definiu como interface, amanh√£ pode virar um classe. O modelo evolui. O uso do I √© uma remanescencia da nota√ß√£o hungara e √© usado na corrente .NET j√° que essa corrente herdou v√°rias coisas dos antepassados VB, Delphi e do codigo do windows, como comentei antes. √Č l√≠cito usar o I em .NET porque essa √© a conven√ß√£o nesse ambiente, mas em pura orienta√ß√£o a objetos , e no java, n√£o.

Se eu precisar criar um objeto utilizando o padr√£o Builder ent√£o justaponho os nomes como ClienteBuilder ou VeiculoBuilder. Normalmente os builders s√£o mais usados com interfaces, mas isso n√£o obrigatorio. Aqui a l√≥gica √© utilizar o nome do padr√£o como sufixo e aproveitar o nome do conceito. Usando este padr√£o de nomenclatura teriamos por exemplo ClienteProxy, ClienteRepository, ClienteFactory, etc… Contudo n√£o se utiliza este padr√£o com singleton nem para as implementa√ß√Ķes do padr√£o Service. N√£o se nomeia ClienteSingleton. Isto pela mesma raz√£o do uso do I em interfaces : quebra o polimorfismo e o que hoje √© singleton, amanh√£ poder√° deixar de ser.

Na quest√£o do padr√£o service, definimos uma interface como o contrato do servi√ßo e mais do que uma implementa√ß√£o. Cada implementa√ß√£o √© especializada por alguma raz√£o e isso distingue uma implementa√ß√£o do servi√ßo das outras.Por exemplo , para o servi√ßo PrintService poderiamos ter um PDFLocalFilePrintService , um SystemPrinterPrintService e um WebRemotePrintService (como exerc√≠cio, experimente colocar estes nomes em portugu√™s). Todas as implementa√ß√Ķes terminam com o nome do servi√ßo mas descrevem o objetivo da implementa√ß√£o. √Č claro que a primeira implementa√ß√£o ir√° criar um PDF em disco local, a segunda usar√° uma impressora de fato e a terceira algum servi√ßo de impress√£o via web ( sem dizer se ser√° em uma impressora ou arquivo). Isto se aplica tamb√©m ao padr√£o DAO (que √© uma especializa√ß√£o do padr√£o de servi√ßo) onde teremos coisas como JDBCClienteDAO ou BigTableClienteDAO ou LDAPClienteDAO. O uso de Impl com o sufixo (ClienteDAO e ClienteDAOImpl, por exemplo) al√©m de amb√≠guo e desinformador (como √© a implementa√ß√£o ?) √© pura falta de imagina√ß√£o.

A mesma regra de nomenclatura pode ser seguido em geral com interfaces onde antes do nome da interface é dito algo sobre como aquela implementação é diferente das outras. Exemplos classicos são ArrayList , LinkedList e HashSet e LinkedHashSet ( este é duplamente qualificado)

Este regra de momenclatura tamb√©m funciona bem quando voc√™ quer juntar conceitos que n√£o s√£o necess√°riamente padr√Ķes de projeto, mas que voc√™ definiu um conjunto de classes com um proposito semlhante, por exemplo ClienteManager se vc criou o conceito de Manager ou XMLTextTransformer se voc√™ criou o conceito de TextTransformer. N√£o necess√°riamente estas classes herdam de Manager ou TextTransformer, pode ser uma classifica√ß√£o puramente conceptual. (Se for puramente conceptual recomenda-se que crie uma interface marcadora e fa√ßa todos os objetos que partilham o mesmo conceito implement√°-la. Leia Heran√ßa e Interfaces para mais detalhes deste assunto)

Uma variante do padr√£o de sufixo indicando padr√Ķes de projeto, embora n√£o utilize o nome de um padr√£o √© o sufixo “Utils”. MathUtils ou DateUtils ou ClienteUtils. Este tipo de classes cont√©m apenas m√©todos est√°ticos √© final e sem construtor publico. Em certos casos √© poss√≠vel utilizar a variante no plural do nome como Clientes ou, retirando exemplos do pr√≥prio java : Collections e Arrays. Contudo √© mais raro que esta forma de nomenclatura soe bem ou encaixe em qualquer situa√ß√£o.

Para classes abstratas √© √ļtil utiliza Abstract como prefixo AbstractCliente ou AbstractPrintService. Este padr√£o pode ser usado mesmo quando a classe n√£o √© abstrata no sentido t√©cnico ( n√£o √© definida como “abstrat class”) mas √© abstrata no sentido do modelo ou do negocio. Ou seja, olhando para o nome sabemos que n√£o √© suposto instanciarmos esta classe e sabemos tamb√©m que devem haver classes herdando dela. Uma classe com Abstract no nome pode herdar de outra com Abstract no nome, contudo sabemos que no fim da linha de heran√ßa existir√° pelo menos uma classe n√£o abstrata que poderemos utilizar. Este padr√£o √© especialmente util quando o nome a seguir a abstract se refere a uma interface, por exemplo, AbstractList do java.

Especialmente para interfaces muitas vezes elas caracterizam n√£o entidades ( substantivos) mas a√ß√Ķes que podem ser feitas (adv√©rbios). Em ingl√™s √© muito f√°cil transformar qualquer palavra em adverbio e aqui √© um dos exemplo onde √© vantagem utilizar o ingl√™s. Para um a√ß√£o como Print, teriamos Printable (que pode ser impresso) ou mais complexo como Mergeable ( que pode ser jeito merge). Em portugu√™s tamb√©m funciona se usar o prefixo “-vel” ou suas varia√ß√Ķes como “Junt√°vel” , “Imprim√≠vel” , “Fund√≠vel”, mas √© aqui que come√ßa a ficar esquisito. Na API do java temos Serializable e Clonable como exemplos desta forma de nomenclatura.

Um outro padr√£o de projeto que tem uma nomenclatura diferenciada √© o Adapter. Aqui estamos tentando usar uma classe com a “cara” de outra. Para o adapter √© bom usa a regra [InterfacePublica][ObjectoPrivado]Adapter. Por exemplo,¬† InjectorSpringContextAdapter. Daqui podemos inferir que se trata de um objeto no padr√£o adapter, que implementa uma interface chamada Injector e usa um SpringContext por baixo dos panos. Ou seja, o contexto do spring est√° sendo adaptado ao contrato de um Injector.

Resumo

Nomenclatura coerente das suas classes e interfaces é uma boa forma de documentação do código, ajuda a manter os conceitos de negocio e os conceitos técnicos frescos, evita ambiguidade e, se bem usada, ajuda a identificar a camada a que pertence a classe.  São regras simples que todos podemos seguir, e com isso ajudar que todos entendamos o código uns dos outros.

Mais informação

Informação adicional pode ser encontrada em Princípios : Nomenclatura.

Um comentário para “Nomenclatura”

  1. Muito bom o artigo! Por√©m, uma ressalva: apesar de singleton tamb√©m significar “solteiro”, acredito que no contexto de design patterns signifique “um conjunto com apenas um elemento”, que √© uma das tradu√ß√Ķes do verbete (o nosso “Conjunto Unit√°rio).

Comente

Artigos