Quando ‘null’ é um problema

Como um programador experiente, você precisa lidar com ocorrências NullReferenceException todos os dias. Certo? Eu defendo que este é um problema de design. Por favor, considere o código que segue:

public interface IEmployeeRepository
{
  Employee GeyById(string id);
}

class EmployeeRepository : IEmployeeRepository
{
  public Employee GetById(string id)
    => new DbContext().Find(id);
}

Qual deveria ser o resultado da execução de GetById? Uma instância de Employee, certo? Infelizmente, este não é o caso sempre. Se não há registro com o id especificado, o resutaldo seria null. Talvez você esteja conformado com isso. Eu não!

O fato é que o código não é totalmente claro sobre qual deveria ser o resultado esperado para a execução desse método. Como programador experiente, algumas vezes você vai verificar o resultado do método, mas as vezes não…

Minha proposta seria começar a usar um container indicando que, as vezes, o resultado seria “sem resultado”.

public interface IEmployeeRepository
{
  Option<Employee> GeyById(string id);
}

class EmployeeRepository : IEmployeeRepository
{
  public Option<Employee>; GeyById(string id)
    =>; new DbContext().Find(id);
}

Agora o código é bem mais claro. Não acha?

Sobre a implementação de Option

O tipo Option é apenas uma struct que provê algumas conversões implicitas e algumas operações funcionais básicas.

A coisa mais interessante sobre essa abordagem é que os programadores consumindo EmployeeRepository do exemplo anterior não teriam mais acesso direto a (possível) instância de employee. O único meio para ter acesso seria através do container.

public IActionResult Get(string id) => _repository.GetById(id)
  .Match<IActionResult>(
    some: employee => Ok(employee),
    none: () => NotFound()
  );

NullReferenceExcption se foi!

Legal, não acha? Option está disponível no meu github.

Compartilhe este insight:

3 respostas

  1. Muito interessante, Elemar! São pequenos cuidados assim que tornam nossas aplicações cada vez melhores!

  2. Excelente post.

    Uma duvida, no caso onde o repositorio esta implementado com async/await sendo que retorna uma Task funcionaria igual?

    A implementacao seria algo como: public async Option<Task<List>> GetXpto() ?

    Abs,

Deixe um comentário

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

Elemar Júnior

Sou fundador e CEO da EximiaCo e atuo como tech trusted advisor ajudando diversas empresas a gerar mais resultados através da tecnologia.

Elemar Júnior

Sou fundador e CEO da EximiaCo e atuo como tech trusted advisor ajudando diversas empresas a gerar mais resultados através da tecnologia.

Mais insights para o seu negócio

Veja mais alguns estudos e reflexões que podem gerar alguns insights para o seu negócio:

Há tempos, venho pensando sobre “mérito”. Superficialmente, quanto dos meus resultados, positivos e negativos, se devem exclusivamente a mim? Descartando...
Publicado originalmente em meu linkedin Se há algo que aprendi, tanto academicamente quanto empiricamente, é que a motivação é intrínseca...
Dando continuidade a uma jornada iniciada há mais de 20 anos, comunico a fundação da Eximia! Trata-se de uma empresa...
Sometimes we want to write functions that may not always return a result. In these cases we can use the...
Este post é uma releitura de um que havia escrito, em 2016, e que se perdeu no “reboot” do blog....
Uma das premissas fundamentais do conceito de contrato social é que nós, como indivíduos livres, abrimos mão do direito natural...