Похоже, что вы ищете, это фабрика, которая может возвращать различные уровни доступности API, в зависимости от потребностей вызывающего абонента. Один из способов сделать это - предоставить разные методы-конструкторы, которые возвращают указатели разных типов, как показано в приведенном ниже примере кода. Например, если вызывающему абоненту нужен IBird, он может позвонить createBird()
, но если ему на самом деле не нужно звонить Fly()
или любым другим вызовам IBird c, он может вместо этого позвонить createAnimal()
и получить вернуть IAnimal-указатель, а не IBird-указатель.
// Begin abstract interfaces
class IAnimal
{
public:
virtual void Eat() = 0;
};
class IBird : public IAnimal
{
public:
virtual void Fly() = 0;
};
class IFish : public IAnimal
{
public:
virtual void Swim() = 0;
};
class IAnimalFactory
{
public:
virtual IAnimal * createAnimal(const std::string & speciesName) = 0;
virtual IBird * createBird(const std::string & speciesName) = 0;
virtual IFish * createFish(const std::string & speciesName) = 0;
};
// Begin concrete classes that implement various levels of interface
class Snail : public IAnimal
{
public:
virtual void Eat() {printf("Snail eats!\n");}
}
class Sparrow : public IBird
{
public:
virtual void Eat() {printf("Sparrow eats!\n");}
virtual void Fly() {printf("Sparrow flies!\n");}
};
class Pigeon : public IBird
{
public:
virtual void Eat() {printf("Pigeon eats!\n");}
virtual void Fly() {printf("Pigeon flies!\n");}
};
class Tuna : public IFish
{
public:
virtual void Eat() {printf("Tuna eats!\n");}
virtual void Swim() {printf("Tuna swims!\n");}
};
class Marlin : public IFish
{
public:
virtual void Eat() {printf("Marlin eats!\n");}
virtual void Swim() {printf("Marlin swims!\n");}
};
class MyAnimalFactory : public IAnimalFactory
{
public:
virtual IAnimal * createAnimal(const std::string & speciesName)
{
if (speciesName == "snail") return new Snail;
else if (speciesName == "sparrow") return new Sparrow;
else if (speciesName == "pigeon") return new Pigeon;
else if (speciesName == "tuna") return new Tuna;
else if (speciesName == "marlin") return new Marlin;
else return NULL; // unknown animal type!
}
virtual IBird * createBird(const std::string & speciesName)
{
IAnimal * a = createAnimal(speciesName);
IBird * b = dynamic_cast<IBird *>(a);
if (b) return b;
else
{
// Oops, requested animal isn't an IBird! Caller can't use it
delete a;
return NULL;
}
}
virtual IFish * createFish(const std::string & speciesName)
{
IAnimal * a = createAnimal(speciesName);
IFish * f = dynamic_cast<IFish *>(a);
if (f) return f;
else
{
// Oops, requested animal isn't an IFish! Caller can't use it
delete f;
return NULL;
}
}
};