10.04
2023
O pattern Factory Methods é uma forma de encapsular o construtor de forma a tornar a criação de objetos muito mais flexível e acessível às classes derivadas. Basicamente é um método estático chamado no lugar no operador new para alocar uma nova instância da classe. Veja o exemplo a seguir:
#include <iostream>
#include <string>
class Part {
private:
protected:
std::string id;
Part() {
id = "";
std::cout << " -> New empty part constructor" << std::endl;
}
Part(std::string id) {
this->id = id;
std::cout << " -> New part constructor by id" << std::endl;
}
Part(std::string name, std::string instance, std::string rev) {
std::cout << " -> query for part on database" << std::endl;
std::cout << " -> New part construcutor by part data" << std::endl;
}
public:
~Part() {
std::cout << "-> Part destructor" << std::endl;
}
static Part* createPart() {
std::cout << "-> Execute checks and preparations for new empty part" << std::endl;
return new Part();
}
static Part* createPart(std::string id) {
std::cout << "-> Execute checks and preparations for new part by id" << std::endl;
return new Part(id);
}
static Part* createPart(std::string name, std::string instance, std::string rev) {
std::cout << "-> Execute checks and preparations for new part by part data" << std::endl;
return new Part(name, instance, rev);
}
};
int main() {
Part* first = Part::createPart();
Part* second = Part::createPart("0123456789ABCDEF");
Part* third = Part::createPart("Name", "1", "1");
delete first, second, third;
}
Neste exemplo o retorno para os objetos é em forma de ponteiros, mas é possível também ser feito por valor, ou referência, facilitando a gestão da memória.
Cuidados
Muito cuidado com a documentação de códigos deste tipo. É necessário deixar bem documentado a forma de desalocação dos objetos alocados, seja deixando a responsabilidade da desalocação (delete) pelo método que efetuou o chamado, ou por um método específico para isso (Part::destroyPart(), por exemplo).
Profissionalmente
Algumas equipes não aceitam a utilização do operador new, sendo obrigatório sempre haver um Factory Method, outras apenas incentivam quando há necessidade.
Quanto maior a complexidade de inicialização de um objeto, mais indicado é o Factory Method. Uma máquina de estados é um bom exemplo, ainda mais se os estados e suas conexões dependerem de uma fonte de dados externa, como um arquivo ou uma base de dados.