17.12
2020
Design Patterns, ou Padrões de Projeto, são soluções gerais para problemas comuns de desenvolvimento de software, apesar de controversas são considerados um conjunto de melhores práticas. Um desses padrões é o Singleton, utilizado para garantir que somente haverá uma instância dessa classe no programa todo, sem impactar na facilidade de acesso a essa instância.
Singleton Template
Uma abordagem para criação de um singleton é a criação de uma classe template, que gerencia a instanciação da classe:
#include <iostream>
#include <string>
template <class T>
class Singleton {
private:
static T* instance;
public:
static T& getInstance() {
if (!instance)
instance = new T();
return *instance;
}
};
template <class T>
T* Singleton<T>::instance = NULL;
class Config {
private:
Config() {
std::cout << "New Config instance" << std::endl;
}
friend class Singleton<Config>;
public:
bool parse(std::string filename) {
return true;
}
std::string getValue(std::string key) {
return "";
}
};
int main() {
Config config = Singleton<Config>::getInstance();
Config conf = Singleton<Config>::getInstance();
}
A saída para o código acima:
New Config instance
Note a classe Singleton, bem simples, usando template, e o método getInstance. A class Config precisa de duas coisas: primeiro precisa ter um construtor privado evitando ser instanciado com new; segundo precisa declarar a classe Singleton como friend para que somente a Singleton possa acessar seu construtor.
A partir daí sempre que for chamado Singleton<Config>::getInstance() haverá uma única instanciação da classe Config, e nenhuma mais.
Um cuidado com a classe declarada acima é a concorrência, como Singleton::getInstance() não é atômico, pode ocorrer de duas threads distintas solicitem uma instância simultaneamente, o que pode causar uma racing condition, e duas instâncias da classe ser criada. Isso pode ser resolvido com um mutex.
Desvantagens do Singleton
Como a implementação depende de uma classe estática, haverá alguns problemas no desenvolvimento de mocks para testes unitários, dificultando TDD.
Além disso existe o criticismo dos Design Patterns, diz que os Design Patterns apesar de parecerem uma ótima ideia podem trazer mais problemas que soluções a partir do momento em que o esforço para se manter dentro dos padrões acaba por dificultar o desenvolvimento ou a manutenção do código. Mas é uma discussão muito maior que um Snippets para Singleton.