Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Professional C++ [eng].pdf
Скачиваний:
284
Добавлен:
16.08.2013
Размер:
11.09 Mб
Скачать

Chapter 26

mNumCarsInProduction++; return createCar();

}

int CarFactory::getNumCarsInProduction() const

{

return mNumCarsInProduction;

}

Car* FordFactory::createCar()

{

return new Ford();

}

Car* ToyotaFactory::createCar()

{

return new Toyota();

}

The implementation approach used in this example is called an abstract factory because the type of the object that is created depends on which concrete subclass of the factory class is being used. A similar pattern can be implemented in a single class instead of a class hierarchy. In that case, a single create() method takes a type or string parameter from which it decides which object to create. For example, a CarFactory object would provide a buildCar() method that takes a string representing the type of car and constructs the appropriate type. However, that technique is less interesting and less flexible than the factory hierarchy described previously.

Factory methods are one way to implement virtual constructors: methods that create objects of different types. For example, the buildCar() method creates both Toyotas and Fords, depending on the concrete factory object on which it is called.

Using a Factory

The simplest way to use a factory is simply to instantiate it and to call the appropriate method, as in the following piece of code:

ToyotaFactory myFactory;

Car* myCar = myFactory.requestCar();

A more interesting example makes use of the virtual constructor idea to build a car in the factory that has the fewest cars in production. To do this, you will need a function that looks at several factories and chooses the least busy one, such as the following function:

CarFactory* getLeastBusyFactory(const vector<CarFactory*>& inFactories)

{

if (inFactories.size() == 0) return NULL;

CarFactory* bestSoFar = inFactories[0];

764

Applying Design Patterns

for (size_t i = 1; i < inFactories.size(); i++)

{

if (inFactories[i]->getNumCarsInProduction() < bestSoFar->getNumCarsInProduction()) { bestSoFar = inFactories[i];

}

}

return bestSoFar;

}

The following sample program makes use of this function to build 10 cars, whatever brand they might be, from the currently least busy factory.

int main(int argc, char** argv)

{

vector<CarFactory*> factories;

//Create 3 Ford factories and 1 Toyota factory. FordFactory* factory1 = new FordFactory(); FordFactory* factory2 = new FordFactory(); FordFactory* factory3 = new FordFactory(); ToyotaFactory* factory4 = new ToyotaFactory();

//To get more interesting results, preorder some cars. factory1->requestCar();

factory1->requestCar(); factory2->requestCar(); factory4->requestCar();

//Add the factories to a vector.

factories.push_back(factory1); factories.push_back(factory2); factories.push_back(factory3); factories.push_back(factory4);

// Build 10 cars from the least busy factory. for (int i = 0; i < 10; i++) {

CarFactory* currentFactory = getLeastBusyFactory(factories); Car* theCar = currentFactory->requestCar();

theCar->info();

}

}

When executed, the program will print out the make of each car produced:

Ford

Ford

Ford

Toyota

Ford

Ford

Ford

765