Imagine que você tenha um tipo que ocupa muito espaço na memória, ou que requer muitos recursos para ser instanciado. Se uma instância deste tipo puder ser reutilizada em diferentes lugares da aplicação, isso diminuiria o consumo de memória ou dos recursos consumidos para criação.
A descrição formal do Singleton é a seguinte: O Singleton garante que uma classe tenha apenas uma instância e fornece um ponto global de acesso a ela.
Um exemplo seria uma classe de geração de log. Dentro de uma aplicação, faria sentido haver apenas uma instância da classe responsável por escrever em um arquivo (ou base de dados) de log. Isso reduziria problemas de concorrência no acesso ao arquivo de log, pois a mesma seria tratada dentro do próprio Singleton, uma vez que haveria apenas uma única instância da classe de log acessando o arquivo.
Neste exemplo, teríamos o seguinte desenho:
Observe que temos o método construtor privado, o que não permite que a classe seja instanciada com o comando new por outras classes. Temos também um atributo estático que armazena a única instância de Log na aplicação, e o método ObterInstância() que retorna essa única instância.
O Singleton pode trazer problemas em alguns aspectos: ele pode ser um ponto de gargalo em aplicações que usam threads, devido à concorrência no acesso à instância única. Outro ponto que deve ser considerado: é interessante para a sua aplicação que o estado do objeto singleton seja compartilhado? Se não, você deve evitar o singleton, pois ele pode trazer problemas que serão difíceis de rastrear.
Baixe o código-fonte do exemplo em C# (requer o Visual Studio 2010)