Resumo do Capítulo:
Bancos de Dados Orientados a Objetos
Heitor Augustus Xavier Costa
1.
Novas Aplicações de Banco de Dados
Os bancos de dados que utilizam o modelo relacional e o modelo de entidade-relacionamento não estão suportando, de maneira adequada, o armazenamento das informações oriundas de aplicações que não utilizam este modelo para a modelagem de seus dados. Como exemplo de tais aplicações pode-se mencionar: CAD, CASE, Multimídia, OIS e hipertexto.
2.
Modelo de Dados Orientados a Objetos
Estrutura do Objeto
Um objeto é constituído de dados (atributos) e códigos (métodos). A um objeto estão vinculados:
|
um conjunto de variáveis (atributos); |
|
um conjunto de mensagens (forma de comunicação entre objetos); |
|
um conjunto de métodos (implementação das mensagens). |
A interface de um objeto é caracterizada pelo seu conjunto de mensagens, ou seja, a interface identifica quais são as mensagens que um objeto deve responder. Como a interface é a única parte acessível (visível) do objeto, é possível realizar alterações no código que implementa as mensagens que compõem a interface (métodos) sem impactar a forma de comunicação entre os objetos. A habilidade de modificar a definição de um objeto sem afetar o resto do sistema é considerada uma das maiores vantagens do paradigma de orientação a objetos.
Classes de Objetos
Quando existem objetos similares, ou seja, objetos que possuem as mesmas mensagens, os mesmos métodos e variáveis com mesmo nome e tipo, eles podem ser agrupados e constituir uma classe. Desta maneira, os objetos de uma classe são chamados instâncias desta classe.
Herança
O conceito de hierarquia de classe é similar ao conceito de especialização no modelo entidade-relacionamento.
Para estabelecer uma hierarquia de classes é necessário realizar um estudo analítico das classes identificadas para determinar quais as classes que são potencialmente indicadas para participarem da hierarquia. Após a determinação destas classes deve-se fatorar as variáveis (mesmo nome e tipo) e os métodos e alocá-los em uma outra classe, estabelecendo a hierarquia de classes. Nesta hierarquia de classes, as classes fatoradas são chamadas de subclasses e as classes que receberam as variáveis e os métodos em comum são chamadas super caces.
Em uma hierarquia de classes que possui N níveis, ao identificar um caminho da classe que está em um nível mais alto até uma classe presente em um nível mais baixo (deste caminho), a classe no nível mais baixo herdam todas as variáveis e todos os métodos de todas as classes superioras a ela no caminho.
Um benefício importante da herança em orientação a objetos é a reusabilidade, visto que os métodos em uma classe não precisam ser redefinidos nas suas subclasses, a menos que uma delas requeira uma implementação distinta.
Há duas possibilidades de associar um objeto a uma classe, a saber:
|
os objetos de uma superclasse são todos os objetos desta classe em conjunto com todos os objetos de todas as suas subclasses; |
|
os objetos de uma superclasse são todos os objetos desta classe exceto os objetos de suas subclasses. |
A escolha mais utilizada nos sistemas desenvolvidos sob a luz de orientação a objetos é a segunda possibilidade.
Herança Múltipla
A herança múltipla é a habilidade de uma classe herdar variáveis e/ou métodos de mais de uma classe. Ao utilizar este recurso, a hierarquia de classes passa a ser representada por um grafo acíclico direcionado (DAG).
A herança múltipla possibilita ambigüidade, uma vez que duas ou mais superclasses envolvidas podem possuir variáveis e/ou métodos com mesmos nomes. Para tentar solucionar esta ambigüidade quatro estratégias podem ser adotadas, a saber:
|
renomear as variáveis e/ou os métodos conflitantes, incorporando o nome (identificador) da classe no final do nome; |
|
escolher uma variável das variáveis conflitantes, bem como escolher um método dos métodos conflitantes para serem herdados; |
|
forçar a escolha explícita pelo usuário; |
|
tratar como erro. |
Em geral, nenhuma solução é aceita como a melhor, pois sistemas diferentes requerem escolhas diferentes.
Identidade do Objeto
A identidade de objeto é noção mais forte de identidade do que as encontradas em linguagem de programação ou em modelos de dados não baseados em orientação a objetos.
Entre as diversas formas de representar a identidade de objeto, pode-se destacar a forma em que é atribuído automaticamente um identificador pelo sistema quando o objeto é criado. Esta forma está embutida no modelo de dados ou na linguagem de programação e é usada nos sistemas de orientação a objetos.
Em orientação a objetos existe o conceito de identificador de objetos (object identifier – OID). Cada objeto possui um único OID e não existem dois objetos com o mesmo OID.
Objetos Complexos
(Compostos)
Os objetos que contém outros objetos são chamados de objetos compostos ou complexos, incorrendo em uma hierarquia de composição de objetos.
Em determinadas aplicações, um objeto pode participar na composição de muitos objetos. Neste caso, a hierarquia de composição é representada com um grafo acíclico direcionado (DAG).
3.
Linguagem Orientada a Objetos
A incorporação dos conceitos de orientação a objetos em um sistema de banco de dados pode ser feita de duas formas:
|
utilizar os conceitos de orientação a objetos como uma ferramenta de design e implementar em um banco de dados relacional; |
|
incorporar os conceitos de orientação a objetos em uma linguagem de programação que manipule um banco de dados. |
Nesta última opção os conceitos podem ser incorporados da seguinte forma:
|
estender a linguagem de manipulação de dados para incorporar os conceitos de orientação a objetos; |
|
estender a linguagem de programação orientada a objetos para incorporar funcionalidade de banco de dados. |
4. Linguagem
de Programação Persistente
As linguagens de banco de dados diferem das linguagens de programação, pois elas manipulam dados persistentes. Dados persistentes são dados que continuam a existir após o término do programa que os criou. Uma linguagem de programação é uma linguagem estendida com estruturas para tratar dados persistentes.
A diferença entre uma linguagem de programação persistente e a linguagem de manipulação de dados (por exemplo SQL) consiste no programador ser responsável em converter os tipos da linguagem de programação persistente para linguagem de manipulação de dados. Isto pode incorrer em erros não detectáveis, pois a conversão é feita não considerando os conceitos de orientação a objetos, e aumento de código, pois além da tradução também é necessário código para o armazenamento e a recuperação dos dados. Em linguagem de programação persistente a linguagem de programação e a linguagem de manipulação de dados atuam de maneira integrada.
Persistência de
Objetos
As linguagem de programação orientadas a objeto trabalham com objetos transientes. Objetos transientes são objetos que existem apenas enquanto a aplicação que os criou continuar executando. Após o término da aplicação eles deixam de existir. Para tornar estes objetos persistentes deve-se adotar uma das seguintes estratégias:
|
Persistência por Classe: estratégia mais simples, porém não flexível. Esta estratégia consiste em declarar uma classe persistente, ou seja, todos os objetos instanciados por esta classe são objetos persistentes; |
|
Persistência por Criação: consiste em sobrecarregar o operador de construção de objetos, ou seja, no momento da instanciação de um objeto é determinado se ele deve ser ou não persistente; |
|
Persistência por Marcação: esta estratégia é uma variação da estratégia anterior. Consiste em marcar o objeto, após sua criação, indicando se ele é ou não persistente. Deste modo, há apenas objetos transientes. Ao terminar a aplicação, todos os objetos marcados devem persistir; |
|
Persistência por Referência: dentre todos os objetos existentes durante a execução da aplicação, alguns objetos são declarados como persistentes. Esta estratégia consiste em tornar persistentes todos os objetos que são "alcançados" (referenciados) pelos objetos declarados persistentes, mesmo que não tenham sido declarados como tal. |
Identidade e Ponteiro
de Objetos
Todo objeto instanciado, sendo transiente ou persistente, possui um identificador único. Em diversas linguagens de programação orientadas a objetos o identificador de objeto é um ponteiro para um endereço da memória. Contudo a localização física do objeto pode mudar com o tempo, existindo graus de identidades, a saber:
|
Intraprocedimento: a identidade persiste apenas durante a execução de um procedimento; |
|
Intraprograma: a identidade persiste apenas durante a execução do programa; |
|
Interprograma: a identidade persiste apenas durante execuções distintas de programas; |
|
Persistência: a identidade persiste apenas durante execuções distintas de programas e reorganizações estruturais dos dados. |
O último grau de identidade é exigido nos sistemas de orientação a objetos.
Armazenamento e
Acesso a Objetos Persistentes
Tornar um objeto persistente significa que se deve armazenar não apenas os valores de seus atributos como também os seus métodos. Contudo, é muito comum armazenar o código (método) em arquivos fora do banco de dados.
Há diversas maneiras de encontrar um objeto. A seguir são citadas três abordagens para realizar tal tarefa:
|
dar nome aos objetos (funciona para uma pequena quantidade de objetos); |
|
alocar identificadores de objetos persistentes ou ponteiros a objetos persistentes; |
|
armazenar conjunto de objetos (a aplicação interage para descobrir o objeto desejado). |
5.
Sistemas Persistentes
Há vários Bancos de Dados Orientados a Objetos, embora existam diferenças na arquitetura do sistema, possuem características comuns em termo de linguagem de programação.
Em diversas linguagens de programação orientadas a objetos existe a possibilidade de redefinir nomes de atributos e métodos e operações dos métodos, esta redefinição é chamada de sobrecarga (Overloading/Overriding). Esta facilidade permite os operadores se comportarem de acordo com a situação apresentada.
A Linguagem de
Definição de Objetos da ODMG
O ODMG (Object Data Management Group) tem trabalhado na padronização de extensões das linguagens de programação orientadas a objetos, de modo que elas aceitem o mecanismo de persistência de objetos. O ODMG propõe a extensão em duas partes:
|
Linguagem de Definição de Objetos (Object Definition Language - ODL); |
|
Linguagem de Manipulação de Objetos (Object Manipulation Language - OML). |
Abaixo é apresentado um exemplo da linguagem de definição de objetos da ODMG, utilizando a linguagem de programação C ++.
Class Pessoa: Public
Objeto_Persistente { Public: String nome; String endereço; }; Class Cliente: Public
Pessoa { Public: Date membro_desde; Int cliente_id; Ref <Agência> origem_agência; Set <Ref
<Conta>> contas inverse Conta : : proprietários; }; Class Agência: Public
Objeto_Persistente { Public: String nome; String endereço; Int ativos; }; Class Conta: Public
Objeto_Persistente { Private: Int saldo; Public: Int número; Set <Ref
<Cliente>> proprietários inverse Cliente : : contas; Int entrar_saldo(); Int atualizar_saldo(int
delta); }; |
Comentários a respeito do exemplo acima:
|
a palavra-chave Private indica que os atributos e os métodos são visíveis apenas pela classe; |
|
a palavra-chave Public indica que os atributos e os métodos são visíveis por todas as classes; |
|
os tipos int, string e date são definidos em C ++; |
|
os tipos string e date são definidos pelo ODMG; |
|
os gabaritos Ref<tipo> e Set<tipo> são definidos pelo ODMG de maneira independente do tipo; |
|
a cláusula inverse é utilizada para especificar restrições de integridade referencial. |
A Linguagem de
Manipulação de Objetos da ODMG
Ao escrever o código para manipular dados em bases de dados deve-se primeiro abrir um banco de dados e em seguida iniciar a transação. Uma transação consiste em uma seqüência de passos delimitados por duas palavras-chaves: Begin e Commit.