/* 
 * factory.cpp
 *
 * Example of Factory Method
 *
 * Define an interface for creating an object, but
 * let subclasses decide which class to instantiate.
 */

#include <iostream>

class Product {
public:
  virtual void operation() = 0;
};

class ConcreteProduct : public Product {
public:
  void operation() { std::cout << "ConcreteProduct\n"; }
};


class CollardProduct : public Product {
public:
  void operation() { std::cout << "CollardProduct\n"; }
};

class Creator {
public:
  virtual Product* factoryMethod() = 0;

  void operation() { }
};

class ConcreteCreator : public Creator {
public:
  virtual Product* factoryMethod() { return new ConcreteProduct; }
};


class CollardCreator : public Creator {
public:
  virtual Product* factoryMethod() { return new CollardProduct; }
};

class Client {
public:
  Client(Creator& creator) : _creator(creator) {}

  void dosomething() {
    Product* pproduct = _creator.factoryMethod();

    pproduct->operation();
  }

private:
  Creator& _creator;
};



int main() {

  ConcreteCreator concreteCreator;

  Client client(concreteCreator);

  client.dosomething();

  CollardCreator collardCreator;

  Client client2(collardCreator);

  client2.dosomething();
}
