«

»

Apr 19

Print this Post

Implementando a Camada de Controle – Controller

Vamos a quarta parte do artigo de arquitetura para desenvolvimento em camadas, para quem ainda não viu os artigos anteriores desta série, veja os links abaixo:

Pode dar uma lida também nesse post de referência:

Uma visão sobre arquitetura de softwares.
Conforme falamos nos artigos anteriores, vamos mais uma vez apresentar de forma prática a implementação de uma metodologia de desenvolvimento de softwares em camada.

Estamos estudando agora a camada de controle, essa camada é muito importante para o desenvolvimento da aplicação, já que é ela que conversa proximamente com a camada de visualização. Lembrando que temos ainda uma camada de ajuda, chamada de ViewHelper, mas esta camada serve para implementação de lógica e não de ponte para a camada de controle. Resumindo, podemos ter casos onde utilizamos a camada de helper antes de chamar o controller, mas pode ter momentos que não precisamos utilizar um ViewHelper.

Bom, a camada de controle é muito importante por ter a responsabilidade de controlar as solicitações de recursos lógicos das camadas de dados, através da camada de modelo é claro.

Mas como as outras camadas, essa camada também não é somente uma ponte, se fosse para ser uma ponte, não havia sentido em ter uma camada a mais na aplicação. Como a camada de modelo, não é responsável por manipulação de dados do cliente, tratamentos, validações básicas. O Controller assume esse papel, em métodos que recebem DTOs, você irá notar que o Controller é a única camada que não receberá dados nesse formato, e sim uma coleção que populará um DTO para ser passado para as demais camadas. Isso é trabalho para a camada de controle, controlar quais dados chegará a camada de modelo.

Tratamentos com resultados, devem ser implementados dentro da camada de controle, um exemplo seria a necessidade de um array contendo dados diferentes de uma mesma tabela, talvez para gerar uma estatística ou um relatório dos mesmos dados, detalhados de fora diferente. Podem ser consultados e separados na camada de controle, gerando um array contendo os dos resultados diferentes, sem ter que fazer essa separação em outra camada.

Na teoria, essa divisão de responsabilidade é determinada por um bom senso. Quando estamos implementando uma classe mais específica, por exemplo uma classe chamada Pessoa, onde temos explicitamente definidas todas as suas responsabilidades.

Então tenha calma e pense bem antes de começar a implementar suas lógicas em qualquer lugar, conversar com a equipe de desenvolvimento e até mesmo consultar a equipe de arquitetura pode ajuda e evitar de implementações de difícil entendimento.

Agora que falamos bem sobre o que é e para que serve uma camada de controle, vamos a implementação da mesma de forma que se integre com as demais camadas que já implementamos nos artigos anteriores.

Vamos começar implementando a classe base para a camada controle.

ControllerBase.cfc


<cfcomponent>
	<!---
	* Função: Construtor
	* @name init
	* @return void
	--->
	<cffunction name="init" access="package" returntype="void">
		 <cfscript>
			this.instance = Application.instance.Factory;
		</cfscript>
	</cffunction>
</cfcomponent>

Usuarios.cfc


<cfcomponent displayname="Usuarios" hint="Objeto Controller de Usuarios" output="false" extends="ControllerBase">
	<!---
	* Função: Construtor
	* @name init
	* @return void
	--->
	<cffunction name="init" access="public" output="false" returntype="Usuarios">
		<cfscript>
			super.init();
			this.model 	= this.instance.getModel("Usuarios");
			this.dto 	= this.instance.getDTO("Usuarios");
			return this;
		</cfscript>
	</cffunction>
	<!---
	* Função: lista os dados
	* @name listar
	* @return Query
	--->
	<cffunction name="listar" access="public" output="false" returntype="Query">
		<cfargument name="id" type="numeric" required="false" default="0" />
		<cfscript>
			return this.model.listar( id : arguments.id );
		</cfscript>
	</cffunction>
	<!---
	* Função: salva os dados
	* @name salvar
	* @return void
	--->
	<cffunction name="salvar" access="public" output="false" returntype="string">
		<cfargument name="dados" type="Any" required="true" />
		<cfscript>
			var retorno = "";
			if( isQuery( "arguments.dados" ) == true OR StructKeyExists( arguments.dados , "fieldnames" == true ) ) {
				retorno = this.dto.popular( argumentsCollection : dados );
				if( Len( retorno ) == 0 ) {
					try{
						this.model.salvar( dto : this.dto );
					}catch(e){
						return e.message;
					}
				}
			}
			return retorno;
		</cfscript>
	</cffunction>
	<!---
	* Função: deleta os dados
	* @name delete
	* @return void
	--->
	<cffunction name="delete" access="public" output="false" returntype="void">
		<cfargument name="id" type="numeric" required="true" />
		<cfscript>
			try{
				this.model.delete( id : arguments.id );
			}catch(e){
				throw(e.message);
			}
		</cfscript>
	</cffunction>
	<!---
		* Função: autenticar usuários
		* @name autenticar
		* @return query
	--->
	<cffunction name="autenticar" access="public" output="false" returntype="Void">
		<cfargument name="dados" type="Any" displayname="dados" required="true" default="" />
		<cfscript>
			var retorno = "";
			if( isQuery( "arguments.dados" ) == true OR StructKeyExists( arguments.dados , "fieldnames" == true ) ) {
				retorno = this.dto.popular( argumentsCollection : dados );
				if( Len( retorno ) == 0 ) {
					try{
						this.dto.popular( this.model.autenticar( usuario : this.dto ) );
						SESSION['UsuarioLogado'] = this.dto;
					}catch(e){
						throw(e.message);
					}
				}
			}
		</cfscript>
	</cffunction>
	<!---
		* Função: ativar usuários
		* @name ativarUsuario
		* @return boolean
	--->
	<cffunction name="ativarUsuario" access="public" output="false" returntype="boolean">
		<cfargument name="dados" type="Any" displayname="dados" required="true" />
		<cfscript>
			var retorno = "";
			if( isQuery( "arguments.dados" ) == true OR StructKeyExists( arguments.dados , "fieldnames" == true ) ) {
				retorno = this.dto.popular( argumentsCollection : dados );
				if( Len( retorno ) == 0 ) {
					try{
						return this.model.ativarUsuario( usuario : this.dto );
					}catch(e){
						throw(e.message);
					}
				}
			}
		</cfscript>
	</cffunction>
	<!---
		* Função: listar usuários
		* @name listarUsuarios
		* @return Query
	--->
	<cffunction name="listarUsuarios" access="public" output="false" returntype="query">
		<cfargument name="dados" type="any" displayname="dados" required="false" default="0" />
		<cfargument name="ativos" type="boolean" displayname="ativos" required="false" default="true" />
		<cfargument name="inativos" type="boolean" displayname="inativos" required="false" default="true" />
		<cfscript>
			var retorno = "";
			var usuario = "";
			if( isQuery( "arguments.dados" ) == true OR StructKeyExists( arguments.dados , "fieldnames" == true ) ) {
				retorno = this.dto.popular( argumentsCollection : dados );
				if( Len( retorno ) == 0 ) {
					try{
						usuario = this.dto;
					}catch(e){
						usuario = arguments.dados;
					}
				}
			}
			return this.model.listarUsuarios( usuario : usuario , ativos : arguments.ativos , inativos : arguments.inativos );
		</cfscript>
	</cffunction>
</cfcomponent>

Como estamos vendo acima, implementamos de forma bem simplificada a classe de controle Usuarios, fiz validações básicas e tratamentos básicos para não alongar muito esses exemplos.

Dessa forma, você consegue criar o seu padrão de controller e implementar mais uma camada da sua arquitetura.

Gostaria de lembrar, que minha ideia com esses artigos não é dizer qual padrão é certo ou errado, e sim dar uma base para que desenvolvedores que não estão acostumados a trabalhar com arquitetura, possam criar seus próprios padrões e criar aplicações bem estruturadas e de fácil manutenção.

Fico por aqui, na próxima parte desse artigo, chegamos ao final do artigo e falaremos sobre ViewHelper.

Até a próxima.

Paulo Teixeira

Post Original

 

Permanent link to this article: http://ensina.me/coldfusion/implementando-a-camada-de-controle-controller/

Leave a Reply