David CHC

Princípio da Responsabilidade Única com PHP

Uma classe precisa ter uma única responsabilidade e apenas um motivo para alterá-la. É o que informa o SRP – Single Responsability Principle (Principio da Responsabilidade única), que é um dos componentes do SOLID.

O que é o SOLID

SOLID é um conjunto de orientações para você possa trabalhar melhor com a Orientação a Objeto.

  • Single Responsability Principle
  • Open/Closed Principle
  • Liskov Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle

S, que seria o Single Responsability Principle, que iremos tratar nesse artigo. Tende a evitar as classes chamadas God Class, que são classes que fazem tudo, e com isso podem ser problemáticas. Se você precisa ficar alterando vários pontos da sua classe, tem uma maior possibilidade de dar algum bug.

A aplicação do SRP (Single Responsability Principle)

Precisamos criar um cadastro de contato básico, apenas nome e e-mail, e a classe precisará realizar o cadastro e enviar um e-mail para o contato que foi cadastrado.

Segue a classe:

<?php 

class Contact
{
    public $name;
    public $email;
    
    public function insert()
     {
         $pdo =  new \PDO("mysql:host=localhost;dbname=site", "root", "");
         $sql = "INSERT INTO contacts SET name = :name, email = :email";
         $stmt = $pdo->prepare($sql);
         $stmt->bindValue(':name', $this->name);
         $stmt->bindValue(':email', $this->email);
         $stmt->execute();
         $this->sendEmail();
    }
    
    public function sendEmail()
    {
        mail($this->email, "Enviar email", "Contato");
    }
}

Na classe acima, ela tem mais de uma responsabilidade: ela é responsável pelos dados, por fazer persistência, por conectar ao banco de dados e enviar um e-mail.

Ela tenta se responsabilizar por todas as etapas.

Para utilizar, seria assim:

<?php

$contact = new Contact();
$contact->name = 'David';
$contact->email = '[email protected]';
$contact->insert();

Apesar da execução parecer simplificada, a classe possui vários problemas: a falta de encapsulamento dos dados, conexão do banco de dados definida dentro da classe (se precisarmos alterar os dados da conexão ou se precisarmos criar um template para o e-mail, teremos que mexer na mesma classe).

Essa classe é bem problemática, porque falta coesão e ela é muito acoplada, não permitindo variações ou utilizações separada dos itens.

E com isso, é preciso separar essas responsabilidades. Vamos refatorar a classe, e separar cada responsabilidade em classes distintas.

<?php

class Contact
{
    private $name;
    private $email;

    public function setName($name)
    {
        $this->name = $name;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }

    public function getName()
    {
        return $this->name;
    }

    public function getEmail()
    {
        return $this->email;
    }
}
<?php 

class ContactSendMail
{
    private $contact;

    public function __construct(Contact $contact)
    {
        $this->contact = $contact;
    }

    public function shoot()
    {
        mail($this->getEmail(), "Enviar email", "Contato");
    }
}
<?php 

class ContactDAO
{
    private $db;

    public function __construct(\PDO $pdo)
    {
        $this->db = $pdo;
    }

    public function insert(Contact $contact)
    {
        $sql = "INSERT INTO contacts SET name = :name, email = :email";
        $stmt = $this->db->prepare($sql);
        $stmt->bindValue(":name", $contact->getName());
        $stmt->bindValue(":email", $contact->getEmail());
        return $stmt->execute();
    }
}

Refatoramos a nossa classe, e criamos 3 classes:

  • Uma classe Contact, que é entidade, responsável por representar um Contato.
  • Uma classe ContactSendMail que é responsável por disparar o e-mail.
  • Uma classe ContactDAO que é responsável pela interação com Banco de dados.

Como deve ser utilizada:

<?php

//Conexão com banco de dados com PDO
$pdo =  new \PDO("mysql:host=localhost;dbname=site", "root", "");

/*Define os dados a serem inserido*/
$contact = new Contact();
$contact->setName('David');
$contact->setEmail('[email protected]');

//Classe que será responsavel pelas operações no banco de dados
$contactDAO = new ContactDAO($pdo);
if($contactDAO->insert($contact)) {
	//Classe responsável por disparar um e-mail
	$send = new ContactSendMail($contact);
	$send->shoot();
}

Conclusão

Cada classe tem o nome coerente do que é responsável, facilitando assim a forma de trabalhar com elas.

É importante ressaltar, que a questão não é ter um método por classe, e sim que os métodos dessa classe sejam coerentes com que o que classe se propõe a fazer.

Espero que o artigo tenha ajudado, e até a próxima.

Compartilhar a publicação

Trabalha com desenvolvimento web há 15 anos, atuou como programador líder do MX Cursos por mais de 8 anos.  Possui vasto conhecimento em PHP, Javascript, HTML5, CSS3,  GIT, MySQL

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Sobre

Trabalho  com desenvolvimento web há 17 anos, atuou como programador líder do MX Cursos por mais de 8 anos . Possui vasto conhecimento em PHP, Javascript, HTML5, CSS3,  GIT, MySQL, WordPress, WooCommerce

© 2023 – Todos direitos reservados