Começando com o EverClassy Dataset

O propósito do EverClassy Dataset é simples de ser posto: interoperar objetos e componentes dataware! Ainda que seja um propósito simples e curto, tal tarefa esconde alguns desafios específicos que justificam a longa espera até agora. Por exemplo, uma vez que o dataset esteja carregado com instâncias, representá-los como registros é fácil (na verdade, não tão fácil quanto parece!), mas de onde vêm estas instâncias? Um TObjectList clássico? Ou sua muito mais interessante versão com generics, TObjectList<T>? As duas classes são semelhantes, mas são também tipos completamente diferentes! Ou talvez uma instância de TCollection, outra classe útil com um comportamento bastante peculiar? Ou quem sabe o programador tenha uma razão muito forte para usar uma coleção de objetos completamente diferente que ele mesmo tenha construído (digamos, uma coleção persistente de objetos!)?

Além de tudo isso, quando um novo registro é inserido no dataset, é necessário gerar uma nova instância! De que forma tal instância é criada? É necessário que a classe tenha um constructor default? O que acontece se o desenho da aplicação requerer um processo de instanciação mais complexo? E quanto à exclusão de registros? É o suficiente a chamada de Free() sobre a instância correspondente ou algo mais precisa ser feito?

Bem, diversas são as variaveis em um cenário onde uma aplicação é construída em um desenho verdadeiramente orietado a objetos. Um dataset à altura do desafio precisa ser capaz de lidar com todos estes pequenos detalhes e qualquer programador experiente sabe que o verdadeiro trabalho está precisamente em lidar com pequenos detalhes!

Nas sessões seguintes os principais conceitos do EverClassy Dataset serão apresentados! O leitor precisa ter em mente que que o componente é o resultado de esforços específicos direcionados à solução dos problemas descritos acima, assim como alguns outros, no sentido de fazê-lo poderoso, flexível, útil e de fácil uso. Todas estas virtudes juntas fornecem ao programador uma ferramenta capaz de prover a muito desejada e esperada habilidade de mapear objetos Delphi nativos em registros de datasets!

Reconhecendo o terreno

Quando o EverClassy Dataset é instalado em um computador, o assistente de instalação distribui algumas aplicações de exemplo especificamente escritas para demonstrar o uso das características do produto. Este tutorial irá focalizar em um destes exemplos para explicar os conceitos em torno da operação do EverClassy Dataset! Trata-se de um projeto Delphi denominado People.VCL! Existe também um projeto gêmeo denomidado People.FMX para FireMonkey, mas este não será discutido nesta oportunidade.

A seguinte imagem mostra o único form desta aplicação.

Forms.People.VCL

Neste form o usuário é capaz de ver uma lista de pessoas de interesse (o TDBGrid à esquerda) e os detalhes da pessoa selecionada (os diversos componentes dataware no painel à direita). Sobre o componente TDBGrid existe o bem conhecido TDBNavigator que dá condição ao usuário de navegar pelos registros, inserir ou remover um registro e todas as outras operações que o componente provê.

No painel de detalhes existe uma outra instância de TDBGrid que lista todos os métodos de contato que uma dada pessoa tem. Isso quer dizer que a aplicação tem um relacionamento mestre-detalhe (master-detail) entre dois datasets, uma configuração visual muito frequente em aplicações de banco de dados.

As sessões seguintes mostram como tal aplicação foi escrita inteiramente baseada no EverClasse Dataset!

EverClassy Dataset IDE

O nome do show

O EverClassy Dataset é implementado pelo componente VCL do Delphi denominado TECDataset. O mesmo está presente dentro do IDE do Delphi sob a guia de componentes chamada EverClassy. Este é o único componente presente nesta guia!

Como qualquer outro dataset, trata-se de um componente não visual que deve ser colocado sobre um form ou datamodule e

Como se vê, em termos de tempo de design é basicamente mais um componente dataset!

EverClassy Dataset IDE

O modelo de domínio

O EverClassy Dataset objetiva a idéia de se colocar as regras de domínio (ou de negócio) ao longo de um conjunto de classes, criando um conjunto de abstrações que representam os verdadeiros conceitos existentes na realidade. A porção da realidade que é considerada importante a ser estudada é denominada o domínio da aplicação e o modelo orientado a objetos que representa o domínio normalmente é chamado de modelo de domínio. O método ou processo que focaliza o domínio para desenvolver modelos de aplicação hoje em dia é chamado de Desenho Dirigido pelo Domínio (Domain Driven Design) ou simplesmente DDD!

Assim sendo, em um projeto DDD o ponto de partida é, certamente, o modelo de domínio! O modelo para a aplicação People.VCL é exatamente o mesmo para a aplicação People.FMX e está apresentado à direita.

Este modelo está expressado como um diagrama de classes UML e apresenta algumas classes e os relacionamentos entre eles!

Como se trata de um projeto DDD, este modelo é o ponto de partida de todo o desenho. As classes identificadas após algum estudo da realidade (o domínio) devem então ser implementadas em alguma linguagem de programação, Delphi no caso deste tutorial!

A implementação de tais classes não é o problema em questão nesta aplicação. O verdadeiro problema se mostra quando o programador deseja criar um form simples que manipule instâncias destas classes, uma vez que os componentes visuais não são capazes de manipular diretamente objetos e propriedades não descendentes de TPersistent e já registrados no IDE do Delphi.

Algum tipo de componente intermediário precisa ser usado para unir os componentes dataware e as instâncias de classes. Este componente é o TECDataset!

O desenho da interface

O uso de TECDataset para criar uma interface gráfica totalmente funcional que é capaz de manipular objetos de domínio é muito simples e (quase) nada diferente da prática necessária a qualquer outro dataset. A imagem abaixo mostra o form já completamente construído, contendo todos os componentes configurados para trabalhar.

Forms.People.VCL

A primeira coisa a ser percebida é a presença de três instâncias de TECDataset. Um é dedicado a manipular instâncias de TPerson (component ECDatasetPeople), que é o objeto raiz (como mostrado pelo modelo acima). Nesta aplicação, tudo começa com uma instância de TPerson!

O modelo de domínio mostra que instâncias de TPerson podem conter uma instância de TAddress. O relacionamento entre TPerson e TAddress é uma composição que em código gera um relacionamento mestre-detalhe. Este é o motivo pelo qual existe uma outra instância de TECDataset (ECDatasetAddress), dedicado a manipular instâncias de TAddress.

O modelo também mostra que uma instância de TPerson pode também conter um número arbitrário de instâncias de TContact, que é uma classe abstrata e por isso mesmo, nunca instanciada. De fato, o que realmente ocorre é que somente as duas classes descendentes de TContact, TPhone e TEMail são efetivamente instanciadas. Uma vez que tais instâncias estão relacionadas com uma instância de TPerson por meio de uma agregação, um outro relacionamento mestre-detalhe fica estabelecido. Como consequência, uma terceira instância de TECDataset (ECDatasetContact) precisa existir para conter as instâncias de TPhone e TEmail.

O restante do desenho do form é o mesmo que seria com qualquer outro dataset. Instâncias de TDataSource, TDBNavigator, TDBEdit, TDBGrid e assim por diante são usadas na mesma maneira que sempre o são, preservando todo o conhecimento (e possivelmente também código) já existente do programador.

Mapeando fields

Assim como qualquer outro dataset, TECDataset é composto por uma certa quantidade de fields. No caso de datasets que operam com bancos de dados, tais fields correspondem diretamente a colunas de um result set, algumas vezes retornado como a resultante da execução de uma sentença SQL. Entretanto, a natureza de TECDataset não está ligada a qualquer sistema de banco de dados, mas a objetos nativos do Delphi. É por este motivo que os fields de TECDataset são ligados a propriedades de objetos!

Os fields definidos em TECDataset são mapeados para as propriedades do mesmo nome. Assim, em todas as vezes que um field recebe um valor, tal valor é diretamente atribuído à propriedade com o mesmo nome. Se um field não tem uma propriedade correspondente, este age tão somente como um buffer, limitando-se a guardar o valor.

De forma a criar relacionamentos mestre-detalhe, TECDataset também suporta instâncias de TDatasetField, que são atribuídas a propriedade DatasetField em outro TECDataset, em uma configuração muito similar àquela encontrada no TClientDataset.

Carregando objetos

Uma vez que a instância de TECDataset esteja completamente configurada e com todos os fields definidos, a mesma está pronta para começar a trabalhar. O que é necessário é atribuir uma coleção de TPerson a ECDatasetPerson e abrir o dataset. Os outros dois datasets não precisam ser explicitamente abertos, pois operam como datasets de detalhe. Nestas circunstâncias, a abertura do dataset mestre produz um reação em cadeia que termina com todos os datasets dependentes abertos e prontos para trabalhar.

Forms.People.VCL.OnShow

O fragmento de código à direita mostra como o dataset é aberto. O método LoadPeople carregar a lista People com algumas instâncias. A lista People está declarada como People: TObjectList<TPerson> e não tem qualquer preparação especial. A mesma é declarada, instanciada e carregada! Após estes passos, a lista é simplesmente atribuída à propriedade TECDataset.Source e o dataset é aberto. A chamada ao método Open comanda o dataset a iterar sobre a coleção atribuída à propriedade Source (a lista People), enumerar os itens e mapeá-los a registros.

Aqui vem um aspecto muito importante do desenho e operação de TECDataset. De que maneira o componente usa o objeto atribuído à propriedade Source e que tipo de objeto pode ser atribuído à mesma?

A propriedade Source é declarada como TObject o que significa que aceita qualquer instância que se deseje atribuir. É possível que seja atribuída uma única instância que será mapeada para um único registro em um dataset que não aceitará inserções e é possível que se atribua um objeto coletivo que contenha uma quantidade de outros objetos, que serão então mapeados para registros ao invés da coleção propriamente.

Como TECDataset sabe como proceder em cada caso? A resposta é o adaptador de dataset!

O Adaptador do EverClassy Dataset

De forma a dar o máximo de flexibilidade e versatilidade ao programador, TECDataset opera com um objeto associado chamado Adaptador do EverClassy Dataset (EverClassy Dataset Adapter). Se a instância atribuída à propriedade Source não apresentar um adaptador definido para sua classe, tal instância será diretamente operada por TECDataset como um dataset de um único registro que não aceita inserções. Será possível mapear fields a propriedades e atribuir valores a estes fields. O dataset trabalhará perfeitamente, mas será um dataset de um único registro e pronto!

No entanto, se a instância atribuída tiver um adaptador definido para sua classe, tal adaptador será usado para que o dataset possa descobrir quantas instâncias estão contidas nela e, quando necessário, irá interagir com o adaptador para criar ou destruir instâncias! O adaptador é responsável por comunicar o dataset e a coleção de objetos!

Um adaptador é um objeto que implementa a interface IECDatasetAdapter. Este objeto irá operar a efetiva coleção toda vez que o dataset necessitar. Diferentes tipos de coleção precisam ter difererentes e dedicadas implementações desta interface. Estas implementações são registradas a uma classe e todas as vezes que TECDataset é aberto, este procura por um adaptador para o objeto presente na propriedade Source. Se tal adaptador existir, será então usado para carregar os registros e o dataset operará!

Forms.People.VCL.Initialization

O trecho de código à direita mostra o registro de três adaptadores que precisam existir para suportar o uso de três classes de domínio sobre as quais a aplicação People.VCL opera.

Nesta aplicação em particular, o programador decidiu fazer uso da classe TObjectList<T> e existe uma implementação genérica do adaptador para tal tipo já implementada em EverClasse Dataset. Nenhuma implementação é necessária por parte do programador. O adaptador está pronto para ser usado e vai trabalhar com qualquer instâncias de TObjectList<T>. O registro é suficiente para deixar tudo em situação de trabalho quando o dataset ligado a esta fonte de instâncias for aberto!

Este desenho delega ao adaptador a responsabilidade de trabalhar sobre uma coleção e lidar com quaisquer necessidades particulares que esta tenha, escondendo do dataset em si quaisquer especificidades. Também permite o uso de qualquer tipo de coleção. Se um programador tiver uma colecão de instâncias muito especial que sua aplicação precise para operar, esta irá funcionar com TECDataset. O programador terá apenas que implementar um adaptador!

Junto com os exemplos que o assistente de instalação distribui existe um exemplo de implementação de um adaptador que é fornecido para guiar quem precise criar um novo Adaptador do EverClassy Dataset.

Conclusões

Este tutorial apresentou uma visão geral do componente TECDataset. Ao longo do texto diversos conceitos relativos ao produto EverClasse Dataset foram discutidos, tais como:

  1. O TECDataset mapeia instancias para registros e propriedades para fields;
  2. É possível declarar fields do tipo TDatasetField para estabelecer um relacionamento mestre-detalhe entre datasets;
  3. De forma a trabalhar com qualquer objeto coletivo e acessar suas instâncias contidas, TECDataset opera com um objeto associado que implementa a interface IECDatasetAdapter;
  4. Qualquer tipo de coleção pode ser operada por TECDataset se existir um adaptador especializado para lidar com a mesma.

O desenho e operação de TECDataset objetivam, desde o princípio, a verstilidade de trabalhar com todos os tipos de objetos, independentemente do eco-sistema de classes ao qual pertença. Este requisito particular é considerado a chave mestra para permitir que o componente seja parte de qualquer tipo de aplicação que esteja baseada em objetos de domínio.

A Inovativa sinceramente espera que, pela leitura deste tutorial, as princicpais dúvias e questões concernentes ao EverClassy Dataset estejam respondidas. No entanto, se qualquer questão ainda persistir, poderá ser enviada para support@inovativa.com.br. Teremos muita satisfação em elucidar!


Fale conosco

Em caso de dúvida ou questão, por favor, envie um e-mail para support@inovativa.com.br. Será uma enorme satisfação fornecer toda a informação necessária a respeito de nossos produtos!