Abstract Factory
Problem Description
The scenario is in a game, where there are enemies like tanks, airplanes, automobiles and bosses, items like medicines, bullets.
This game has two levels: easy and hard. Enemies and items of different level has different appearance, behaviour and other properties. So enemy and item should be abstract classes, enemy and item of a specific level should be instantiation class.
We also regulate any one plays the game only under one level at one time, which means at one time there are only a cluster(level) of objects.
Source
#pragma once
class Enemy {
public:
Enemy(){}
virtual ~Enemy()=0;
};
class EasyEnemy : public Enemy
{
public:
virtual ~EasyEnemy();
protected:
friend class EasyEnemyFactory;
EasyEnemy(){}
};
class HardEnemy : public Enemy
{
public:
virtual ~HardEnemy();
protected:
friend class HardEnemyFactory;
HardEnemy(){}
};
class Item
{
public:
virtual ~Item()=0;
protected:
Item(){}
};
class EasyItem : public Item
{
public:
virtual ~EasyItem();
protected:
friend class EasyEnemyFactory;
EasyItem(){}
};
class HardItem : public Item
{
public:
virtual ~HardItem();
protected:
friend class HardEnemyFactory;
HardItem(){}
};
class EnemyFactory
{
public:
virtual Enemy* CreateEnemy()=0;
virtual Item* CreateItem()=0;
};
class EasyEnemyFactory : public EnemyFactory
{
public:
virtual EasyEnemy* CreateEnemy();
virtual EasyItem* CreateItem();
};
class HardEnemyFactory : public EnemyFactory
{
public:
virtual HardEnemy* CreateEnemy();
virtual HardItem* CreateItem();
};
#include "AbstractFactory.h"
Enemy::~Enemy()
{
}
EasyEnemy::~EasyEnemy()
{
}
HardEnemy::~HardEnemy()
{
}
Item::~Item()
{
}
EasyItem::~EasyItem()
{
}
HardItem::~HardItem()
{
}
EasyEnemy* EasyEnemyFactory::CreateEnemy()
{
return new EasyEnemy;
}
EasyItem* EasyEnemyFactory::CreateItem()
{
return new EasyItem;
}
HardEnemy* HardEnemyFactory::CreateEnemy()
{
return new HardEnemy;
}
HardItem* HardEnemyFactory::CreateItem()
{
return new HardItem;
}
Remark
Concrete Product has protected constructor so that we must declare a friend class of the corresponding Concrete Factory. Like this, a system can control all the birth of Concrete Product. Also you can use public constructor and need not a friend class, and you will lose some of the manipulation of object creation.
Whether abstract product is abstract class is decided by whether the abstract product can be instantiated.
Whether abstract factory only provide an interface or has an implementation is decided by the specific application. Abstract factory can return Null pointer or return an abstract product, if it can be instantiated.