[Delphi] Design Patterns GRASP – Controller

Olá, leitores! Quanto tempo, hein?
Depois de alguns compromissos e problemas de saúde, finalmente retorno aos meus trabalhos aqui no blog.
Conforme prometido, hoje inicio uma nova série sobre Design Patterns GRASP! Embora poucos conhecidos, eles apresentam boas práticas de codificação que contribuem para uma arquitetura desacoplada. Vamos lá?

Introdução

Se você considera que só existem os Design Patterns do GoF (Gang of Four), está enganado! Há vários outros padrões de projeto distribuídos em diversas literaturas. Um destes conjuntos de padrões é chamado de GRASP – acrônimo de General Responsibility Assignment Software Patterns, ou, em tradução livre: “Padrões de Software de Atribuição de Responsabilidade Geral”.

Os nove padrões de projeto do GRASP estão relacionados basicamente com as responsabilidades que as classes possuem em um projeto. Neste momento acredito que você deve ter lembrado do SRP, não é? 🙂

No decorrer dessa série, você notará que alguns deles se assemelham aos padrões do GoF, e isso é bom! Essa equivalência entre os padrões alimenta a nossa sensibilidade técnica.

Controller

Pois bem, pessoal, o primeiro destes padrões é o Controller, que traz um conceito bem fácil: seu propósito é delegar eventos e regras de negócio para uma classe não-visual. Em um simples cadastro de clientes, por exemplo, haveriam duas classes: uma responsável pela apresentação visual (TCadastroClientes) e outra responsável por controlar as regras de negócio (TCadastroClientesController). Observe que essa separação já é algo relativamente comum nas arquiteturas atuais.

Isso nos lembra… o padrão MVC! 🙂
O “C” refere-se ao Controller, que faz o intermédio entre as camadas View e Model. Lembre-se que, neste padrão de arquitetura, a responsabilidade de validações, transporte de dados e parte das regras de negócio é incumbida ao Controller. Uma das grandes vantagens é o baixo acoplamento entre classes, já que cada uma recebe apenas uma responsabilidade. Logo, podemos dizer que este padrão de projeto está “dentro” do MVC!

Show me the code!

Essa é uma nova seção do blog, leitores. Trata-se de frase que foi citada por Linus Torvalds em 2000 e achei conveniente utilizá-la nas partes práticas dos artigos.

Para exemplificar o uso do Controller, codificaremos o código da inclusão de um novo registro em um cadastro de produtos. Antes disso, veja como seria o código sem a aplicação do padrão de projeto:

O código parece estar correto, concorda?

Realmente não há nada de errado, porém, considerando também os métodos de exclusão, alteração, consulta, validações e manipulação dos componentes visuais, a classe provavelmente ficará sobrecarregada de responsabilidades. No caso de formulários no Delphi, já podemos contar três responsabilidades: apresentação visual, validações e persistência.

A ideia do Controller é encapsular estes métodos em uma classe isolada, de forma que a camada View (parte visual) tome conta apenas das regras de exibição ao usuário. Para isso, portanto, teríamos uma nova classe:

No formulário (View), basta criar um objeto Controller e invocar o método de inclusão do produto:

Opcionalmente, podemos criar uma classe DTO (Data Transfer Object) para enviar apenas um parâmetro para a função ao invés de três. Recomendo essa opção!

Ao delegar tais responsabilidades para o Controller, a camada View fica encarregada apenas das regras visuais, como atualização de textos, preenchimento de listas, exibição de mensagens e controle do estado de componentes.

Componentes visuais e regras de negócio

Para controlar componentes visuais, use o Controller também! Veja um exemplo abaixo:

Simples, né? Mas… há algo que nos incomoda: é preciso instanciar e liberar o Controller a todo momento, tornando o código dos métodos muito repetitivo.

Bom, já que o Controller normalmente é utilizado em quase todos os métodos da camada View, é mais viável, obviamente, instanciá-lo como uma variável de classe:

That’s it!

Agora que você já conhece o Controller, tenho certeza que, em algum momento, já codificou algo parecido, ou seja, uma classe que encapsula o controle de eventos e regras de negócio de forma isolada, não visual, e exclusiva. Mesmo que você não tenha adicionado o sufixo “Controller” (que, claro, não é uma regra), essa classe é um Controller!

Na verdade, como mencionei no início do artigo, esse tipo de codificação já é bastante recomendado.

Fico por aqui, e encontro vocês no segundo artigo dessa série!


 

André Celestino