Singleton Será um anti-pattern ? E o Repository?

Mónica Rodrigues
4 min readJul 15, 2018

Em primeiro lugar este artigo tal como outros será em Português. E porquê? Para apelar à existência de bons artigos técnicos portugueses que são muito escassos. Todos os termos técnicos serão escritos em Inglês assim como alguns títulos, pois na minha opinião muitos não devem ser traduzidos, soam melhor em Inglês e é o que muitos de nós já estamos habituados a ver.

Este poderá ser ou não um artigo que cause muita discussão ou até alguma polémica. No entanto, não resisto em partilhar uma discussão que tive com um colega muito recentemente, em torno de algo que aparenta ser tão simples à primeira vista.

Dos vários padrões de desenho existentes, o Singleton é um dos mais simples de implementar. O problema que ele resolve é garantir que usas sempre a mesma instância.

Segue uma possível implementação:

public class Singleton
{
private static readonly Singleton instance = new Singleton();
static Singleton() { } public static Singleton Instance
{
get
{
return instance;
}
}
}

Depois de se falar da utilidade do Singleton, eis que surge a seguinte frase:

O Singleton é um anti-pattern.

Uma pessoa que olhe para esta frase provavelmente pode começar a mandar vir. No entanto, acho que essa não é a abordagem correcta e devemos ter uma mente aberta e perceber as razões que estão por detrás daquela afirmação e o que leva a pensar aquilo.

Pelo facto de eu ser uma pessoa de mente aberta e embora faça um esforço diário para aplicar boas práticas, aquela frase deixou-me a pensar, levando-me à seguinte pergunta:

  • O que faz esta classe?

Se olharmos para a classe com atenção deparamo-nos que ela apresenta duas responsabilidades:

  • Criar a instância
  • Devolver o objecto

Isso significa que viola o SRP (Single Responsability Principle) que diz que uma classe deve ter uma e uma só responsabilidade e observando o nosso Singleton apresenta mais do que uma. É incrível como uma simples classe pode dizer tanta coisa e muitas das vezes nem reparas nisso só pelo facto de aquilo ser um padrão de desenho conhecido e defendido pela maioria.

E agora perguntas, como evito isso? Não usando o Singleton. Delegas a responsabilidade de cuidar da instância para uma outra classe. Provavelmente já usaste o IoC, se fores a pensar ele faz isto tudo de forma transparente sem te preocupares e essa pode ser uma solução.

Note-se que não te estou a dizer para deixares de usar o Singleton, apenas estou a alertar que é importante ter estes promenores em mente. Por vezes usamos certos de padrões de código e estamos a violar um princípio, mas tudo bem. Não tem mal nenhum usar o Singleton. Puristas de OOP provavelmente não vão usar mesmo. É um padrão existente e conhecido e o teu código está legível na mesma. Mas é bom ter estas discussões em mente.

Vamos olhar agora para o Repository. Segue uma possível interface do mesmo:

public interface IRepository<TEntity>
{
IEnumerable<TEntity> GetAll();
IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> expression); TEntity Get(Expression<Func<TEntity, bool>> expression); void Add(TEntity entity); void Update(TEntity entity); void Remove(Expression<Func<TEntity, bool>> expression);
}

Se reparares as classes que a vão implementar vão ter quatro responsabilidades:

  • Obter entidades
  • Adicionar uma nova entidade
  • Actualizar uma entidade
  • Remover uma entidade

Onde está o princípio de responsabilidade única? Incrível não é? E quantas vezes nós usamos esta solução? Imensas. Tem classes que vão sempre fazer mais do que uma coisa mas no contexto do nome da classe é como se ela só tivesse uma responsabilidade. É aqui que atribuição de nomes numa classe se torna tão importante mas tão difícil ao mesmo tempo. Imagina uma SnackMachine, tens que ter comportamentos que te permitam inserir dinheiro e comprar o snack. Faz tudo parte do mesmo domínio. Agora o importante é garantires que cada método tem uma única responsabilidade e vais ver como a tua vida fica tão mais simples.

Esta é uma razão pela qual fazer software se torna tão difícil. As opiniões se divergem constantemente, há sempre vantagens e desvantagens, mas é isso que nos faz crescer, aprender e evoluir. E depois desta linda discussão senti que evolui mais um pouco ou não hehe.

Conclusão

Para concluir, e voltando às discussões sobre os padrões Singleton e Repository considero importante ter noção destes aspectos, aliás estas são para mim as discussões mais interessantes e é em sessões de pair e mob programming que muitas das vezes elas surgem, daí ter uma certa “paixoneta“ por essas sessões e de não gostar de trabalhar sozinha, embora trabalhe quando necessário, claro.

Mais uma vez obrigado por perderes um tempinho a ler o meu artigo. Todos os comentários são muito bem vindos, seja a dizer bem ou mal porque como te dei a entender, sou uma pessoa aberta que gosta de ouvir outras opiniões.

--

--

Mónica Rodrigues

A content creator about leadership, personal development and software. Follow @monicarodriguesjourney on Instagram for more content also.