Singleton - A Bola do Jogo
Tags: designpatterns, dotnet, dotnetcore
Published: 2023-11-22 23:43:08

## Analogia
Assim como basquete, futebol, tenis, entre outros esportes, uma das regras do jogo é: **Só se deve existir uma bola**. Isso porque no que diz respeito a lógica, muitas das vezes não é lógico a existência de mais de uma bola em jogo. Imagine, ao assistir um jogo de futebol do seu time favorito, perceber que há duas bolas ou mais em jogo, seria muito complexo o entendimento do real motivo daquilo. Pois bem, assim como em um jogo de futebol que só se deve existir uma bola em jogo, o **Singleton** é mantenedor da mesma regra. Ou seja, **Ele se mantém único durante todo o ciclo de vida do sistema**.

## Representando a bola do jogo com o Pattern **Singleton**.

Para representar a bola do jogo iremos trabalhar com linguagem C#. **note que a linguagem é indiferente e o que se deve entender é o propósito do Pattern e seu funcionamento**.

Entendendo que nosso objeto principal é uma bola, criaremos uma classe de sua representação.

> Nota: O método `GetSoccerBallId()` será utilizado posteriormente para obtermos a identificação da instancia da Bola. **Isso facilitará mais ainda o entendimento do Pattern**.


```C#
    public class SoccerBall
    {
        public void GetSoccerBallId(string name){
            Console.Write($"{name} - Ball code: ");
            
            Console.ForegroundColor = ConsoleColor.Yellow;
            
            Console.WriteLine(this.GetHashCode());
            
            Console.ForegroundColor = ConsoleColor.White;

        }
    }
```

Claro que em jogo  de futebol uma bola só tem sentido quando em uso por jogadores. **Criaremos então nossa classe de Jogadores**.

```c#
    public class PlaySoccer
    {
        public PlaySoccer(string name)
        {
            Name  = name;
        }
        public string Name { get; private set; } = "";
        public SoccerBall? SoccerBall { get; set; }
    }
```
> Nossa classe `PlaySoccer` tem um atributo `Name` e a bola `SoccerBall` que hipoteticamente está em sua posse.

Ao atribuir uma bola para cada jogador e verificar o código hash da bola, veremos que para cada jogador uma nova bola é criada.  

```c#
PlaySoccer everton  = new("Everton")
{
     SoccerBall =   new SoccerBall()
};
everton.SoccerBall.GetSoccerBallId(everton.Name);

PlaySoccer veiga = new("Veiga")
{
    SoccerBall = new SoccerBall()
};
veiga.SoccerBall.GetSoccerBallId(veiga.Name);


PlaySoccer vini = new("Vinicius Junior")
{
    SoccerBall = new SoccerBall()
};
vini.SoccerBall.GetSoccerBallId(vini.Name);


PlaySoccer rodrigo = new("Rodrigo")
{
    SoccerBall = new SoccerBall()
};
rodrigo.SoccerBall.GetSoccerBallId(rodrigo.Name);
```

Resultado

```shell
Everton - Ball code: 58225482
Veiga - Ball code: 54267293
Vinicius Junior - Ball code: 18643596
Rodrigo - Ball code: 33574638
```
> Observe os códigos hash's
- 58225482
- 54267293
- 18643596
- 33574638

**Até aqui não houve controle de instancia e para cada jogador uma nova bola foi criada.
**

Criaremos agora uma classe de controle que instancia e verifica se a instancia da bola existe e à retorna únicamente para o jogador.


```c#
    public class SingletonBall
    {
        private static SoccerBall? SoccerBall = null;

        public static SoccerBall GetSoccerBall()
        {
            SoccerBall ??= new SoccerBall();

            return SoccerBall;
        }
    }
```

Agora passe a bola para cada jogador utilizando a rotina criada acima.

```C#
PlaySoccer everton  = new("Everton")
{
     SoccerBall = SingletonBall.GetSoccerBall()
};
everton.SoccerBall.GetSoccerBallId(everton.Name);

PlaySoccer veiga = new("Veiga")
{
     SoccerBall = SingletonBall.GetSoccerBall()
};
veiga.SoccerBall.GetSoccerBallId(veiga.Name);


PlaySoccer vini = new("Vinicius Junior")
{
     SoccerBall = SingletonBall.GetSoccerBall()
};
vini.SoccerBall.GetSoccerBallId(vini.Name);


PlaySoccer rodrigo = new("Rodrigo")
{
     SoccerBall = SingletonBall.GetSoccerBall()
};
rodrigo.SoccerBall.GetSoccerBallId(rodrigo.Name);
```

resultado

```bash
Everton - Ball code: 58225482
Veiga - Ball code: 58225482
Vinicius Junior - Ball code: 58225482
Rodrigo - Ball code: 58225482
```

> Note que o hash da bola não muda, isso indica que todos os jogadores utilizaram a mesma bola.

- 58225482
- 58225482
- 58225482
- 58225482

E aqui encerramos o **Singleton** com a bola do Jogo!


[Github](http://github.com/reginaldo-marinho)

[Meu Projeto](https://rucula-js.github.io/)

[Contribua, favorite ⭐](https://github.com/rucula-js/rucula-js)