Boas práticas no desenvolvimento de software - parte 2
Tags: php, portugues, braziliandevs
Published: 2020-12-06 13:20:56

*Photo by [Maxwell Nelson](https://unsplash.com/@maxcodes?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/software?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)*

*Se você ainda não leu a primeira parte, [confira aqui](https://dev.to/tadeubarbosa/boas-praticas-no-desenvolvimento-de-software-parte-1-5gla)!*

Desenvolver software não é algo simples. Sempre tem coisa nova pra gente aprender, tem sempre desafios novos. Vi uma frase ontem e achei muito interessante, não sei de quem é a frase, mas é muito verdadeira:

> Think twice, code once

Em outras palavras:

> Pense duas vezes, codifique uma.

A ideia da frase é que quanto mais pensamos no que iremos codificar, menos teremos que mexer naquele código. Existem alguns princípios como o SOLID, mas não iremos falar diretamente sobre eles agora, mas em um outro momento.

## Múltiplos parâmetros num construtor ou método

Na primeira parte escrevi um código de exemplo, reparem na quantidade de parâmetros:

```php
function isAdmin($usuarioTipo)
{
  return $usuarioTipo === 1;
}

function getValorOperacao($dividaInterna, $dividaExterna, $novaDivida, $usuarioTipo)
{
  if (isAdmin($usuarioTipo)) {
    return $dividaExterna + $novaDivida;
  }

  return $dividaInterna + $dividaExterna + $novaDivida;
}
```

Poderíamos deixar o código um pouco melhor, e diminuir os parâmetros:

```php
function getValorOperacao(Usuario $usuario, DividaUsuario $divida)
{
  if ($usuario->isAdmin()) {
    return $divida->getExterna() + $divida->getNova();
  }
  return $divida->getInterna() +
         $divida->getExterna() +
         $divida->getNova();
}

$usuarioId = 1;
$usuario = new Usuario($usuarioId);
$divida = new DividaUsuario($usuario->id);

$valorOperacao = getValorOperacao($usuario, $divida);
```

## Confiar de mais no usuário

Confiar que o usuário será sempre alguém bem intencionado é um erro! A primeira coisa é que esperamos que o usuário do sistema não vai tentar de alguma forma aproveitar do sistema para fazer algo malicioso. Alguém querendo pegar informações que não deveria, tentando se passar por outra pessoa etc. Alguns exemplos são os seguintes:

### Não validar as entradas dos usuários

Quem garante que o input de email é mesmo um email e não um SQL Injection?

- Filtrar as requisições: aquela informação é realmente a que esperamos?
- Validar se os campos foram preenchidos tanto no front, quanto no backend.
- No caso de frameworks como Laravel, inserir logo os dados do Request.

```php
class Usuario
{
  public function store()
  {
    $email = trim($_GET['email']);
    $email = filter_var($email, FILTER_VALIDATE_EMAIL);

    $nome = trim($_GET['nome']);
    $nome = filter_var($nome, FILTER_SANITIZE_STRING);
    
    if (!$email || !$name) {
      // redireciona
    }
    ...
  }
}

// no laravel
class UsuarioService
{
  public function store(int $usuarioId, Request $request)
  {
    $validatedData = $request->validate([
      'nome' => ['required'],
      'nick' => ['required'],
    ]);
    ...
  }
}
```

### Não validar rotas

Você possui uma rota para excluir um produto, mas quem pode acessar aquela rota? Digamos que o sistema possua diversos usuários e cada usuário possui seus produtos. Temos as seguintes rotas:

- produtos
- produtos/{id}
- produtos/{id}/destroy

Todas elas possuem o `middleware auth`, que diz que somente os usuários logados podem acessar. Certo! Eu estou autenticado, porém o produto de id 4 não pertence a mim, mas mesmo assim eu poderia acessar a rota `produtos/{id}/destroy` e remover aquele produto. Há algumas maneiras de corrigir isso, você poderia buscar o id do produto junto ao id do usuário por exemplo:

```php
class ProdutoController
{
  public function destroy(int $idProduto)
  {
    $produto = Produto::query()
      ->where("id", $idProduto)
      ->where("usuario_id", auth()->user()->id)
      ->first();
    if ($produto && $produto->delete()) {
      return response()->json([
        "type" => "success",
        "message" => "Produto deletado com sucesso!"
      ]);
    }
    return response()->json([
      "type" => "error",
      "message" => "Algo deu errado ao tentar deletar o produto!"
    ]);
  }
}
```

### Passar mais informações que o necessário nas requisições

Já vi e já cometi esse tipo de erro, e acredito que seja um erro grave! Na hora de entregar dados vindos do banco para o usuário, é necessário verificar o que está sendo passado.

Vejamos a seguinte situação. Tenho um site que funciona como uma rede social, quando um usuário vai pesquisar alguém, ele irá encontrar outros usuários que ele nem conhece, não é mesmo? E se na hora de pesquisar eu retornasse todos os dados daquele usuário? Por exemplo:

```json
{
  "total": 1,
  "usuarios": [
    {
      "id": 1234,
      "nome": "Fulano da Silva",
      "email": "fulanodasilva@gmail.com",
      "endereco": "Rua Dos Bobos, nº 0",
      "bairro": "Bairro da Laranjeira",
      "cidade": "Vila Nova da Rainha",
      "telefone": "(99) 9999-9999",
      "celular": "(99) 9 1111-1111",
      "relacionamento_id": 2,
      "parceiro_id": 5,
      "forma_de_pagamento": {
        "banco": "Banco do Brasil",
        "ag": 1234,
        "conta": 45678
      }
    }
  ]
}
```

Primeiro que você estaria perdendo performance por estar buscando informações que não são necessárias, e segundo que você não sabe para quem está indo aquelas informações.

## Esperar que o usuário conheça tanto tecnologia quanto você

Um outro erro é achar que o usuário sabe sempre o que está fazendo, que não precisa deixar a coisa descritiva, pois… quem, afinal, não sabe o que o ícone tal representa?

A gente não conhece todos os usuários, às vezes nem um sequer, dos nossos sistemas! A gente não deve esperar que atrás da tela esteja alguém que saiba tudo sobre tecnologia, alguém que conheça técnicas para melhor fazer seu trabalho etc. É melhor esperar um usuário leigo, descrever o funcionamento da coisa, do que achar que o usuário vai saber o que fazer. Talvez a pessoa que irá usar o sistema, acabou de migrar de algo físico pra digital. Acabou de trocar papel e caneta por um teclado e um mouse.

*Uma outra coisa que ainda não sou capaz de falar sobre, mas que vem me intrigando, é o acesso a pessoas com deficiência ou algum tipo de limitação.*

---

Vamos parar por aqui, mas quero continuar falando sobre esse assunto. Quando penso em uma coisa, lembro de outra e assim em diante.