Mas o que é Modelo Canônico afinal? – Parte 2

No ultimo post, comentei que o Modelo Canônico seria o modelo de dados universal utilizado pela camada SOA e que sua modelagem difere da modelagem tradicional.

Normalmente primeiro aprendemos a modelar banco de dados relacional, que tem como principal preocupação a normalização dos dados. Mais tarde aprendemos a modelar orientado a objetos, onde a normalização não é tão importante, a  distribuição de responsabilidades, alta coesão e baixo acoplamento são mais importantes. Em SOA, a modelagem muda novamente, agora os dados e comportamento estão separados novamente. Distribuição de responsabilidades, alta coesão e baixo acoplamento continuam importantes, porém a ‘normalização semântica’ dos dados ganha maior força pois o escopo agora é muito maior. Quando falamos de recursos RESTful, a modelagem muda completamente.

Costumo dizer que modelagem é um assunto indigesto, pesado. Digo isso porque leva um tempo para ser digerido, assimilado, e isso só é alcançado através de exercícios, ou seja, só se aprende fazer fazendo! Mas existem algumas ‘dicas’ que podem ajudar a encurtar este caminho.

A parte mais dificil e complexa na modelagem do Modelo Canônico é a ‘normalização semântica’, então vamos deixa-la para o próximo post, começando pela parte técnica:

  • Como estamos falando em SOA e a maioria das implementações utiliza SOAP, a implementação do Modelo Canônico é em XML Schema;
  • Deve ser definida um padrão de nomenclatura. Normalmente é utilizado como em java, UpperCamelCase para os tipos (complexType) e lowerCamelCase para campos (element);
  • Como as entidades do Modelo Canônico são reutilizadas por várias operações, não é possível definir a obrigatoriedade dos campos (elementos). Por este motivo todos os campos devem ser opcionais utilizando o atributo minOccurs="0" e não devem possuir nenhum tipo de restrição, como limite de tamanho;
  • Utilize element para representar os campos, não attributes;
  • Não utilize referência cíclica, mais conhecida como relacionamento bi-direcional. Por exemplo: se a entidade Cliente possui um relacionamento com a entidade ContaCorrente não deve ser criado um relacionamento da entidade ContaCorrente para Cliente. Isso pode gerar problemas de performance e incompatibilidade em alguns clients / ferramentas;

Depois da parte técnica, existem alguns tópicos relacionados a modelagem:

  • Evite criar relacionamentos entre entidades muito independentes. Este tipo de composição pode ser feito na interface do serviço;
  • Eventualmente uma associação é identificada, porém não é necessário que tais informações sejam estruturadas. Neste caso a desnormalização pode ser usada. Por exemplo: a entidade Endereço possui todos os campos do entedereço estruturados, porém para a entidade Nota Fiscal esta normalização não é necessária, podendo ser um único campo texto;
  • Em alguns casos similares ao exemplo acima o tipo de informação de uma determinada entidade muda de acordo com o contexto. Por exemplo para o contexto de faturamento o Cliente possui algumas informações e para o contexto de CRM possui outros. Neste caso a entidade Cliente pode ser ‘quebrada’ de acordo com o domínio;

Modelagem é um assunto complexo e subjetivo. Cada tópico acima pode se extender por vários posts e ainda existem outras considerações a respeito da modelagem de Modelo Canônico que serão tratados no próximo post.

  • Roger

    Olá Felipe!

    Uma dúvida sobre a técnica de desnormalização que você exemplificou com o endereço na entidade Nota fiscal.
    Os legados na grande maioria trabalha com o endereço na nota fiscal normalizado, acredito que isso por causa da herança da modelagem relacional. Qual sua opinião neste caso, para quando o legado tem um serviço que recebe os dados normalizados, acha interessante no canônico os dados estarem desnormalizados e fazer um trabalho de normalização para este serviço do legado e vice-versa?

    • Oi Roger,

      Este tema é complicado devido a sua alta subjetividade, principalmente quando não temos um cenário bem definido. O caso que você comentou talvez não seja o melhor candidato a desnormalização, considerando que é complicado ‘quebrar’ o endereço desnormalizado para a API do legado. Na consulta esse problema não aconteceria, pois seria uma simples concatenação de campos.

      Acabei não comentando no post, mas não existe modelagem certa ou errada, o que existe é modelagem boa e modelagem ruim. Em um determinado cenário ambas abordagems podem parecam boas, mas provavelmente com o decorrer do tempo a desnormalizada apresentará menos problemas na evolução por ser menos acoplada.

      Normalmente candidatos a desnormalização são aqueles onde a modelagem normalizada foi complicada, dando a sensação que a entidade foi mal modelada.

  • Roger

    Obrigado pela resposta Felipe!

  • Pingback: Modelo Canônico – Normalização Semântica | Felipe Firmo()

  • Hugo Marques

    Olá Felipe, muito bom os artigos. Ficaram algumas dúvidas, você conseguiria esclarece-las, por favor?

    1. A título de curiosidade: Por que não devemos utilizar atributes e sim elements nos atributos?
    2. No exemplo acima você citou para quebrar a entidade clientes, isso não traria problemas em termos ClienteCRM/Cliente/ClienteXPTO etc? E se mais na frente for preciso identificarmos que uma mesma informação representada em todos esse clientes deve ser alterada?
    Abraços

  • Obrigado Hugo!

    Quanto as suas perguntas:
    1. Acabei não comentando, mas por convenção acabamos usando elementos para dados e atributos para meta-dados (quando necessário). Estes metadados podem ser algum código sistêmico que não foi possível/viável remover da camada SOA ou meta-dados referentes a paginação por exemplo.

    Mas respondendo mais diretamente sua pergunta, elementos são mais flexiveis, facilitando evolução e aumentam a legibilidade.

    2. Como estariam em namespaces diferentes, todas as entidades Cliente poderiam ter o mesmo nome, mas em contextos diferentes (não aconcelharia uma modelar uma entidade com o nome ClienteCRM por exemplo). Cada uma destas entidades teriam um subset diferente de atributos, uma com dados financeiros, outra com dados cadastrais, etc. Para resolver o problema de dados duplicados é possível (e aconcelhavel) usar o recurso de herança.

    Porém este problema pode ser minimizado utilizando um modelo informacional como mencionado neste post

    Finalmente, só arranhei a superficie deste extenso e controverso assunto de Modelagem de Modelo Canônico.