Pergunta

Digamos que eu tenho uma aula como esta:

class MonkeyFish
{
   MonkeyFish( GlobalObjectA & a, GlobalObjectB & b, GlobalObjectC & c);

   private:
     GlobalObjectA & m_a;
     GlobalObjectB & m_b;
     GlobalObjectC & m_c;
}

Sem uma fábrica, preciso fazer o seguinte para instantar um MonkeyFish.

GlobalObjectA a;
GlobalObjectB b;
GlobalObjectC c;

int main()
{
  MonkeyFish * monkey_fish = new MonkeyFish(a, b, c);
  monkey_fish->go();
}

Por outro lado, se eu tiver um MonkeyFishFactory, parece que tenho que fazer isso:

GlobalObjectA a;
GlobalObjectB b;
GlobalObjectC c;

int main()
{
  MonkeyFishFactory mf_factory(a, b, c);
  MonkeyFish * monkey_fish = mf_factory.buildMonkeyFish("Bob");
  monkey_fish->go();
}
  1. Eu ainda tenho objetos globais.

  2. Mesmo que o próprio macaco tenha criado o próprio GlobalObjects Internamente (então eles agora estão dentro do macaco -pescam em si ainda precisa ser um objeto global para que eu possa acessá -lo sempre que quiser criar um MonkeyFish.

O padrão de fábrica não é a mesma coisa que o estado global neste caso?

(Atualmente, estou operando sob a suposição de que o estado global é uma coisa ruim e eliminando isso é uma coisa boa.)

Foi útil?

Solução

Você está confundindo conceitos aqui?

O padrão de fábrica é geralmente aplicado quando você está retornando uma instância de uma classe de concreto que se esconde atrás de uma interface abstrata. A idéia é que o chamador veja apenas a interface e nem precisa saber qual é o tipo concreto do objeto. Trata -se de criar uma instância de objeto com base em parâmetros e desacoplar a lógica associada à decisão de qual objeto criar do usuário criando o objeto.

O que você está descrevendo é uma mistura de singleton (ou monostato) e fábrica. Sua fábrica tem estado para que não possa ser tornada estática. Nesse caso, você precisará aplicar algo como o padrão Singleton para controlar a criação de uma única instância de fábrica com os globais apropriados escondidos nele:

class IMonkeyFish {
public:
    virtual ~IMonkeyFish() = 0;
    virtual void go() = 0;
};

class Factory {
public:
    static Factory& instance();
    IMonkeyFish* createMonkeyFish();
protected:
    Factory(GlobalObjectA& a, GlobalObjectB& b, GlobalObjectC& c);
private:
    static Factory *theInstance;
    GlobalObjectA&  instanceOfA;
    GlobalObjectB&  instanceOfB;
    GlobalObjectC&  instanceOfC;
};

Factory& factory = Factory::instance();
IMonkeyFish* fishie = factory.createMonkeyFish();
fishie->go();

o Singleton O padrão governa a criação da instância da fábrica. o Factory padrão esconde os detalhes em torno da criação de objetos que implementam o IMonkeyFish interface. A coisa boa (TM) é o esconderijo do estado global e a dissociação do MonkeyFish detalhes concretos da criação de uma instância.

O uso ou correção de usar o Singleton O material é uma outra questão. Provavelmente há um monte de fios flutuando sobre isso também.

Outras dicas

O estado global não é uma coisa ruim. Público O estado global é uma coisa ruim. O padrão de fábrica ajuda a encapsular o estado global, o que é uma coisa boa.

Não há estado global na fábrica. Apenas cria objetos. Já que não é nenhum estado na fábrica. Não há problema em ser global.

Você não precisa deixar objetos globais. A fábrica de peixes de macaco deve criar aqueles objetos globais | B | C sob demanda. Usando o switch ou se método interno para determinar qual.

Você encapsulou o controle sobre a criação de objetos em uma fábrica. Você deseja que seus detalhes de instanciação sejam escondidos, não reproduzidos em todos os lugares que você precisa de um novo macaco. Pense em testes, responsabilidade única e lei do Demeter. Por que sua turma que deseja usar um peixe -macaco precisa saber qualquer coisa sobre o trabalho necessário para construir uma. E se você quiser testar o Monkeyfish? Como você faria isso se não tivesse detalhes da criação encapsulados?

O trabalho de uma aula de fábrica é instanciar um objeto e passá -lo de volta ao chamador; não escolher qual objeto instanciado global usar. Portanto, seu exemplo de fábrica está incorreto. Deveria ser:

int main()
{
  MonkeyFish * monkey_fish = MonkeyFishFactory::buildMonkeyFish("Bob");
  monkey_fish->go();
}

Observe, sem objetos globais, e o MonkeyfishFactory não é instanciado.

Eu acho que você está pensando no padrão de singleton, não no padrão de fábrica. No padrão Singleton, você só tem em instância de uma classe que basicamente o torna equivalente a um objeto global, exceto que não há variável global anexada a ele.

Você deve declarar suas restrições e requisitos se quiser obter uma boa resposta. A coisa mais importante para obter uma boa resposta é saber qual pergunta fazer.

Nos trechos de código, você desde que decidiu usar globais, mas isso não tem nada a ver com você usar uma fábrica ou não. Se você usa uma fábrica que ainda depende desses globais, basta ter outro código para se acumular com o resto.

Tente declarar claramente o que você está tentando alcançar e provavelmente obterá uma resposta melhor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top