Quando trabalho com MVCBr o “model” é responsável em executar ações do aplicativo. Um aplicativo, mesmo os mais simples, poderá consumir um número considerável de Models para levar a cabo a execução de todas as ações.
Não será raro que sua aplicação requeira carregar uma dezena de “model” em um único “controller” – nem sempre irá utilizá-los de imediato ou todos ao mesmo tempo. Nada mais sensato postergar a criação do objeto para o momento que for necessário sua execução e concluído a ação liberá-lo da memória sem perder o acesso a classe para posterior execução de novas ações.
Postergar a criação do objeto é chamado de “Lazy Load” – carga tardia do objeto.
Estratégia
A estratégia para criar o objeto tardiamente é criar um “Patterns Adapter” para que faça o controle da classe a ser criada no momento que for necessária, ou seja, ao instânciar o “adapter” ele deve guardar qual a classe que irá criar somente quando for chamado para executar a ação requerida.
Para executar uma carga tardia da classe o MVCBr utiliza a classe TModelAdapterFactory
[code]
TModelAdapterFactory<T: Class> = class(TModelFactory, IModel,
IModelAdapter<T>)
private
FInstanceClass: TComponentClass;
FInstance: T;
function GetInstance: T; virtual;
constructor CreateInternal; overload; virtual;
public
constructor Create; overload;
class function New(AController: IController)
: TModelAdapterFactory<T>; static;
destructor Destroy; override;
procedure Release; override;
property Instance: T read GetInstance;
procedure FreeInstance; virtual;
end;
[/code]
Criando o Adapter
Explorando o código do TModelAdapterFactory
Durante a criação do adapter não haverá inicialização da sub-classe, que só poderá ser criada ao chamar a propriedade “Instance” – momento criar e retorna uma instância da sub-classe;
Exemplo:
[code]
/// declarando a variável para o Adapter – passando tipo da sub-classe
var LMeuAdapter : TModelAdapterFactory<TDataModuleXXX>;
…..
/// criando o adapter
LMeuAdpater := TModelAdapterFactory<TDataModuleXXX>.new( FController );
/// consumindo a sub-classe
LMeuAdapter.Instance.ExecutarMeuProcedimento; // exemplo de chamada de um método da sub-classe
[/code]
Sendo o adapter uma herança de “IModel”, em geral será utilizado como uma instância ligada a um controller no MVCBr – neste caso dispensa a declaração da variável e permite tratar o MODEL como outro MODEL comum ligado ao seu controller.
[code]
/// adicionando o model para o controller no CreateModels do Controller
add( TModelAdapterFactory<TDataModuleXXX>.New(FController) );
[/code]
Quando usar um Adapter
Há duas razões para querer utilizar um Adapter como um MODEL.
1. O primeiro deles é quando você quer importar uma classe para o MVCBr sem fazer as alterações da classe existente – irá permitir consumir a sub-classe como um MODEL mesmo quando a classe não implementa a interface de um MODEL – a sub-classe será acessível pela propriedade “Instance” ;
2. Quando um objeto requeira “instânciar” e “liberar” de forma formal sem interferência da contagem de referência. Casos práticos foram detectado necessidade da utilização do Adapter quando se trabalha com TDataModule – para melhorar o controle e liberação da instância;
Liberação temporária da Instância
Um bom motivo para utilizar carga tardia de um classe pode ser justificada para manter carga de memória somente dos objetos que sejam necessário para a ação e liberá-los tão logo termine sua utilização – para liberar a instância utilizar “FreeInstance” que libera somente a instância da sub-classe mantendo a Adapter ativo.
Git: Projeto MVCBr (quando deste artigo o código corrente Branch DEV); Localizar UNIT: MVCBr.Model para ver o código;