A moda do padrão Factory deriva de uma crença quase dogmática entre codificadores em linguagens "C-style" (C / C ++, C #, Java) de que o uso da palavra-chave "new" é ruim e deve ser evitado a todo custo (ou pelo menos menos centralizado). Por sua vez, isso provém de uma interpretação ultra-estrita do Princípio de Responsabilidade Única (o "S" do SOLID) e também do Princípio de Inversão da Dependência (o "D"). Em termos simples, o SRP diz que, idealmente, um objeto de código deve ter um "motivo para mudar" e apenas um; esse "motivo para mudar" é o objetivo central desse objeto, sua "responsabilidade" na base de código e qualquer outra coisa que exija uma alteração no código não deve exigir a abertura desse arquivo de classe. O DIP é ainda mais simples; um objeto de código nunca deve depender de outro objeto concreto,
Caso em questão, usando "new" e um construtor público, você está acoplando o código de chamada a um método de construção específico de uma classe concreta específica. Seu código agora precisa saber que existe uma classe MyFooObject e possui um construtor que aceita uma string e um int. Se esse construtor precisar de mais informações, todos os usos do construtor precisam ser atualizados para passar essas informações, incluindo a que você está escrevendo agora, e, portanto, eles precisam ter algo válido para passar e, portanto, devem ter ou seja alterado para obtê-lo (adicionando mais responsabilidades aos objetos de consumo). Além disso, se o MyFooObject for substituído na Base de Código pelo BetterFooObject, todos os usos da classe antiga precisarão ser alterados para construir o novo objeto em vez do antigo.
Portanto, todos os consumidores do MyFooObject devem depender diretamente do "IFooObject", que define o comportamento da implementação de classes, incluindo o MyFooObject. Agora, os consumidores do IFooObjects não podem apenas construir um IFooObject (sem ter o conhecimento de que uma classe concreta específica é um IFooObject, da qual eles não precisam); portanto, eles devem receber uma instância de uma classe ou método de implementação do IFooObject do lado de fora, por outro objeto que tem a responsabilidade de saber como criar o IFooObject correto para a circunstância, que em nossa linguagem é geralmente conhecida como Fábrica.
Agora, é aqui que a teoria encontra a realidade; um objeto nunca pode ser fechado para todos os tipos de alterações o tempo todo. Caso em questão, o IFooObject agora é um objeto de código adicional na base de código, que deve mudar sempre que a interface exigida pelos consumidores ou as implementações do IFooObjects mudam. Isso introduz um novo nível de complexidade envolvido na alteração da maneira como os objetos interagem entre si nessa abstração. Além disso, os consumidores ainda terão que mudar, e mais profundamente, se a própria interface for substituída por uma nova.
Um bom codificador sabe como equilibrar o YAGNI ("Você não precisará dele") com o SOLID, analisando o design e encontrando locais que provavelmente terão que mudar de uma maneira específica, e refatorando-os para serem mais tolerantes a que tipo de mudança, porque, nesse caso, "você está indo precisar dele".