Abstração de Acesso a Dados e Orientação a Objetos – Parte 02

Introdução

No post anterior (Abstração de Acesso a Dados e Orientação a Objetos) vimos o conceito de abstração e uma ideia de implementar uma classe superior — ou superclasse — que eliminaria várias duplicidades entre as classes ZDBFFILE e ZMEMFILE. Bem, mãos a obra.

Classe ZISAMFILE

Tudo o que é comum e exatamente igual na implementação de ambas as classes de acesso a DBF em disco e em memória são parte de uma lógica de acesso e comportamento ISAM. Ao criar a classe ZISAMFILE, ela passa a ter as propriedades e métodos comuns a ambas implementações, que são removidas das respectivas implementações e colocadas nela.

A classe ZISAMFILE não tem construtor explícito, ela não têm um “New”. Mas não precisa, pois ela não foi feita para ser instanciada diretamente. Ela deve ser a classe superior a ser herdada pelas classes ZMEMFILE e ZDBFFILE, da seguinte forma:

// Ao invés de 
CLASS ZDBFFILE FROM LONGNAMECLASS
CLASS ZMEMFILE FROM LONGNAMECLASS

// Agora temos
CLASS ZISAMFILE FROM LONGNAMECLASS
CLASS ZDBFFILE FROM ZISAMFILE
CLASS ZMEMFILE FROM ZISAMFILE

Métodos reimplementados

Existem alguns métodos comuns implementados tanto na classe filha como na classe pai. Ao implementar na classe filha um método da classe pai, você pode ou não chamar o método da classe pai de dentro da classe filha, quando o objetivo do método não é substituir a implementação da classe pai, mas sim COMPLEMENTÁ-LA.

Por exemplo, cada uma das classes (ZDBFFILE e ZMEMFILE) possui propriedades específicas, declaradas em sua definição. E, a classe pai ( ZISAMFILE) também tem as suas propriedades, comuns a todas as heranças. Na implementação original, o método de uso interno da classe chamado _InitVars() foi feito para justamente inicializar estas propriedades, e ele agora também foi implementado na classe ZISAMFILE.

A forma correta e elegante de se fazer isso é: Cada método _InitVars() da sua classe inicializa as propriedades da sua classe. E, as classes que herdam a ZISAMFILE -- no caso ZMEMFILE e ZDBFFILE -- antes de mais nada chamam o método _InitVars() da classe superior (ZISAMFILE). Sendo assim, o método _InitVars da classe ZMEMFILE ficou assim:

METHOD _InitVars() CLASS ZMEMFILE 

// Inicialização das propriedades da classe pai
_Super:_InitVars()

// Inicializa demais propriedades da ZMEMFILE
::aFileData   := {}
::lOpened     := .F. 
::lExclusive  := .F. 
::lCanWrite   := .T. 
::dLastUpd    := ctod("")
::aGetRecord  := {}
::aPutRecord  := {}
::lUpdPend    := .F. 
::lSetDeleted := .F. 
::nRecno      := 0

Return

Como eu disse, ainda existem propriedades em duplicidade implementadas nas classes ZMEMFILE e ZDBFFILE, elas serão remanejadas em outro momento. Mas sabe o que é o mais lindo de tudo isso?

  • Os programas de teste que usavam as classes continuam funcionando perfeitamente, pois todos eles acessam as funcionalidades das classes através de métodos, até mesmo as propriedades são retornadas por métodos — recurso também chamado de “Getters and Setters” — torne as propriedades privadas da classe, e encapsule qualquer mudança de estado das propriedades em métodos Set<Propriedade>(), e as consultas por métodos Get<Propriedade>()
  • A classe ZISAMFILE ficou com 700 linhas. Isto significa que cada fonte das classes ZMEMFILE e ZDBFFILE agora tem cada um 700 linhas a menos, eliminando a duplicidade de código, e implementando as funcionalidades na classe pai. 
  • Até mesmo um método que era

Outras mudanças

Aproveitando o momento de refatoração, a classe de índices em memória deixou de se chamar ZDBFMEMINDEX e passou a ser ZMEMINDEX — afinal ela é usada pelos métodos e propriedades de controle da implementação da ZISAMFILE. Outra alteração interessante era o processamento de uma expressão AdvPL, onde era necessário trocar a ocorrência de campos na expressão pelo o:FieldGet() do campo. Isto era feito exatamente da mesma forma tanto na classe de índice quanto nas classes de ZDBFFILE e ZMEMFILE para aplicar filtros.

Agora, existe um método chamado _BuildFieldExpr(), que recebe uma string com uma expressão AdvPL qualquer que use campos da tabela — onde todos os campos na expressão devem ser colocados com letras maiúsculas — e retorna uma string com o texto do Codeblock com a expressão resultante. Agora, quem precisa desta funcionalidade chama o método  _BuildFieldExpr() da classe  ZISAMFILE, e com a expressão resultante, criar o Codeblock dinâmico com macro-execução e usar conforme a necessidade.

GITHUB

Conforme o projeto vai sendo alterado e os fontes refatorados, novos recursos arquivos vão sendo acrescentados no GITHUB, a versão mais atual de todos os fontes envolvidos está lá. Pode ser necessário remover alguns fontes do projeto e recompilar os programadas para dar tudo certo. Em breve os fontes das implementações de arquivo e implementações comuns vão fazer parte de um novo projeto — Chamado “ZLIB”.

Conclusão

Eu deixo a conclusão desse post e da implementação para vocês. Espero que este exemplo sirva não somente pela sua funcionalidade, mas como um modelo de boas práticas de desenvolvimento.

Desejo a todos novamente TERABYTES DE SUCESSO 😀

 

 

 

 

 

Um comentário sobre “Abstração de Acesso a Dados e Orientação a Objetos – Parte 02

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s