Singleton – este é um cara engraçado. Não aceita sobrecarga nem substituição – fecha em sí e não abre para estender seu recursos. Maaasss… ele é o fino em compartilhar os seus atributos. Sempre que alguém pergunta por ele, a resposta é a sempre a mesma – inflexível e sem surpresas.

base
Singleton é uma instância global a ser evitada, mas quando não tem outra saída – é um bom parceiro.

elementar meu caro
Sendo um Singleton uma instância global, basta criar a instância uma única vez e sair usando – controlar o momento em que um Singleton pode ser liberado da memória pode ser um bom desafio. Em geral a instância é criado em algum momento do código e sua liberação ocorrerá ao finalizar a aplicação, mantendo-o carregado na memória durante o tempo de vida do aplicativo.

quando usar
Sempre que for necessário uma instância que faça controle de outras instâncias, o Singleton será bem útil. O Delphi possui alguns deles como exemplo o “Application”, uma instância que existe por toda a vida ativa do aplicativo, criado ao entrar e liberado somente quando é encerrado.
O MVCBr possui um subtitulo ao “application” o “ApplicationController”. ApplicationController é uma instância única que mantém uma pilha de “controllers” aberto no aplicativo, aqueles que estão instanciados.

limitações

Quando o desejo é atribuir um variável única para o um objeto específico e suas herança, o uso do Singleton é bastante “simples” – basca criar um “Class Var” para a instância a controlar.
Se de outro lado, se o desejo for permitir herança e cada herança tem o seu próprio Singleton então “Class Var”* não irá resolver a classe base precisa implementar mecanismos mais espertos (*a class var pertencerá sempre ao pai e não permite nova cópia aos filhos).

curiosidades
O TMVCBrSingleton faz uso de outros dois patterns:
LazyLoad – quando cria a instância para a classe alvo somente quando ela for necessária (ver invoke);
Adpater – exporta a classe base por default sem necessidade de fazer referências indiretas ( ver ..factory.mudarFlag(true) .. )

Uma classe que permite transferir um Singleton individual aos filhos
Unit: MVCBr.Patterns.Singleton
O Singleton do MVCBr implementa uma interface de adaptadora para a interface IMVCBrSingleton como já vimos antes (ver mais: princípio adaptador para interface ). Como uma classe adaptadora, é possível aplicar o “generics” para retornar o próprio singleton adaptado pela classe, vejamos:

[code]
unit singleton.MinhaClasse;

interface

uses MVCBr.Patterns.singleton;

type

/// minha classe alvo
TMinhaClasseAlvo = class(TObject)
public
function mudarFlag(AValue: Boolean): Integer;
end;

/// criando uma classe factory filha
TMinhaClasseFactory = class(TMVCBrSingleton<TMinhaClasseAlvo>)
end;

var
MinhaClasseFactory: IMVCBrSingleton<TMinhaClasseAlvo>;

implementation

{ TMinhaClasseAlvo }
function TMinhaClasseAlvo.mudarFlag(AValue: Boolean): Integer;
begin
result := ord(AValue);
end;

initialization
MinhaClasseFactory := TMinhaClasseFactory.new() ;
end.
[/code]

caso 1
Para criar uma instância local da interface – não parece lógico, somente para ilustrar, podemos fazer:
[code]
var
MinhaClasseFactory: IMVCBrSingleton<TMinhaClasseAlvo>;
begin
/// LOCAL
/// criando a classe factory para singleton
MinhaClasseFactory := TMVCBrSingleton<TMinhaClasseAlvo>.New();
showMessage(MinhaClasseFactory.mudarFlag(true).ToString);

[/code]

caso 2
Usando a classe factory que implementa uma herança de TMVCBrSingleton:
[code]
// usa o singleton
showMessage( MinhaClasseFactory.mudarFlag(false).toString);
[/code]

Tenho visto muitos videos que falam sobre como aplicar MVC com Delphi e sempre fiquei com a impressão que não é nada fácil. O que não é fácil se torna um desafio – é assim que nasceu MVCBr – Um desafio para elevar a organização do código a outro patamar.

A filosofia nativa vendida pelo fabricando do delphi, basta ver os diversos videos disponíveis na comunidade, é que a ferramenta suporta MVVM, ou seja Model View e View Model – talvez seja este o maior entrave em implementar um MVC.

1) O desafio

Sendo a IDE altamente produtiva é preciso que um projeto MVC não retire aquilo que há de melhor, mesmo assim, encontramos muitos que condenam a condição de “arrastar e soltar” utilizada deliberadamente ao longo dos anos, formando uma legião de arrastadores de componentes para a interface e quando precisa de um pouco mais de profundidade da engenharia de software – foi esquecida.

2) Onde encaixar o Controller (“o bobo da corte”)

O papel o Controller é fazer o meio de campo entre o VIEW e MODEL, o que já chamei antes de “bobo da corte”, ou seja, é o controle que faz a ponte entre os MODELs e as VIEWs. Quando uma VIEW precisa de alguma informação, ela pregunta para o CONTROLLER quem detém este dado – em existindo entrega a VIEW o MODEL que é responsável pelo informação.

3) A View – camanda de apresentação

É a VIEW que se encarrega de fazer a apresentação ao usuário – no caso de desktop o “FORM” – toda VIEW possui um controller associado a ela. Se o aplicativo rodar em um browser, a VIEW é a página de apresentação para o usuário…

Não é responsabilidade da VIEW saber como guardar informações;

4) O Model – onde tudo acontece

É no MODEL que as regras acontecem. Persistência, cálculos, DAO, ORM…

VIEWMODEL

No MVCBr ainda temos a figura do VIEWMODEL – o ViewModel é um artefato de MVVM e não de MVC, no entanto o seu uso pode ser bastante útil para não nos afastarmos muito da filosofia da ferramenta.

O que fazer com o VIEWMODEL ?

Com o ViewModel, pode-se adotar uma estrutura híbrida e delegar ao VIEWMODEL a validação do formulário. Sendo ele ao mesmo tempo um conector direto para o VIEW com funcionalidades de um MODEL, ou seja, ele pode receber validações do FORM ou mesmo guardar alguns estados ligados ao FORM (ou particulares ao VIEW).

 

O MVCBr

No MVCBr, a relação entre CONTROLLER  e  VIEW  é de 1 para  <=1 – Um Controller possui  no máximo  uma  VIEW, em alguns casos talvez nenhuma. Assim toda vez que se cria uma VIEW é preciso construir um controller para a VIEW.

Já o CONTROLLER pode possuir ligações para múltiplos MODELs do projeto. Sendo o MODEL um artefato que possui regras de negócio, um MODEL pode conter as regras de persistência de cliente enquanto outro MODEL possui regras de transação de cartão de crédito separando cada MODEL por finalidade.

Se um MODEL implementar uma NFe, ele dever saber lidar com o acesso ao cadastro de cliente, acessar cadastro de produto …. além de fazer persistência do conjunto de regras de NFe – Muitas vezes um MODEL poderá precisar de ajuda de outro MODEL;

O Assistente do MVCBr

Desafio lançado – código complexo. Precisamos de um assistente para nos ajudar a escrever código. Foi pensando nisto que o Assistente do MVCBr esta apto a criar o projeto com estrutura de MVC, VIEW, MODEL e CONTROLLER para a nossa aplicação;

Todo o projeto tem por base trabalhar com assinaturas publicadas em INTERFACEs visando eliminar ao máximo o acoplamento, implementadas em UNITs em separado dos seus “Object Factory”. Neste contexto, sempre que uma UNIT precisa de um recurso que se encontra em outra UNIT – deverá preferencialmente trocar informações pelas INTERFACEs.

Todo “Object Factory” public o seu THIS, uma espécie de SELF para o “Factory” onde permite facilmente fazer CAST de interfaces usando   “This. AsType<interface>” – claro que o “Factory” precisa conhecer e implementar a tal interface solicitada (ou retornará NIL).

 

Veja o Vídeo:  Criando um Projeto com FireDAC

Códigos:  MVCBr