• Nenhum resultado encontrado

6 ESTUDO DE CASO DA METODOLOGIA PROPOSTA

6.5 Etapa 4: mapear o diagrama de classes para BDOO

6.6.2 Implementação do modelo proposto

Os scripts do modelo exemplo são gerados através do Caché Studio, que é a interface de desenvolvimento do banco de dados Caché, permitindo a criação de classes, métodos, etc. Os exemplos são alocados no pacote denominado Modelo. 6.6.2.1 Geração das Classes Dimensão

As classes dimensão são geradas com os atributos como propriedades. Observando que as classes são definidas como persistentes, para armazenamento definitivo dos dados, utilizam-se conceitos de herança, possibilitando a utilização dos métodos da classe %Persistent.

A persistência de objetos é provida pela classe %Persistent, que define os métodos da Persistence Interface e o compilador de classe que administra a evolução do esquema e a projeção do SQL. Para que a classe possa ser persistente, os seguintes requisitos devem ser atendidos:

• sua superclasse primária deve ser também %Persistent; • seu ClassType deve ser persistente.

A figura 51 mostra o script de geração da classe exemplo Agencia no banco de dados orientado a objetos Caché.

Class modelo.Agencia Extends %Persistent [ ClassType = persistent, ProcedureBlock ] {

Relationship PosicaoConta As modelo.Posicao [ Cardinality = many, Inverse = Agencia ]; Property ChaveAgencia As %Integer [ Required ];

Index ChaveAgenciaIndex On ChaveAgencia [ Unique ]; Property NomeAgencia As %String [ Required ];

Property AgrupadorAgencia As %Integer [ Required ]; Property EnderecoAgencia As %String [ Required ]; Property FormatoAgencia As %String [ Required ]; Property CidadeAgencia As Cidade [ Required ]; }

Figura 51 - Script da criação da classe Agencia.

A classe dimensão Tempo também é definida como persistente. O atributo NomeMes utiliza a declaração Property para definir uma propriedade de valores possíveis para uma String, especificando valores para a coleção na lista de palavras-

chave dos meses do ano. Esta aplicação da declaração permite a utilização do conceito da declaração enum da ODL.

O atributo ChaveMes utiliza a mesma propriedade, porém, especificando o maior e menor valor para a identificação numérica de cada mês do ano, considerando do mês 01 ao mês 12. A figura 52 mostra o script de geração da classe no banco de dados orientado a objetos Caché.

Class modelo.Tempo Extends %Persistent [ ClassType = persistent, ProcedureBlock ] {

Relationship PosicaoTempo As modelo.Posicao [ Cardinality = many, Inverse = Tempo ]; Property Ano As %Integer [ Required ];

Property ChaveData As %String [ Required ];

Property ChaveMes As %Integer(MAXVAL = 12, MINVAL = 1); Property Data As %Date [ Required ];

Property DiasdoAno As %Integer; Property DiaSemana As %String;

Property NomeMes As %String (VALUELIST=",JANEIRO,FEVEREIRO,MARÇO,ABRIL,MAIO, JUNHO, JULHO,AGOSTO,SETEMBRO,OUTUBRO,NOVEMBRO,DEZEMBRO");

Index DataIndex On Data [ Unique ]; }

Figura 52 - Script da criação da Classe Tempo.

Considerando a superclasse Pessoa, uma generalização das classes Gerente e Cliente, com atributos gerais para a superclasse e específicos para as classes especializadas, o script da figura 53 define tais características.

Class modelo.pessoa Extends (%Persistent) [ ClassType = persistent, ProcedureBlock ] {

Property nomepessoa As %String [ Required ]; Property chavepessoa As %Integer [ Required ]; Property cidadepessoa As Cidade [ Required ]; Property enderecopessoa As %String;

}

Figura 53 - Script da criação da superclasse Pessoa.

A partir da superclasse definida através da geração da classe Pessoa, são especializadas as classes Gerente e Cliente, com os atributos correspondentes. As classes herdam as características da classe Pessoa, e agregam suas próprias características, conforme mostra o script da figura 54a (classe Gerente) e figura 54b (classe Cliente).

Class modelo.Gerente Extends modelo.Pessoa [ ClassType = persistent, ProcedureBlock ] {

Relationship PosicaoGerente As modelo.Posicao [ Cardinality = many, Inverse = Gerente ]; Property GerenteDepto As %String;

Property GerenteDesde As %Date [ Required ]; }

(a)

Class modelo.Cliente Extends modelo.Pessoa [ ClassType = persistent, ProcedureBlock ] {

Relationship PosicaoCliente As modelo.Posicao [ Cardinality = many, Inverse = Cliente ]; Property CPFCliente As %Integer;

Property DataNascimento As %Date;

Index ClienteIndex On CPFCliente [ Unique ]; }

(b)

Figura 54 - Script da criação das classes Gerente e Cliente .

O Caché suporta uma variedade de tipos de classe para comportamentos especializados. As classes são divididas em classes tipo de dados e classes objeto. Classes tipo de dados representam valores literais como string, integer e date e são usadas para criar propriedades literais de outros objetos, não possuindo propriedades e não podendo ser instanciadas.

Classes objeto podem ter propriedades e podem ser instanciadas. A maior parte das classes consiste de subclasse de classes de sistema chamadas %RegisteredObject, que fornecem automaticamente muito do comportamento básico de um objeto. Uma classe objeto tem um conjunto padrão de comportamentos que incluem:

• sua instanciação ativa a alocação automática de memória do sistema para suas propriedades;

• sua instanciação ativa a criação automática da referência OREF; • suporta polimorfismo.

Classes objeto são classificadas de acordo com seu comportamento no banco de dados, como objeto transiente, persistente ou serial. Um objeto transiente (derivado diretamente da classe %RegisteredObject) não tem nenhum comportamento armazenado, existindo apenas em memória. Uma classe persistente (derivada da classe %Persistent) pode ser armazenada em um banco de dados. Objetos seriais (derivados da classe %SerialObject) podem ser embutidos em outros objetos; um

objeto serial só pode ser armazenado em banco de dados quando é embutido em um objeto persistente.

A classe %SerialObject gera um objeto com a habilidade de produzir uma string representando o estado do objeto (ou seja, suas propriedades atuais). A criação desta string é conhecida como serialização do objeto. Como um objeto persistente, um objeto serial pode ser usado como um tipo propriedade, mas seu comportamento em disco difere de um objeto persistente. Quando usado como uma propriedade, é conhecido como um objeto embutido.

Objetos embutidos têm representação diferente em memória e em disco:

• em memória é representado como um objeto separado e não se diferencia de outro tipo de objeto; o valor em memória de um atributo de objeto embutido é um OREF que se refere à representação do objeto em memória;

• em disco é armazenado como parte do objeto no qual está contido, não possuindo identidade individual (OID) e não podendo ser referenciado por outros objetos; os valores das propriedades do objeto embutido são serializados e armazenados com os outros atributos do objeto.

A figura 55 mostra uma aplicação da classe %SerialObject com a utilização da classe Cidade, referenciada por outras classes. A classe serial é embutida nas classes Pessoa, Agencia e UnidadeDomiciliar do modelo exemplo. A figura 55 registra a classe serial Cidade como um objeto embutido na classe Pessoa.

Class modelo.Cidade Extends %SerialObject [ ClassType = serial, ProcedureBlock ] {

Property descricaoregiao As %String (VALUELIST = ",NORTE,NORDESTE,SUL,SUDESTE, CENTRO-OESTE");

Property nomecidade As %String [ Required ];

Property ufcidade As %String(MAXLEN = 02) [ Required ];} Figura 55 - Script da criação da classe serial Cidade.

6.6.2.2 Geração da Classe Fatos

Os Fatos também são mapeados para classes. Analisando a natureza da classe Fatos, cada fato é uma classe associativa, de acordo com a granularidade dos dados. Como definido na seção anterior, o relacionamento entre a classe Fatos

caracteriza uma agregação com as classes dimensão. A figura 56 mostra o script dos atributos da classe Fatos PosicaoConta.

Class modelo.PosicaoConta Extends %Persistent [ ClassType = persistent, ProcedureBlock ] {

Property JurosCobrados As %Currency; Property JurosPagos As % Currency; Property NumeroTransacoes As %Integer; Property SaldoData As % Currency;

Property SaldoMedioMensal As % Currency; Property TaxasCobradas As % Currency; Property TotalCredito As % Currency; Property TotalDebito As % Currency; …

}

Figura 56 - Script da geração dos atributos da classe Fatos.

6.6.2.3 Geração de identificadores

Um objeto é uma instância específica de uma classe. Um objeto pode existir em disco, em memória ou em uma aplicação do cliente. No Caché, os objetos podem estar em disco ou em memória. Os objetos podem ser referenciados de dois modos diferentes: OREF ou OID.

• OREF: uma referência do objeto. Um valor que se refere a uma instância específica do objeto na memória. Cada vez que um objeto é carregado para a memória pode ter um valor de OREF diferente.

• OID: um identificador do objeto. Um valor que identifica unicamente um objeto persistente no banco de dados. Uma vez que o objeto receba um valor de OID, este valor não muda.

Pode-se usar o OID de um objeto persistente para a localização do objeto e trazê-lo para a memória. Uma vez na memória, o sistema assinala-o com um valor OREF que a aplicação pode usar para acessar o objeto e seu conteúdo. Quando um objeto persistente é armazenado no banco de dados, os valores de quaisquer referências para outros objetos persistentes são armazenados como valores OID. Para atributos de objeto que não têm OIDs, o valor literal do objeto é armazenado juntamente com o restante do estado do objeto persistente.

O Caché gerencia o OID através de mecanismos próprios, atribuindo automaticamente para cada nova instância de objeto criado um OID, na forma de um número inteiro seqüencial.

Quando as classes Dimensão e Fatos são criadas, automaticamente são implementados os OIDs de cada uma delas.

6.6.2.4 Geração dos Relacionamentos entre as Classes

As classes dimensão Conta e Cliente caracterizam um relacionamento n:n, gerando a classe bridge de associação ContaCliente, conforme o script gerado na figura 57 para as classes Conta, Cliente e ContaCliente, respectivamente:

Class modelo.ContaCliente Extends %Persistent [ ClassType = persistent, ProcedureBlock ] {

Relationship Conta As modelo.Conta [ Cardinality = one, Inverse = ItemCta ]; Relationship Cliente As modelo.Cliente [ Cardinality = one, Inverse = ItemCli ]; Property Titular As %boolean [ Required ];

}

Class modelo.Cliente Extends modelo.Pessoa [ ClassType = persistent, ProcedureBlock ] {

Relationship PosicaoCliente As modelo.Posicao [ Cardinality = many, Inverse = Cliente ]; Property CPFCliente As %Integer;

Property DataNascimento As %Date;

Index ClienteIndex On CPFCliente [ Unique ]; }

Class modelo.Conta Extends Extends %Persistent [ ClassType = persistent, ProcedureBlock ] {

Relationship PosicaoConta As modelo.Posicao [ Cardinality = many, Inverse = Conta ]; Property DataAbertura As %Date;

Property DescricaoCategoria As %String; Property DescricaoTipoConta As %String; Property NumeroConta As % String;

Index ContaIndex On NumeroConta [ Unique ]; }

Figura 57 - Script da geração das classes associadas.

A característica de encapsulamento no Caché é utilizada para se manter a representação externa de uma classe - propriedades e métodos - independente de sua implementação atual:

• propriedades encapsulam dados: é possível mudar o banco de dados enquanto se mantém a mesma propriedade de interface;

• métodos encapsulam comportamento: quando um objeto persistente é carregado do banco de dados é automaticamente associado com os métodos definidos para sua classe, podendo mudar a implementação destes métodos independentemente dos dados no banco de dados e de qualquer usuário destes métodos.

O Polimorfirmo é a habilidade para invocar o mesmo método em objetos de tipos diferentes (mas com uma superclasse comum). Cada objeto executa a implementação específica do método. Isto permite a utilização de novos tipos de objeto em aplicações existentes sem a necessidade de se modificar as aplicações.

As aplicações podem se adaptar facilmente a novas circunstâncias fornecendo implementações especializadas das operações. O sistema de runtime executa automaticamente a implementação correta baseado no tipo de objeto.

Documentos relacionados