Submarino.com.br

Property Bag

Objetivo

Agrupar um conjunto de propriedades numa unidade lógica.

Propósito

É bastante comum que se necessite trabalhar com um conjunto de valores para diferentes propriedades normalmente como argumento para um método, como resultado de um, ou como informação de configuração de um outro objecto.

Se cada propriedade fica "livre" pelo código é mais dificil saber depois onde alterá-la ou de onde lê-la. A ideia, portanto, é usar um objeto como ponto de amarração para todas as propriedades relacionadas a um certo item,ou contexto. Assim, de certa forma reforçamos a tipagem de um conjunto (sacola) de propriedades sem forçar nenhuma abstração mais elaborada.

Implementação

Existem várias formas de implementar um Property Bag em java.

java.util.Map e java.util.Properties

A forma mais simples de construir um Property Bag em java é utilizando um mapa (um objeto cuja classe implemente java.util.Map) , como por exemplo HashMap.

Esta classe já provê métodos que permitem atribuir valor a uma propriedades, listar todas as propriedades, todos os valores e todos os pares propriedade-valor. Por outro lado, o uso do mapa obriga a que todas as propriedades tenham o mesmo tipo (todas String, ou todas Color,etc...).Isto se usarmos a tipagem forte oferecida pelo recurso de tipos genéricos. Mas caso não usemos isso, poderemos ter diferentes tipos, mas à custa de uma tipagem fraca.

Embora fracamente tipado este padrão é tão util que existe até uma classe utilitária que o implementa de uma forma mais dirigida. A classs Properties implementa um mapa de String para String e ainda possibilita persistir esse mapeamento em arquivo. Muito util para configurações simples que podem ser convertidas de e para texto. O único problema é que essa conversão tem que ser feita por outro objecto que leia/escreva no objeto Properties mapeando de/para os valores corretos.

Bean

Uma forma mais fortemente tipada é utilizar uma classe java comum que permita definir o tipo de cada propriedade. Esta é a forma mais comum por ser menos propensa a erro de tipagem e relativamente fácil de programar. De tão comum esta abordagem foi batizada de Bean.

Na realidade o nome "bean" (grão) deriva da diminuição de "JavaBean" (grão de Java - um trocadilho com o grão de café Java). JavaBean é uma tecnologia de componentes padronizada na JSE no pacote java.beans. A diferença principal é que um JavaBean contém um mecanismo de geração de eventos seguindo o padrão Observer que avisa quando uma propriedade é modificada e pode até delegar o controle da mudança do valor num mecanismo em que a mudança pode ser vetada.

Um "bean" tem a mesma estrutura que um JavaBean mas sem o mecanismo de eventos. Daí a ideia de que um "bean" é um JavaBean diminuido.

A implementação do Property Bag com um bean java estabelece uma tipagem forte para os tipos dos valores das propriedades, mas não contêm mecanismos embutidos para listar essas propriedades,valores,ou pares propriedade-valor. Isto é contra-produtivo para o uso de classes para a definição de Property Bag e por conseguinte um mecanismo que permitisse isso seria necessário.

O java inclui o pacote java.lang.reflect que permite ler os métodos e atributos de uma classe através de introspeção. Este mecanismo aliado ao pacote java.beans permite tratar uma classe como a definição de um Property Bag e qualquer objeto dessa classe como uma instância de Property Bag.

Para que estes pacotes entendam que a sua classe define um Property Bag algumas convenções devem ser seguidas (chamadas de JavaBeans naming conventions):

  • A classe deve ter definir um construtor sem argumentos.
  • A classe deve ter definir um método acessor e modificador para cada propriedade, e nomeá-los corretamente. A nomenclatura consiste em prefixar o nome da propriedade com o prefixo "get" para os acessores, e o prefixo "set" para os modificadores. No caso da propriedade ter um valor logico, o prefixo do acessor deve ser "is" em vez de "get".

A convenções para JavaBeans exigem mais tipos de métodos relacionados ao controle de eventos e ao padrão Observer. Para implementar um Property Bag estes são suficientes.

Normalmente as propriedades de um Property Bag são objetos simples e não coleções de objetos (caso isso seja necessário essa coleção deverá ser encapsulada em um objeto simples), contudo nada proibe que utilize um objecto de coleção ou array como valor de uma propriedade (propriedade multivalorada), mas o seu tratamento automático é estranho. Normalmente, ao chegar nesta situação é bom começar a desconfiar que objeto que está modelando pode não ser um Property Bag.

Discussão

O padrão Property Bag, mais conhecido pela implementação do tipo Bean no lingo java, é de uso comum e muitas vezes desapercebido sendo só evidente quando se utilizam os recursos da classe Properties.

A tecnologia de objetos é fortemente vinculada a este padrão sendo muito fácil criar um Property Bag que contenham qualquer conjunto de propriedades. E é tão comum que passa desapercebido mesmo quando a pessoa nomeia as suas classes como QualquerCoisaBean.

Outra mostra de como a tecnologia de objetos é dependente deste padrão é a tecnologia de componentes Java Bean. Esta tecnologia foi extentida por meio da Java Management Extentions (JMX) transendo outros tipos de Propery Bags baseados em classes e interfaces. Estas tecnologias , e até os Enterprise Java Beans embora não sendo formados apenas de Property Bag têm este padrão na sua essência.

Exemplos na API padrão

Como já vimos a classe Properties implementa o padrão Property Bag até com possibilidade de persistencia em arquivo ( o famoso arquivo .properties). O JSE utiliza este padrão em System.getProperties() que retorna um objeto Properties com várias propriedades do ambiente de execução [1] da aplicação que permitem saber coisas interessantes como, por exemplo, o nome do sistema operacional.

Padrões associados

Property Bag pode também ser chamado de Bean, pois como vimos, essa é a essência da tecnologia Java Bean. Muitas vezes Property Bag precisam ser acessada globalmente e é util utilizar o padrão Registry.

Transfer Objects são casos particulares de Property Bag que são utilizados para transportar informaçao entre nodos, ou andares, diferentes da aplicação. Transfer Object é a Property Bag vianjante.

Value Objets podem ser entendido como Proeprty Bags de uma propriedade só que se especializam em dar suporte à leitura e manipulação dessa propriedade sem nunca a tornar acessivel a objetos exteriores.

Referências

[1] System Properties

URL: System Properties http://java.sun.com/docs/books/tutorial/essential/environment/sysprop.html