O que faz o seu Tipo ? 

Jul/10
16

Quando uma pessoa aprende a programar em Java, especialmente se ela j√° programava em outra linguagem antes,¬† ela n√£o olha a linguagem java como uma forma de escrever descri√ß√Ķes de objetos mas apenas como um conjunto de “comandos” que est√£o sendo dados. Isto √© uma pena. N√£o s√≥ √© uma pena, mas a raz√£o de muitos erros de estrutura√ß√£o de codigo em java. A primeira coisa necess√°ria para programar em Java √© conhecer Programa√ß√£o Orientada a Objetos, pois apenas assim faz sentido aquilo que o java oferece.

O primeiro erro é confundir objeto com estrutura de dados. Em algumas linguagens não orientadas a objetos é possivel trabalhar com tipos que compoem diferentes variáveis numa variável só agrupando dados de forma mais concisa. Estas estuturas auxiliam na passagem de parametros, e até na tipagem do programa, mas  não são objetos.Contudo, é comum não conseguir diferenciá-los porque ambos têm atributos.

Objectos não são apenas formados por atributos, eles são também formados por comportamento. Este comportamento pode, ou não, depender do valor dos atributos ou operar sobre eles. Claro que é possivel também conceber objetos que apenas detêm comportamento sem nenhum atributo ou propriedade. Mas não é isto que diferencia uma estrutura de dados de um objeto.

Um objeto se diferencia de uma estrutura de dados porque t√™m uma responsabilidade. A responsabilidade adv√©m do papel que o objeto representa no sistema, e esse papel adv√©m do significado que o objeto t√™m no sistema. A responsabilidade do objeto leva a uma classifica√ß√£o do objeto por papeis no sistema e a exist√™ncia de v√°rios objetos que se auxiliam para formar o sistema induz a uma classifica√ß√£o hierarquizada. Portanto, uma outra forma de dizer que objetos t√™m responsabilidade √© dizer que objetos pertencem a uma hierarquia de classifica√ß√Ķes.A existencia de hierarquia de classifica√ß√£o est√° intimiamente ligada √† opera√ß√£o de heran√ßa ( que seria impossivel existir sem dita hierarquia).¬† Estruturas de dados, n√£o pertencem a uma hierarquia, e¬† portanto, embora fisicamente semelhantes, estruturas de dados n√£o s√£o objetos.

Mas podem objetos ser estruturas de dados ? A resposta rápida é : sim. A resposta longa é : podem, mas apenas se essa for a sua responsabilidade.

Objetos não se podem eximir de possuir responsabilidade e é um desafio manter apenas uma responsabilidade por objeto. Mesmo quando o desenvolvedor é inexperiente todo o objeto usado ganha uma responsabilidade no sistema mesmo quando o desenvolvedor não é consciente disso e atribuir a responsabilidade correta é que é o real desafio da programação orientada a objetos.

A programação orientada a objetos advém dos principios de modelagem orientada a objetos que é uma atividade abstrata em si mesmo e independente de qualquer tecnologia ou linguagem de programação.  Modelar o objeto corretamente passa por definir seus atributos e métodos, mas principalmente por definir sua responsabilidade.

Se um objeto pode ser uma estrutura de dados, isso significaria que a responsabilidade¬† do objeto √© manter referencia a dados.¬† Isso nos leva a duas prespetivas. A primeira √© a do objeto que √© apenas um cabide de dados e permite transportar os dados de forma agrupada de um ponto do sistema para o outro, sendo o objeto totalmente neutro em rela√ß√£o √† raz√£o dos dados estarem agrupados daquela forma e terem aqueles valores. Esta seria a melhor aproxima√ß√£o a uma estrutura de dados convencional, n√£o orientada a objetos. Por outro lado, podemos pensar no objeto que atua como protetor dos dados que guarda, mantendo coerencia nos valores e com pelo conhecimento de porqu√™ aqueles dados est√£o agrupados.O primeiros s√£o meros objetos de transporte (Transport Objects, TO) e os segundos s√£o objetos de valor (Value Objects, VO). √Č clara a diferen√ßa entre estes dois tipos.¬† Poderiamos argumentar que o objeto de valor que agrupa os valores por uma raz√£o e com conhecimento dessa raz√£o, acaba servindo, tamb√©m, para transportar esses dados de um ponto do sistema para outro. Aqui jaz a diferencia√ß√£o:¬† os dados que o TO transporta podem ser utilizados em diferentes pontos do sistema, como o sistema bem entender. Todos os dados s√£o publicos e a sua manipula√ß√£o √© livre. Os dados que o VO cont√©m n√£o podem ser utilizados desassociadamente ou condicionalmente conforme os interesses do sistema. O sistema est√° obrigado a seguir as regras que o pr√≥prio VO imp√Ķe.

Em modelagem orientada a objetos aprendemos que os conceitos do mundo real devem ser incorporados no sistema de uma forma que a coopera√ß√£o l√≥gica entre os objetos seja equivalente √† coopera√ß√£o dos conceitos ( ou dos objetos reais traduzidos por eles) no mundo real. √Č por isto que modelamos classes Cliente, Pedido e Produto e as identificamos com os conceitos de mesmo nome no mundo real¬† e ao dizermos que “O cliente faz um pedido composto de produtos” n√£o existe diferen√ßa se essas palavras se referem a objetos no sistema ou √†s entidades no mundo real.¬† Para que este mecanismo funcione, √© claro que precisamos conseguir converter os conceitos reais em objetos. A este processo que usamos para criar equivalencia entre objetos e conceitos reais d√°-se o nome de: Abstra√ß√£o.

A abstra√ß√£o dos conceitos reais √© a fonte da origem dos objetos. Abstra√ß√£o n√£o significa neste contexto fazer as coisas mais dificeis, mais universais ou mais matem√°ticas, mas apenas e s√≥ significa mapear os conceitos reais com os objetos que temos no modelo/sistema. Na realidade n√£o √© correto dizer que o mapeamento √© entre os objetos e os conceitos, e sim que √© entre os conceitos e as classes de objetos do modelo/sistema. O nome “classe” n√£o √© aleat√≥rio. Nos remete ao conceito de que todos os objetos pertecem a uma hierarquia de classifica√ß√£o, e portanto pertencem a uma ou a mais categorias (classes).¬† Portanto, modelar de forma orientada a objetos √© a realidade nada mais que criar uma (grande) arvore de categorias, ou melhor, de classes.

As classes de objetos que identificamos com conceitos do mundo real podem pertencer a 3 grandes classes de objetos : Entidades, Serviços e Valores. As classes de serviços são caracterizadas por não deter atributos ou propriedades. Todos os dados necessários à sua operação vêm do seu exterior. Entidades são caracterizadas como objetos de transporte(TO) de Valores para certas propriedades espeficicas que são,também,  mapeadas do mundo real. Por exemplo, o cliente terá uma propriedade nome cujo valor será um conjunto de caracteres que, numa certa lingua, compoem o nome do cliente. Entidades podem também ter métodos que trabalham sobre as suas propriedades e/ou cujo resultado é alterado pelos valores dessas propriedades.   Valores são objetos de valor (VO) que detém a informação sobre os valores , passo o plenoasmo, das caracteristicas das propriedades.

Existe atualmente uma confusão sobre o conceito de objeto como composição de dados e comportamento na forma de que certas pessoas confundem o fato dos objetos poderem ter dados e comportamento, com a obrigatoriedade de todos os objetos deverem ter dados e comportamento.  Isto é pura e simples sandice. O que o objeto tem que respeitar é a responsabilidade ( ou responsabilidades) inerentes à(s) classe(s) a que pertence. Por este motivo, objetos da classe de serviço não detém atributos e isso é perfeitamente normal.

No mundo real, os conceitos s√£o muito mais male√°veis que no mundo do software. Nem sempre √© trivial destinguir entre o que √© um objeto da classe de entidade, e o que √© um objeto da classe de valores. Os exemplos classicos s√£o o n√ļmero de telefone e o endere√ßo. Para um sistema comercial de compras e vendas o numero de telefone ou o endere√ßo n√£o passa de um valor de uma propriedade de alguma entidade como casa, pessoa ou cliente. Mas para o sistema dos correios o endere√ßo √© uma entidade ela mesma com propriedades e relacionamentos com outras entidades num vasto sistema de classifica√ß√£o completamente diferente daquele do sistema comercial. O mesmo poderiamos dizer do numero de telefone e da companhia de telefones. Portanto, se o conceito √© melhor modelado como um objeto da classe de entidades ou da classe de valores n√£o √© constante entre sistemas de tipos diferentes.

Tipos Prim√°rios

Todas as linguagens orientadas a objetos oferecem em maior ou menor numero um conjunto de objetos de valor pr√©-prontos que podem ser usados como objetos da classes de Valores facilmente em qualquer entidade ou sistema. Estes objetos nunca ser√£o usados como sendo da classe de entidade ou servi√ßo, e portanto √© seguro para a linguagem/plataforma de programa√ß√£o assumir algumas caracteristicas para estes objetos e de certa forma prover otimiza√ß√Ķes para eles. Em java estes tipos prim√°rios (n√£o confundir com os tipos primitivos do java) s√£o representados, por exemplo, pelas classes: String, Date, Boolean, Integer, Double e BigDecimal.

Porque estes tipos¬† est√£o sempre disponiveis e s√£o conhecidos de todos os desenvolvedores, √© comum que eles sejam usados para os valores das propriedades de objetos de transporte e/ou de valor.¬† O problema aqui √© que quando queremos modelar o numero de telefone, por exemplo, como sendo um objeto pertencente na classe de objetos de valor, decidimos escolher um dos tipos prim√°rios em vez de criar um novo tipo ( classe) para ele. Ent√£o em vez da propriedade “telefone” do cliente ser um objeto do tipo “NumeroTelefone” √© apenas um objeto String ou¬† Integer.¬†¬† O problema com esta abordagem √© a falha do processo de abstra√ß√£o. O erro √© t√£o grande e grosseiro como se a pessoa aceitasse modelar o numero de telefone usando um Double( afinal todos os Integer cabem num Double e o Double permite ter uma parte decimal que poderia ser usada para o ramal … n√£o tente isto em casa).

Para a grande maioria dos desenvolvedores parece um pre√ßo muito elevado criar uma classe com uma duzia de linhas para representar um conceito de valor. O argumento √© que isso aumentaria o numero de classes no projeto, como se existisse alguma regra dizendo que o numero de classes deve ser abaixo de algum numero m√°gico. N√£o entendo isto. Realmente n√£o consigo entender como uma desculpa destas que advem de pura pregui√ßa pode triunfar sobre um raciocinio l√≥gico, cientifico, e comprovado da modelagem orientada a objetos. O que a modelagem orientada a objetos sugere √© que o numero de abstra√ß√Ķes seja o minimo possivel. Sendo que as palavras chave aqui s√£o “possivel” e “abstra√ß√£o”.¬† √Č o numero de mapeamentos entre o mundo real e mundo dos objetos que tem que ser minimizado. Isto porque esses mapeamentos s√£o complexos e frageis¬† ( como o exemplo do endere√ßo e telefone demonstram)¬† e portanto, ter mapeamentos demais apenas aumenta a complexidade e risco do modelo estar furando em algum ponto.¬† Porque as pessoas pessoas entender “abstra√ß√£o==classe” ent√£o acham que minimizar o numero de classes est√£o respeitando este principio.¬† O problema √© que o principio da separa√ß√£o de responsabilidade √© mais importante do que a sugest√£o que comanda o numero de abstra√ß√Ķes.¬† Ou seja, quando a pessoa mapeia o numero de telefone √† classe NumeroTelefone est√° separando a responsabilidade de descrever um numero de telefone. Usar um objeto String, poupa uma classe, mas coloca sobre a classe String a responsabilidade de al√©m de descrever texto, tamb√©m descrever numeros de telefone. E convenhamos que isto √© um pouco idiota, pois se eu quiser ter um m√©todo getRamal() no numero de telefone, isto seria trivial num objeto NumeroTelefone , mas impossivel num objeto String j√° que ele n√£o √© extensivel. Mas mesmo que String fosse extensivel, n√£o o poderiamos extender e criar o nosso StringTelefone pois isso significaria aumentar uma classe no nosso projeto e seria vetado pelas mesma raz√£o (idiota) que veta a cria√ß√£o de NumeroTelefone em primeiro lugar.

√Č importante seguir principios , sugest√Ķes e boas pr√°ticas.Eu acredito muito nisto. Mas veja, existe uma ordem em que estas coisas t√™m que ser seguidas e¬† existem prioridades. O principio de separa√ß√£o de responsabilidade tem prioridade sobre todos¬† as sugest√Ķes e boas pr√°ticas que alguem imaginar.

Isto nos leva ao conceito de que, embora aos olhos destreinados pare√ßa pequeno o ganho de criar um novo tipo (classe)¬† fazer isso √© a √ļnica saida l√≥gica num caso assim. Estes “pequenos¬† tipos” ganharam um nome – Tiny Types – exactamente para deixar clara a sua import√Ęncia.¬† Mas entenda que a necessidade de batizar estes tipos de objetos apenas adv√©m do desconhecimento e incompet√™ncia tecnica da maioria dos desenvolvedores que n√£o sabe seguir os principios mais b√°sicos da orienta√ß√£o a objetos. Eles esquecem que todos os conceitos reais presentes no sistema precisam ser abstraidos e que violar isto √© criar buracos no modelo e por consequencia no c√≥digo e no sistema.

Existem outras formas de dizer a mesma coisa e revelar a mesma import√Ęncia da opera√ß√£o de abstra√ß√£o para a correta modelagem orientada a objetos.¬†¬† Uma que ganhou muita fama ultimamente √© chamada de “Linguagem Ubiqua” (Ubiquos¬† Languagem) introduzida pelo pessoal adepto da filosfia Domain Driven Development (tamb√©m chamada Domain Driven Design). O conceito aqui √© que os mesmos termos (conceitos) que as pessoas usam no mundo real¬† para se referirem aos intrevenientes no processo do mundo real que o software ir√° mimetizar devem ser usados no codigo. Isto √© exactamente o mesmo que dizer que os conceitos devem ser abstraidos.¬† A diferen√ßa √© que dizer “os conceitos devem ser abstraidos” √© uma express√£o tecnica, enquanto “os mesmos termos que as pessoas usam no mundo real¬† para se referirem aos intrevenientes no processo do mundo real que o software” √© uma express√£o usada por pessoas comuns¬† n√£o-tecnicos. As pessoas que estudaram orienta√ß√£o a objetos e conhecem a opera√ß√£o de abstra√ß√£o e n√£o a confundem com “tornar as coisas mais complexas” sempre souberam que √© excelente ideia colocar os nomes/termos/conceitos reais no c√≥digo … afinal foi por causa disso que se inventou o pr√≥prio conceito de Objeto e o paradigma de Orienta√ß√£o a Objetos : porque queriamos que os programas tivessesm a mesma expressividade que o mundo real. √Č simples desconhecimento achar que isto √© algo novo, e √© simples maldade se aproveitar do desconhecimento da maioria dos desenvolvedores – que teve uma fraca prepara√ß√£o acad√©mica – para passar a “linguagem ubiqua” como algo novo e inovador.¬† No fundo n√£o passa de uma ferramenta de marketing igual ao dos Tiny¬† Types para fazer as pessoas aceitarem o que elas deveriam ter aprendido na escola desde o come√ßo : abstra√ß√£o.

Toda e qualquer impedimento em orienta√ß√£o a objetos, seja modelagem, seja implementa√ß√£o, adv√©m do conceito de objeto ( redundante, mas importante ter sempre isto presente). O conceito de objeto significa entender que existe uma separa√ß√£o de responsabilidade e que isso que define “objeto” e o destingue de “estrutura de dados”. Simultaneamente essa responsabilidade classifica o objeto em uma hierarquia e a hierarquia de responsabilidades implica em sermos capazes de classificar em qual lugar dessa hierarquia o objeto pertence. A¬† opera√ß√£o que usamos para fazer isto √© a : Abstra√ß√£o.

A correta abstração do problema que o sistema deve resolver leva à correta hierarquia  de objetos para aquele sistema e nem sempre essa hierarquia é a mesma para sistemas diferentes. Nem sempre é claro se o conceito será mapeado como um objeto de entidade, serviço, ou um valor, um objeto de transporte ou um objeto de valor. Contudo, independentemente da classificação é mandatório que o conceito seja mapeado para um tipo, uma classe e esse é a razão por detrás dos conceitos de Tiny Type e da Linguagem Ubiqua.

O principio de separa√ß√£o de responsabilidade ( um dos 5 principios da orienta√ß√£o a objetos) tem prioridade sobre a sugest√£o de manter um conjunto minimo de abstra√ß√Ķes, e por consequencia de classes e em nenhum caso o aumento do numero de classes pode ser usado como desculpa para n√£o respeitar o principio de separa√ß√£o de responsabilidade.

Modele corretamente o seu sistema. Aprenda Orientação a Objetos e poderá fazer seus sistemas tranquilamente sem precisar de muletas. Não tenha medo de criar classes. Tenha apenas medo delas não representarem nada de util ou real no processo que o seu software está tentando desempenhar. Se todos seguirmos isto teremos menos buzz words para nos preocupar e poderemos tornar nossa atenção para o que realmente interessa.

5 comentários para “O que faz o seu Tipo ?”

  1. Sergio, parab√©ns pelo artigo muito esclarecedor. S√≥ uma d√ļvida sobre objetos de entidade e objetos de valor, teria como dar mais alguns exemplos e em qual contexto se encaixariam.

  2. No texto eu tentei diferenciar objetos de valor e valores. Objetos de valor são objetos que conhecem e de certa forma protegem os atributos que contêm.
    Valores s√£o objetos de valor especias porque sua responsabilidade se resume a proteger atributos que no seu conjunto representam uma quantidade de alguma coisa, ou o valor de uma propriedade como Cor.
    Outros exemplos de valores seriam : Integer, Double, Date, BigDecimal, String, todas as enum e implementa√ß√Ķes de padr√Ķes como Money e objetos como CPF, CNPJ, NumeroTelefone. Ou seja, todos os objetos que podem ser usados como valor de uma propriedade ou atributo.
    Entidades são objetos de valor que embora sejam formados por valores são mapeamentos com coisas da vida real que interagem. As regras dessa interação é o que queremos transportar para o codigo e para o software. Entidades são objetos participantes em atividades do software e têm papeis bastante principais. Exemplos são Cliente, Fornecedor, Produto, Estoque, Loja, Pessoa, Automovel, Embarcação, Duplicata, Cheque, Boleto, Banco, Caixa, Impressora, etc.

    Como tentei exemplificar com o endereço e o numero de telefone nem sempre um conceito do mundo real é obrigatoriamente um valor ou uma entidade, contudo, todos são Objetos de Valor e nunca meras estruturas de dados.

  3. Sergio, muito obrigado pelos esclarecimentos que trouxeram mais valor ao conceito tratado. Gostaria mais uma vez de parabeniz√°-lo pelo artigo, venho tentando adquirir esses conceitos e outros a algum tento e seus artigos est√£o me ajudando muito. Fico agradecido por compartilhar o seu conhecimento.

  4. Sergio, excelente post.

    J√° que falou sobre tiny types, gostaria de esclarecer uma d√ļvida.

    Eu concordo plenamente quando vc fala sobre SoC. Concordo que (como no exemplo citado) n√£o seja da classe String ou Integer a responsabilidade de “representar” um telefone. Entretanto, o que vc diria sobre o acoplamento que essa(s) classe(s) gerariam? n√£o ficaria muito grande? Eu at√© vejo o Spring (ou qq outro framework de IoC) como uma solu√ß√£o para isso, mas ainda assim tenho minhas d√ļvidas de se conceitualmente estaria correto us√°-lo nesse sentido.

    Em rela√ß√£o ao DDD vc est√° coberto de raz√£o. Eu comprei o livro do Evans h√° um ano atr√°s esperando algo de novo, mas na verdade √© “mais do mesmo”. Muitos adeptos dizem que a tal da “linguagem ubiqua” √© a grande novidade, mas como vc mesmo relatou, √© apenas um nome dado a um conceito que deveria ser implicito aos desenvolvedores que entendem de oriienta√ß√£o a objeto.

    Obrigado pelo post!

  5. N√£o vejo como Tiny Types geram acoplamento. Quando voc√™ usa um Date para representar uma data isso n√£o √© acoplamento. √Č a correta abstra√ß√£o do conceito pelo tipo mais pr√≥ximo que vc tem. Se vc criar uma data usando o JodaTime isso sim gera acoplamento, mas porque vc est√° usando biblioteca de terceiros, n√£o porque est√° usando Tiny Type. O spring e o IoC em geral n√£o t√™m nada que ver com isto. Voc√™ n√£o usa spring para injetar datas ou nomes em objetos (bom, pelo menos espero que n√£o). Tiny types s√£o valores , s√£o tipos especializados para representar valores. Tiny Types podem interferir com a sua biblioteca de ORM como o Hibernate, mas o Hibernate d√° ferramentas para poder manipular estes objetos tamb√©m de forma simples. N√£o existe realmente nenhuma raz√£o tecnica ou conceitual para n√£o usar tiny types.

Comente

Enquete

Sobre quais assuntos gosta de ler neste blog ?

View Results

Loading ... Loading ...

Artigos