Desenvolvimento

8 out, 2015

Separe o repositório de interface do usuário do repositório central de aplicação

Publicidade

Nihal Sahu perguntou no Twitter: “Como é que você pode cuidar ‘pessoalmente’ da construção de uma aplicação? Qual é sua estrutura?”. Este artigo é a minha resposta com mais de 140 caracteres sobre o assunto.

Obviamente, eu sou um fã de Action-Domain-Responder como um padrão para construção de interfaces de usuário baseadas na web. (O ADR trata o ciclo solicitação/resposta como uma interface de usuário. O HTML/CSS/JS/ etc., que é utilizado no corpo do HTTP, é apenas uma parte da metade da apresentação da interface do usuário; o ADR nos lembra que os cabeçalhos HTTP são parte da apresentação também.)

MVC e ADR são padrões de interface de usuário, e não arquiteturas de aplicação. O “domínio” em ADR e o “modelo” em MVC são apenas pontos de entrada para o núcleo subjacente da arquitetura geral da aplicação. De certa forma, as partes da interface de usuário “Action/Responder” e “Controller/View” não são o grande negócio na aplicação; o grande negócio é o núcleo subjacente. É aí que o verdadeiro trabalho acontece.

Com isso em mente, uma abordagem correta seria separar a interface do usuário do Core da aplicação. Isso é óbvio e incontroverso; a separação de interesses é um princípio central da boa arquitetura.

O que pode ser controverso é o meu conselho mais extenso em relação a essa abordagem. Não estou sugerindo uma separação meramente “lógica” de preocupações para que as classes Action/Controller não tenham um código Domain/Model nelas. Sugiro uma separação “física”. Em outras palavras: Separe a interface de usuário do repositório a partir do repositório central de aplicação.

Sim, quero dizer que você deve ter dois repositórios de código para sua aplicação. Vamos explorar essa ideia por um minuto.

O primeiro repositório, da aplicação central, não contém nenhum código de interface do usuário. Sem HTTP, sem entrada/saída padrão, nada. A aplicação central espera receber entrada de um modo independente de interface, e fornece impressões de uma forma independente de interface. Note que a aplicação recebe a entrada. Ela precisa ser enviada para a aplicação central, de alguma forma, pois não lê os dados a partir da interface (não há superglobals!). A entrada pode ser enviada sob a forma de parâmetros do método, um tradicional PHP comum, um objeto de entrada fornecido pelo aplicativo central, um objeto de comando fornecido pelo aplicativo central etc. Da mesma forma, a saída pode ser via qualquer método disponível e fornecido pela aplicação central, tais como um objeto Model, um Domain Payload, ou outra coisa. É completamente independente de qualquer código de interface do usuário e pode ser testado por conta própria.

O outro repositório, da interface do usuário, contém o código de “Action/Responder” ou “Controller/View” (ou “Command/Stdout”). Não há nenhuma lógica de negócios. Tudo que ele faz é reformatar a entrada do usuário para algo que a aplicação central irá reconhecer, passa para a aplicação central e receber de volta algumas saídas do aplicativo central, que reformata o que será apresentado ao usuário.

Mas se os dois repositórios estão “fisicamente” separados, como a interface do usuário poderá ter acesso ao aplicativo central? O Composer se tornará seu melhor amigo nesse caso. No código de base da interface do usuário, adicione “require”: { “project-name/core-application”: “dev-develop” } a composer.json. Atualize o composer update e voilá: o aplicativo central agora está disponível para a interface do usuário. A interface do usuário depende da aplicação central, mas ela não tem nenhuma dependência existente na interface do usuário.

O melhor de manter os repositórios totalmente separados um do outro é que isso impõe disciplina ao desenvolvedor. Torna-se difícil colocar o código principal do aplicativo no código de interface do usuário. Qualquer tentativa de fazê-lo será muito óbvia e quem olhar poderá ver isso acontecendo. Torna-se mais difícil justificar para si mesmo “Eu vou adicioná-lo somente dessa vez” (e, assim, manter de fora essa particular armadilha escorregadia).

A desvantagem é que agora você tem que coordenar as mudanças através de dois repositórios de código. Quaisquer rupturas no aplicativo central irão quebrar a interface do usuário. A desconexão pode ser positiva, uma vez que você pode criar uma versão do aplicativo central separadamente da interface de usuário, mas na prática isso significa que você tem que estar mais atento à gestão das mudanças.

Só mais uma coisa sobre como manter a interface do usuário “fisicamente” separada da interface do usuário: dessa maneira, você começa a pensar de forma diferente sobre frameworks. Comecei a pensar que nosso vocabulário para descrever framework em PHP não é suficientemente variado. MVC e ADR não descrevem “frameworks de aplicação” eles podem descrever frameworks de interface do usuário, mas não há nenhuma palavra para os frameworks do aplicativo central. Talvez eles precisem de seu próprio framework separado.

***

Paul M. Jones faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: http://paul-m-jones.com/archives/6119