MetaObject: mudanças entre as edições
Criou página com 'Meta Object é o '''Objeto do Objeto'''! Mais fácil que isso só dois disso!!! Se não entendeu continue lendo... A definição da 'Meta Dados' é "A informação da Informa...' |
|||
(Uma revisão intermediária pelo mesmo usuário não está sendo mostrada) | |||
Linha 43: | Linha 43: | ||
= Constantes Vs. Métodos = | = Constantes Vs. Métodos = | ||
Para evitar que o MetaObject seja instanciado o tempo todo, cada Meta Object tem uma contante chamada "VO" que carrega uma instância estática do objeto. A maneira correta de utilizar o MetaObject seria a seguinte (de acordo com o exemplo de PersonVO citado acima): | |||
{{java|Utilização do MetaObject por Métodos|<syntaxhighlight lang="java"> | |||
PersonVO_.VO.fullName() //Retorna a String "fullName" | |||
PersonVO_.VO.dad().path() //Retorna a String "dad" | |||
PersonVO_.VO.dad().fullName() //Retorna a String "dad.fullName" | |||
</syntaxhighlight>}} | |||
A sintaxe citada acima é que é definida por métodos. É a melhor e mais simples maneira de se referenciar os atributos ou suas cadeiras de atributos. | |||
Porém, há ainda as constantes de atributos. As constantes sequem a seguinte sintaxe: | |||
{{java|Utilização do MetaObject por Constantes|<syntaxhighlight lang="java"> | |||
PersonVO_._fullName //Constante com a String "fullName" | |||
PersonVO_._dad //Retorna a String "dad" | |||
</syntaxhighlight>}} | |||
Para um atributo direto do VO (que não retorne outro VO), não há diferença entre um método e outro. Isto é "PersonVO_.VO.fullName()" ou "PersonVO_._fullName" tem exatamente o mesmo resultado. Mas note que nessa sintaxe a constante '_dad' retorna diretamente a String "dad" ao invés do MetaObject do objeto retornado pelo atributo 'dad' original do VO. '''Isso impossibilita que seja montada uma cadeia completa com atributos aninhados!''' | |||
Se o acesso por constantes tem menos funcionalidades, para que existem ambos? Em alguns casos a referência ao atributo precisa ser uma constante final. Como por exemplo a referência de atributos dentro de Annotations. Nestes casos a utilização do método não pode ser utilizado, pois o java entende que o retorno de um método não será constante. | |||
Mas e se na annotation eu precisar referenciar um atributo aninhado? Como obter o caminho completo? A resposta é que não tem como obter diretamente. Mas mesmo assim recomendamos a utilização dos MetaObjects. Por exemplo para obter o mesmo resultado de "PersonVO_.VO.dad().fullName()" (que seria "dad.fullName") teriamos de utilizar o seguinte código: | |||
{{java|Utilização do MetaObject por Constantes|<syntaxhighlight lang="java"> | |||
PersonVO_._dad + "." + PersonVO_._fullName | |||
</syntaxhighlight>}} | |||
Desta forma temos o mesmo resultado utilizando apenas os acessos de constantes. Embora mais trabalhoso, e ainda passível de se montar um caminho de atributos inválidos, o código continuará "quebrando" caso alguma das propriedades mude ou deixe de existir. Melhorando a qualidade do código evitando BUGs e erros. | |||
= Escrevendo o MetaObject = | = Escrevendo o MetaObject = |
Edição atual tal como às 20h41min de 19 de maio de 2019
Meta Object é o Objeto do Objeto! Mais fácil que isso só dois disso!!! Se não entendeu continue lendo...
A definição da 'Meta Dados' é "A informação da Informação". Por exemplo, se você tem a informação do tipo texto "Eu amo o BIS". Essa informação contém outras informações, como "tamanho", "charset", "língua", etc.. Essas informações (dados) da própria informação são chamadas de 'Meta Dados'.
De forma similar o BIS tem seus 'Meta Objects', que tem a finalidade de descrever seus próprios objetos. No caso, são utilizados para descrever cada um dos BISVO do sistema.
O Problema
Em várias partes do BIS Framework há processos automatizados com métodos que tratam as classes BISVO (ou suas herdeiras), no entanto sua implementação não conhece especificamente cada objeto. É possível orientá-lo a obter o atributo correto a partir de uma String de parâmetros.
Por exemplo, imagine que estamos montando um relatório de clientes. Os dados seriam uma coleção de PersonVO. Para montar o relatório queremos que o Framework crie uma coluna com o atributo "fullName". E que dentro de PersonVO, temos a referência para outro PersonVO que indica seu pai, no atributo "dad". E queremos outra coluna com o nome completo do pai.
Ao passar os caminhos para o framework por String seriam "fullName" e "dad.fullName".
O problema de passar por String é que se o atributo deixar de existir ou qualquer alteração/refactory que mude o atributo, ou ainda qualquer tipo de erro de digitação, fará com que o código compile normalmente mas não funcione. E mesmo que ele seja testado na hora, alterações futuras podem fazer com que o código deixe de funcionar em outras partes do sistema. Tupo por não haver validação dos atributos dentro da String.
Para resolver isso existe o MetaObject. O Meta object é um objeto espelho do VO, que descreve o VO e seus métodos e atributos. De forma que ele monta a String a ser passada somente durante o RunTime. Durante o tempo de compilação ele mantém métodos que deixam de existir caso o atributo deixe de existir. O que fará com que o código "quebre" já com erros de compilação.
Funcionamento
O MetaObject por padrão tem o mesmo nome que o VO a qual ele descreve e é salvo no mesmo package, com a única diferença que leva um sufixo '_'. Ou seja, caso tenhamos um PersonVO no sistema, o seu MetaObject seria o PersonVO_, salvos um "do lado do outro".
Este objeto tem métodos co o exato nome do atributo do VO que ele representa. Por exemplo, se o PersonVO tem um atributo 'fullName', o PersonVO_ terá um método 'fullName()', que retornará a String 'fullName' como desejado para passar para o Framework.
Nos casos em que o atributo retorne outro VO, como no nosso exemplo do PersonVO com o atributo 'dad' que retorna outro PersonVO, o PersonVO_ terá um método chamado 'dad()', que dessa vez não retorna uma String, mas sim o MetaObject do objeto retornado no VO. No nosso caso o próprio PersonVO_. E então conseguiríamos obter o caminho para o atributo 'fullname' do objeto retornado a partir do retorno de 'dad'. O código ficaria assim:
dad().fullName()
O que retornaria a String "dad.fullName", como esperado pelo Framework. E com a vantagem que esse código "quebra" se dad ou fullname deixarem de existir em PersonVO.
Imagine agora que você queira o caminho de 'dad' e não de um atributo dentro de dad. E dad não retorna a String, retorna outro MetaObject de PersonVO. Nestes casos, pode-se chamar o método path(). Que força o retorno do caminho até aquele ponto, sem obter um atributo dentro do MetaObject retornado. Por exemplo:
dad().path()
Essa código retornará a String "dad".
A partir deste funcionamento podemos obter e descrever o caminho para qualquer propriedade de um VO independente de quantas referências ou "níveis de cadeia" um VO tenha dentro do outro.
Constantes Vs. Métodos
Para evitar que o MetaObject seja instanciado o tempo todo, cada Meta Object tem uma contante chamada "VO" que carrega uma instância estática do objeto. A maneira correta de utilizar o MetaObject seria a seguinte (de acordo com o exemplo de PersonVO citado acima):
![]() |
Utilização do MetaObject por Métodos
PersonVO_.VO.fullName() //Retorna a String "fullName"
PersonVO_.VO.dad().path() //Retorna a String "dad"
PersonVO_.VO.dad().fullName() //Retorna a String "dad.fullName"
|
A sintaxe citada acima é que é definida por métodos. É a melhor e mais simples maneira de se referenciar os atributos ou suas cadeiras de atributos.
Porém, há ainda as constantes de atributos. As constantes sequem a seguinte sintaxe:
![]() |
Utilização do MetaObject por Constantes
PersonVO_._fullName //Constante com a String "fullName"
PersonVO_._dad //Retorna a String "dad"
|
Para um atributo direto do VO (que não retorne outro VO), não há diferença entre um método e outro. Isto é "PersonVO_.VO.fullName()" ou "PersonVO_._fullName" tem exatamente o mesmo resultado. Mas note que nessa sintaxe a constante '_dad' retorna diretamente a String "dad" ao invés do MetaObject do objeto retornado pelo atributo 'dad' original do VO. Isso impossibilita que seja montada uma cadeia completa com atributos aninhados!
Se o acesso por constantes tem menos funcionalidades, para que existem ambos? Em alguns casos a referência ao atributo precisa ser uma constante final. Como por exemplo a referência de atributos dentro de Annotations. Nestes casos a utilização do método não pode ser utilizado, pois o java entende que o retorno de um método não será constante.
Mas e se na annotation eu precisar referenciar um atributo aninhado? Como obter o caminho completo? A resposta é que não tem como obter diretamente. Mas mesmo assim recomendamos a utilização dos MetaObjects. Por exemplo para obter o mesmo resultado de "PersonVO_.VO.dad().fullName()" (que seria "dad.fullName") teriamos de utilizar o seguinte código:
![]() |
Utilização do MetaObject por Constantes
PersonVO_._dad + "." + PersonVO_._fullName
|
Desta forma temos o mesmo resultado utilizando apenas os acessos de constantes. Embora mais trabalhoso, e ainda passível de se montar um caminho de atributos inválidos, o código continuará "quebrando" caso alguma das propriedades mude ou deixe de existir. Melhorando a qualidade do código evitando BUGs e erros.
Escrevendo o MetaObject
Bom, tudo isso é legal, mas é muito trabalhoso ter que ficar escrevendo e editando o MetaObject a cada vez que faço uma alteração no VO.
FATO! Por isso o BIS conta com um Plugin para Eclipse que sempre que vc escrever uma clase cujo nome termine com VO e que estenda BISVO, ele gera automaticamente a classe do lado do VO.
Para instalar e fazer o BISMetaObjectGenerator verifique a página de instalação do ambiente do BIS: Preparação dos Ambientes.