Submarino.com.br




Arquitetura com DomainStore, Repositório e Query Object

Introdução

Esta arquitetura é desenhada através do desacoplamento do objeto que representa um critério de pesquisa (Query Object), do objeto que monta esse critério (Repository) do objeto responsável por executar esse critério e retornar os resultados (DomainStore).

Adicionalmente colocaremos a responsabilidade de controle do ciclo de vida da entidade pesquisada (CRUD) no repositório apenas delegando para o DomainStore o como esse controle é realmente executado

Estratégia de Persistência

A estratégia de persistência representa o objeto responsável pelo trabalho real de executar os critérios de pesquisa e operações CRUD. Eis um esqueleto do contrato deste objeto

public interface DomainStore {

    public <E> E save(E instance);
	public <E> void delete(E instance);
	public <E> QueryResult<E> query(Criteria<E> criteria);
}		
		
Código 1:

A primeira coisa a reparar é que todos os métodos são fortemente tipados, mas o tipo não dependende da classe. Básicamente estamos assegurando que o tipo do resultado é compativel com o do argumento. Na prática, esta classe aceita qualquer objeto e não depende realmente de nenhum outro tipo. A segunda coisa importante é que todas as pesquisas acontecem através dos objectos Criteria e QueryResult. O primeiro define o que queremos encontrar, o segundo encapsula o resultado.

O Repositório

A definição do repositório não carece da declaração de um contrato, até por que, cada repositório tem um contrato diferente do outro. Contudo, vamos definir uma classe abstrata para isolar algumas partes comuns a todos os repositórios.

Uma coisa que todos os repositórios que vamos construir, têm em comum, é o controle do ciclo da sua respetiva entidade. Além disso, todos eles irão delegar algumas funcionalidades à classe domainStore. O uso de uma classe abstrata irá facilitar isto também.

public abstract class AbstractRepository<E> {

	private DomainStore domainStore;
	
	public AbstractRepository (DomainStore domainStore){
		this.domainStore = domainStore;
	}

	protected DomainStore getDomainStore(){
		return domainStore;
	}
	
	public <E> E save( <E> instance){
		return domainStore.save(instance);
	}
	
	public <E> void delete( <E> instance){
		return domainStore.delete(instance);
	}
	
} 		
		
Código 2:

Os métodos save e delete são essencialmente delegados à estratégia de persistência encapsulada no domainStore. Caso seja necessário, o repositório poderá sobrescrever esse comportamento, mas isso é raro sendo usado mais em ambiente de testes.