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:

I have no idea of how many times I had to write a function do discover the minimum and the...
A aquisição de novos clientes é importante para o crescimento. Entretanto, a manutenção dos clientes atuais tende a ser mais...
Publicado originalmente em meu linkedin Se há algo que aprendi, tanto academicamente quanto empiricamente, é que a motivação é intrínseca...
It’s time to start learning RavenDB 4. Even if you know previous versions of RavenDB, you will probably get good...
Neste post, compartilho um exemplo de implementação para um algoritmo extremamente famoso e importante: O algoritmo de Dijkstra. Trata-se de...
Estamos, a maioria, em casa. Nossas rotinas não são as mesmas. Boa parte das atividades econômicas estão paradas. Aqueles que...
× Precisa de ajuda?