Clean Architecture

Criada em 2012 pelo tio Bob, Clean Architecture é uma combinação de outras arquiteturas como Arquitetura Hexagonal e Arquitetura Cebola.

Categoria de Programação

Postado em 24 fevereiro 2022

Atualizado em 02 abril 2022

Visualizações: 716



Introdução

Estarei explicando Clean Architecture (Arquitetura Limpa) de uma forma simples e breve, para que iniciantes possam entender de forma rápida e eficiente.

Primeiramente, tem inúmeras vantagens se utilizarmos da forma correta e objetiva. Por ser uma arquitetura super flexível, é dificil achar um ponto em comum nos exemplos de projetos que encontramos na internet.

Resumo

Clean architecture usa 5 princípios de design de código, cujo conjunto de princípios é chamado de SOLID (em inglês, SOLID principles). Cada letra do SOLID é um princípio que deve ser respeitado pelos programadores para que o Clean Architecture funcione corretamente.

  • S - Single Responsiblity Principle (Princípio de responsabilidade individual)
  • O - Open-Closed Principle (Princípio aberto-fechado)
  • L - Liskov Substitution Principle (Princípio da substituição de Liskov)
  • I - Interface Segregation Principle (Princípio da Segregação da Interface)
  • D - Dependency Inversion Principle (Princípio da inversão da dependência)

clean architecture by uncle bob

Na imagem acima, podemos observar que Clean Architecture possui 4 camadas (Enterprise Business Rules, Application Business Rules, Interface Adapters, Framework and Drivers). Porém a imagem acima não passa de um exemplo de um projeto de Clean Architecture.
Como serão definidas as camadas irá depender do seu projeto.
Mas para facilitar as coisas, vamos nos basear na arquitetura da imagem acima.

Outro fato importantíssimo é a ordem das setas. Se observamos bem, podemos perceber que as setas apontam de fora para dentro. Isso indica a dependência entre as camadas. Por exemplo, não podemos usar uma classe situada na camada Enterprise Business Rules dentro de uma classe que fica na camada Interface Adapters. A dependência das classes vai ter que obedecer a ordem das setas.

Origem

Clean Architecture nasceu em 2012, criada por Robert C. Martin ou tio Bob (uncle Bob). Clean Architecture é uma combinação de outras arquiteturas como Arquitetura Hexagonal (Hexagonal Architecture) e Arquitetura Cebola (Onion Architecture).
Apesar de ter algumas semelhanças com DDD (Domain-Driven Design), ambos possuem objetivos diferentes.

Vantagens

  1. Segurança em modificações
  2. Independência de frameworks e banco de dados (escalabilidade)
  3. Fácil testabilidade

1. Segurança em modificações

Se os principios SOLID forem obedecidos corretamente, é possível adicionar novas funcionalidades no seu projeto apenas adicionando mais código, sem alterar o código já existente. Em outras palavras, caso você precise adicionar uma nova funcionalidade em um projeto que criou vários anos atrás e não se recorda muito bem, não existe perigo de “quebrar” alguma parte do seu projeto, em alguma alteração que você fez.

2. Independência de frameworks e banco de dados (escalabilidade)

Don’t marry the framework!

Ou em português, não case-se com o framework.
Frase do tio Bob, criador do Clean Architecture.

O motivo dessa frase é pelo simples fato de que frameworks sofrem atualização (version update). Caso seu projeto seja muito dependente de uma framework, no pior das hipóteses é até possível que pare de funcionar devido às atualizações do framework que você usa.

Por essa razão Banco de dados e Frameworks ficam na parte mais externa possível no Clean Architecture. Seu código não pode ficar dependente de algo que muda com o tempo.

Com a independência de frameworks e banco de dados, você poderá substituí-los quando for necessario sem mais problemas

3. Fácil testabilidade

Por ser dividido em camadas fica mais óbvio saber onde o erro ocorre. Nas camadas mais internas é possível testar sem a interferência de banco de dados, UI, framework, etc…

Desvantagens

  1. Códigos longos
  2. Demora mais tempo para ser implementado comparado com, por exemplo MVC
  3. Requer bons programadores

1. Códigos longos

Quanto mais escalabilidade, mais código vai ter que ser escrito. Uma das desvantagens dos princípios SOLID.

2. Demora mais tempo para ser implementado comparado com, por exemplo MVC

Por ter mais código, mais tempo demora para você poder ver o resultado na tela. Ao contrário de MVC (Model View Controller), que tem menos código e demora menos tempos para você ter seus resultados.

3. Requer bons programadores

Clean Architecture requer um pouco de dominação na linguagem utilizada e tempo para ser aprendida. O fato de ter muitas regras, acaba fazendo com que a maiorias dos programadores desistam na metade do caminho.

Cada camada e sua função

Enteprise Business Rules

Nessa camada geralmente são escritos estrutura de dados e algumas funções. Essa é a camada que fica no topo, portanto não é dependente de nenhuma outra camada. Depois de um projeto finalizado, uma mudança nessa camada afetaria todas as outras camadas, por isso temos que ter bastante cuidado nessa camada.

Application Business Rules

Aqui serão escritos todas as funcionalidades do seu projeto. Em outras palavras o que seu projeto é capaz de fazer. Por exemplo, um aplicativo de pagamento, as funcionalidades necessárias seriam funções como:

  1. Escanear
  2. Mostrar código qr
  3. Pagar
  4. Ver histórico de pagamentos
  5. Etc

Interface Adapters

Tem várias responsabilidades. A principal delas é ser a ponte entre Application Business Rules e Framework and Drivers. É aqui que você irá escrever a sequência dos seus processos para serem executados.

Framework and Drivers

É nessa camada que você finalmente pode acessar seu banco de dados e framework. Nessa camada você não pode acessar diretamente as camadas Application Business Rules ou Enterprise Business Rules. Essa camada só pode acessar a camada de Interface Adapters.

Na prática

Não tem como discutir sobre arquiteturas sem um exemplo concreto. Mostrarei aqui um exemplo de como seria o Clean Architecture na prática, obedecendo a ordem das setas. Não entrarei a fundo sobre os princípios SOLID.

Primeiramente, começaremos criando uma classe situada na camada Enterprise Business Rules.

class User {
    public string $email;
    public string $name;
	    
    function __construct(string $email, string $name) {
        $this->email = $email;
        $this->name = $name;
    }
}

Apesar de ser muito parecido com um model ou table (classes usadas para accessar o banco de dados) não estaremos usando essa classe diretamente com o banco de dados, pois seria uma violação contra a dependência entre classes.

Seguindo adiante, criaremos uma classe na camada Application Business Rules.

interface IUser {
    public function findByEmail(string $email): User; 
}

Ainda na mesma camada iremos criar o conteúdo dessa interface:

class FindByEmail {
    public IUser $iUser;
    
    function __construct(IUser $iUser) {
        $this->iUser = $iUser;
    }
    
	public function execute(string $email): User {
	    // Também é possível validar o email aqui se desejar
	    $userRecord = $this->iUser->findByEmail(email: $email);
	    return new User($userRecord->email, $userRecord->name);
    } 
}

Já terminadas as camadas Enterprise Business Rules e Application Business Rules, partimos para a camada Interface Adapters.

Criaremos o repositório, responsável por acessar o banco de dados.

class UserRepository implements IUser {
    // DbConnection é uma interface e será declarada nessa mesma camada
    public IDbConnection $iDbConnection;
    
    function __construct(IDbConnection $iDbConnection) {
		$this->iDbConnection = $iDbConnection;
	}
	
	public function findByEmail(string $email) {
		return $this->iDbConnection->findBy([
			'email' => $email
		])->execute([
			'table' => 'users'
		]);
	}
}

Ainda na camada Interface Adapters criaremos um controller, para gerenciar todas as classes nessa mesma camada.

class UserController {
    public UserRepository $userRepository;
    
    function __construct(UserRepository $userRepository) {
		$this->userRepository = userRepository;
	}
	
	public function findByEmail(string $email) {
		return $this->userRepository->findByEmail($email);
    }
}

Finalmente criaremos a classe responsável por uma porção do UI, essa classe irá ser chamada na classe de Framework and Drivers.

class ShowUserDetails extends UI {
    public UserController $userController;
    
    function __construct(UserController $userController) {
	    $dbConnection = new DbConnection(database: 'mysql');
		$userRepository = new UserRepository(iDbConnection: $dbConnection);
		$this->userController = new UserController(userRepository: $userRepository);
	}

    public function showUserByEmail(string $email) {
	    $user = $this->userController->findByEmail(email: $email);
	    return response()->view('user.stats', $user);
    }
}

Conclusão

Antes de começar a usar Clean Architecture muitas horas de estudo irão ser necessárias. Mesmo entendo os conceitos dessa arquitetura, há uma pequena dificuldade na sua implementação. Por essa razão, é importante saber suas vantagens e desvatanges, para então começar a investir seu tempo e começar a aprender.