As fábricas têm muitas vantagens que permitem o design elegante de aplicativos em algumas situações. Uma é que você pode definir as propriedades dos objetos que deseja criar posteriormente em um só lugar, criando uma fábrica e depois entregá-la. Mas muitas vezes você realmente não precisa fazer isso. Nesse caso, o uso de uma fábrica apenas adiciona complexidade adicional sem fornecer nada em troca. Vamos pegar esta fábrica, por exemplo:
WidgetFactory redWidgetFactory = new ColoredWidgetFactory(COLOR_RED);
Widget widget = redWidgetFactory.create();
Uma alternativa ao padrão Factory é o padrão Builder muito semelhante. A principal diferença é que as propriedades dos objetos criados por um Factory são definidas quando o Factory é inicializado, enquanto um Builder é inicializado com um estado padrão e todas as propriedades são definidas posteriormente.
WidgetBuilder widgetBuilder = new WidgetBuilder();
widgetBuilder.setColor(COLOR_RED);
Widget widget = widgetBuilder.create();
Mas quando a superengenharia é o seu problema, substituir uma fábrica por um construtor provavelmente não é uma grande melhoria.
A substituição mais simples para qualquer padrão é, obviamente, criar instâncias de objetos com um construtor simples com o new
operador:
Widget widget = new ColoredWidget(COLOR_RED);
Os construtores, no entanto, têm uma desvantagem crucial na maioria das linguagens orientadas a objetos: eles devem retornar um objeto dessa classe exata e não podem retornar um subtipo.
Quando você precisar escolher o subtipo em tempo de execução, mas não desejar recorrer à criação de uma nova classe Builder ou Factory para isso, poderá usar um método de fábrica. Este é um método estático de uma classe que retorna uma nova instância dessa classe ou de uma de suas subclasses. Uma fábrica que não mantém nenhum estado interno geralmente pode ser substituída por um método de fábrica:
Widget widget = Widget.createColoredWidget(COLOR_RED); // returns an object of class RedColoredWidget
Um novo recurso no Java 8 são as referências de métodos que permitem transmitir métodos, como faria com uma fábrica sem estado. Convenientemente, qualquer coisa que aceite uma referência de método também aceita qualquer objeto que implemente a mesma interface funcional, que também pode ser uma Fábrica de pleno direito com estado interno, para que você possa facilmente introduzir fábricas mais tarde, quando perceber uma razão para fazê-lo.