wiki:WF/camadamodel

Camada de Modelo

A camada Model define o que o processo vai fazer e como implementá-lo, ou seja, as regras de negócio do sistema. Ela possibilita o desenvolvimento de recursos, independentemente da forma como os dados serão exibidos (interface) e do momento em que serão executados (fluxo). Essa camada deve saber somente como executar cada recurso do sistema.

Assim como na camada de Controle, a camada Model, também é subdivida em três níveis:

  • Nível módulo: representado pela classe BaseModel;
  • Nível processo: representado pela classe Model;
  • Nível atividade: representado pela classe AtividadeModel.

Os três níveis unem-se por herança no seguinte esquema:

BaseModel <- Model <- AtividadeModel

A classe BaseModel está declarada no módulo workflow e vale para todos os processos. Nela estão codificados atributos e métodos de uso geral a serem usados pelas classes que a estenderem.

Atributos da classe BaseModel:

  • instance: objeto da instância em execução;
  • activity: objeto da atividade em execução;
  • DAO: objeto da camada de abstração de banco de dados;
  • request: array com os dados submetidos pelo formulário da camada View;
  • workflow: array com as variáveis do ambiente de execução da atividade;
  • natural: objeto para conexão com o mainframe;
  • factory: objeto para a requisição de instâncias das classes auxiliares, como organograma, ldap, etc;
  • viewData: array contendo os dados a serem exibidos na camada View
  • Contém atributos privados da camada model;
  • Contém atributos que representam as propriedades da instância em execução;
  • Pode conter outros atributos para armazenamento de instâncias de classes de negócio (como paginação, filtros, etc);

Em especial o atributo viewData, seu objetivo é armazenar os dados a serem retornados para a camada de Controle. Esta é a forma ideal para que um método de negócio da Model faça o retorno de dados.

Os atributos da instância, por padrão, deverão começar com o caracter underline para diferenciá-los dos atributos privados da classe.

Métodos da classe BaseModel:

  • getAttributes: retorna os atributos da instância (aqueles iniciados por underline);
  • getRequest: cria atributos na classe para as variáveis do array Request;
  • addViewVar: adiciona uma variável ao array viewData;
  • getViewVar: recupera uma variável do array viewData;
  • setWfProperty: seta o valor de uma variável do ambiente de execução;
  • getWfProperty: recupera o valor de uma variável do ambiente;
  • setNameInstance: seta o valor do identificador da instância;
  • updateInstance: transfere os atributos de instância, que estão na classe, para o objeto instance;
  • updateAttributes: carrega, nos atributos de instância da classe, os valores que estão no objeto instance;
  • commitInstance: sinaliza para o módulo workflow que a instância deve ser salva em disco.

Já a nível de processo, deve-se:

  • Criar um arquivo com formato de nome class.Model.inc.php e armazená-lo no diretório 'code' do processo;
  • Codificar a classe Model que estenderá a classe BaseModel.

Exemplo de uma classe Model de processo:

<?php
/**
 * Implementa a Classe Model do Processo
 * @author Fulano
 * @version 1.x
 * @license http://www.gnu.org/copyleft/gpl.html GPL 
 * @package Nome_do_Processo
 */ 
class Model extends BaseModel 
{	
	// Aqui vai o bloco de atributos privados da classe
	/**
	 * @var $variavel
	 * @access protected.
	 */	
	var $variavel;

	// Aqui vai o bloco dos atributos de instância

	/**
	 * @var $_variavel
	 * @access protected
	 */	
	var $_variavel;
	
	// Aqui vai o bloco de métodos privados da classe

	/**
	 * Descrição do método
	 * @return array Resultado da seleção.
	 * @access protected
	 */
	function listar()
	{
		// comandos do método
		
		return $resultado;	
	}
	
	/**
	 * Valida dados do formulário.
	 * @return array Resultado da validação.
	 * @access protected
	 */
	function verifica_erros()
	{
		// comandos de validação dos dados
		return $erro;
	}
	
	 /**
	  * Construtor da camada Model em nível de processo.
	  * @param array $env Configuracao MVC.
	  * @return Model.
	  * @license http://www.gnu.org/copyleft/gpl.html GPL 
	  * @access protected
	  */
	function Model(&$env) 
	{
	   $this->super(&$env);
	}	
}
?>

Agora, a nível de atividade valem as mesmas regras de criação de arquivo, só que o nome será no formato class.Atividade.Model.inc.php. O arquivo deverá conter:

  • Uma classe com nome no formato AtividadeModel, que estenda a classe Model do processo;
  • Métodos que implementam cada uma das ações solicitadas pelo usuário e encaminhadas pelo Controller;
  • Resultados booleanos indicando sucesso ou falha na requisição feita pelo usuário.

Abaixo um exemplo de camada Model de uma atividade:

<?php
/**
 * Implementa a Camada de Modelo da Atividade Cadastrar
 * @author Fulano
 * @version 1.x
 * @license http://www.gnu.org/copyleft/gpl.html GPL 
 * @package Nome_do_Processo
 */
class CadastrarModel extends Model
{
	/**
	 * Implementa acao padrao da atividade Cadastrar
         * @license http://www.gnu.org/copyleft/gpl.html GPL. 
	 * @access public.
	 * @return boolean.
	 */
	function defaultAction()
	{	
		// Comandos do método, por exemplo:

		$this->addViewVar("mensagem", "Digite uma mensagem.");

		return true;			
	}
	
	/**
	 * Implementa acao salvar
	 * @return bool
	 * @access public
	 */
	function salvarAction()
	{
		if (!count($erro = $this->verifica_erros($this->request)))
		{

			$this->_mensagem = trim($this->request['mensagem']);
			$this->addViewVar("mensagem", "Sua mensagem foi salva.");
			
			$this->updateInstance();
			$this->setNameInstance($this->_mensagem);
			$this->commitInstance();
			return true;
		}
		else
		{
			$this->addViewVar("mensagem", "Mensagem inválida. Digite novamente.");

			return false;
		}
	}
}
?>

Neste exemplo estão codificados duas ações da atividade: default e salvar. Ambas serão acionados pela camada de controle conforme as ações forem solicitadas. O método defaultAction() é encarregado de preparar os dados a serem exibidos na camada de visualização quando a atividade for executada a primeira vez. Já o método !salvarAction() implementa o que fazer quando o usuário clicar no botão "Salvar" do formulário da atividade. Analisando mais a fundo este método, ele começa fazendo uma consistência nos dados vindos do formulário (representado pelo objeto Request). Caso sejam válidos realiza as seguintes operações:

  • Armazena os dados do formulário como atributos da camada Model;
  • Em seguida executa o método updateInstance() que irá transferir para a instância os atributos da camada Model;
  • Executa o método commitInstance(), que fará a atualização da instância definitivamente e encerrará a execução da atividade;
  • Retorna indicativo de sucesso da operação.

Caso exista inconsistência nos dados do formulário, irá:

  • Preparar os dados para serem exibidos novamente ao usuário (chamadas ao método addViewVar);
  • Retornar indicativo de insucesso da operação.

Isso conclui a camada Model a nível de atividade.