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 uma resposta

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:

Implementing a good caching strategy is fundamental to achieve good performance. Besides that, it is not a trivial task. There...
Nossos códigos precisam ser fáceis de compilar e testar. Para isso, nada melhor do que começarmos da forma certa, com...
For years, I have known developers who designed beautiful architectures. A lot of them are questioning the need for a...
No último post desta série, tratamos da “Lei do Retorno Acelerado”. Sabemos que negócios digitais tem crescimento potencialmente exponencial. Neste...
Há algum tempo aponto o “abuso” do GC é uma das principais causa para problemas de performance em produção. Nesse...
O comportamento que descrevo nesse post é extremamente nocivo a carreira de todo técnico. Geralmente resulta em desgaste desnecessário e...