Dependency injection is a very important pattern when you want your code to be testable, and it is used all the time in big C++ projects.
Here is a simple example:
// Copyright 2019 Google LLC.
// SPDX-License-Identifier: Apache-2.0
class FooInterface {
public:
virtual void f() = 0;
virtual ~FooInterface() = default;
};
class Foo : public FooInterface {
public:
void f() override { /* Actual work */ }
};
class MockFoo : public FooInterface {
public:
void f() override { /* Mock code */ }
};
class Bar {
public:
Bar(std::unique_ptr<FooInterface>&& foo) : foo_(std::move(foo)) { }
void b() { foo_->f(); }
private:
std::unique_ptr<FooInterface> foo_;
};
// In production
void production() {
auto bar = std::make_unique<Bar>(std::make_unique<Foo>());
bar->b();
// ...
}
// In tests
void test() {
auto bar = std::make_unique<Bar>(std::make_unique<MockFoo>());
bar->b();
// ...
}
One doubt that I've always had is if compilers are able to devirtualize this kind of usage of virtual functions.
I know that in the general case it's impossible to know which derived class is being used, but in the example above the compiler knows which objects are being used in the production and the test functions, because they are being explicitly instantiated.
Can modern compilers optimize this special case and remove the virtual function calls given that they know which derived class is being instantiated at compile time?
If this specific example can't be devirtualized, is there any change that can be made to it so that the calls are devirtualized?
It depends on the compiler and the particular code you are dealing with. In my experience, you should not rely on it if you really care about avoiding virtual calls.
For instance, Clang/LLVM will devirtualize your example under -O2 if f() is noexcept:
class FooInterface {
public:
virtual void f() noexcept = 0;
virtual ~FooInterface() = default;
};
But other major compilers won't. Your mileage may vary.
I have a question regarding a design in C++.
As you see in the code below there is a design problem. I want to be able to have a TestClass which inherits from zero or more classes derived from ModeBase (ModeOne and ModeTwo in this example). If TestClass inherits from ModeOne, it would have the ability to use MethodeOne(), and it would be a requirement for TestClass to implement MethodOne() which is what I want.
class ModeBase
{
//--Methods--------------------------------------------------------------------
public:
virtual ~ModeBase() = default;
};
class ModeOne : private ModeBase
{
//--Methods--------------------------------------------------------------------
public:
virtual ~ModeOne() = default;
virtual void MethodOne() {}
};
class ModeTwo : private ModeBase
{
//--Methods--------------------------------------------------------------------
public:
virtual ~ModeTwo() = default;
virtual void MethodTwo() {}
};
class TestBase
{
//--Methods--------------------------------------------------------------------
public:
TestBase() : currentMode_( nullptr ) {}
virtual ~TestBase() = default;
template <class Mode, class T>
void ChangeMode()
{
if( std::is_base_of<Mode, T>::value )
{
// Class does inherit from Mode so we make sure the current mode
// has changed
currentMode_ = std::make_shared<Mode>();
}
else
{
// Class does not inherit from Mode so we don't do anything
}
}
template <class Mode>
bool CurrentMode()
{
if( std::dynamic_pointer_cast<Mode>(currentMode_) != nullptr )
{
return true;
}
return false;
}
//--Data members---------------------------------------------------------------
private:
std::shared_ptr<ModeBase> currentMode_;
};
class TestOne
: public TestBase
, private ModeOne
, private ModeTwo
{
//--Methods--------------------------------------------------------------------
~TestOne() = default;
void HeartbeatTick()
{
if( CurrentMode<ModeOne>() )
{
MethodOne();
}
else if( CurrentMode<ModeTwo>() )
{
MethodTwo();
}
}
virtual void MethodOne() {}
virtual void MethodTwo() {}
};
class SomeManager
{
~SomeManager() = default;
void ChangeAllMode()
{
for( auto it = vector_.begin(); it != vector_.end(); ++it )
{
// Here is the problem with this implementation. I need to know
// the type of the TestBase derived class (TestOne) to use it as
// a `ChangeMode` method template parameter.
//(*it)->ChangeMode<AIModeFollowLine, SOMETYPE>();
}
};
std::vector<std::shared_ptr<TestBase>> vector_;
};
I already know this is bad design since vector_ will be filled at runtime so I have no way of using ChangeMode like that. It appears that it would be a good solution to use multimethods, wouldn't it ? If so, what would the design look like ?
Multimethods (AKA multiple dispatch) deals with the issue of dispatching a call to a single function based on the runtime type of the parameters involved. This does not appear to be your issue (or have I misunderstood you?), as you have two different method names, implemented on two different types.
Your goal appears to be to select a method implementation based on a runtime type that you have injected into a class. It is not clear whether you are able to dictate the form which that injection takes but if you are then why do you not directly inject the implementation? Then you could use an implicit interface rather than an explicit one. In other words why not inject a functor-like object?
class TestBase
{
public:
typedef std::function<void ()> Ticker;
TestBase(Ticker hbTicker) : ticker{hbTicker} {}
void HeartbeatTick() {
ticker();
}
void setTicker(Ticker hbTicker){
ticker = hbTicker;
}
private:
Ticker ticker;
};
Seems like a lot less complicated to me if that meets your requirements.
If you really do need to implement multiple dispatch you will probably need to implement a visitor pattern on each of the parameters whose runtime type you need to determine. Not sure if that would work for multiple parameters though (I've not tried multiple parameters myself at least). Or you could use RTTI and a case statement or something like that.
I am just being stupid here !
I just have to use a different ChangeMode() method in order to know if TestBase and thus TestOne is of type ModeBase:
template<typename Mode>
bool
IsSame( TestBase* base )
{
return dynamic_cast<Mode*>(base) != nullptr;
};
template <class Mode>
void
ChangeMode()
{
if( isSame<Mode>(this) )
{
// Change the ticker method
}
else
{
}
}
I'm working with a simple object model in which objects can implement interfaces to provide optional functionality. At it's heart, an object has to implement a getInterface method which is given a (unique) interface ID. The method then returns a pointer to an interface - or null, in case the object doesn't implement the requested interface. Here's a code sketch to illustrate this:
struct Interface { };
struct FooInterface : public Interface { enum { Id = 1 }; virtual void doFoo() = 0; };
struct BarInterface : public Interface { enum { Id = 2 }; virtual void doBar() = 0; };
struct YoyoInterface : public Interface { enum { Id = 3 }; virtual void doYoyo() = 0; };
struct Object {
virtual Interface *getInterface( int id ) { return 0; }
};
To make things easier for clients who work in this framework, I'm using a little template which automatically generates the 'getInterface' implementation so that clients just have to implement the actual functions required by the interfaces. The idea is to derive a concrete type from Object as well as all the interfaces and then let getInterface just return pointers to this (casted to the right type). Here's the template and a demo usage:
struct NullType { };
template <class T, class U>
struct TypeList {
typedef T Head;
typedef U Tail;
};
template <class Base, class IfaceList>
class ObjectWithIface :
public ObjectWithIface<Base, typename IfaceList::Tail>,
public IfaceList::Head
{
public:
virtual Interface *getInterface( int id ) {
if ( id == IfaceList::Head::Id ) {
return static_cast<IfaceList::Head *>( this );
}
return ObjectWithIface<Base, IfaceList::Tail>::getInterface( id );
}
};
template <class Base>
class ObjectWithIface<Base, NullType> : public Base
{
public:
virtual Interface *getInterface( int id ) {
return Base::getInterface( id );
}
};
class MyObjectWithFooAndBar : public ObjectWithIface< Object, TypeList<FooInterface, TypeList<BarInterface, NullType> > >
{
public:
// We get the getInterface() implementation for free from ObjectWithIface
virtual void doFoo() { }
virtual void doBar() { }
};
This works quite well, but there are two problems which are ugly:
A blocker for me is that this doesn't work with MSVC6 (which has poor support for templates, but unfortunately I need to support it). MSVC6 yields a C1202 error when compiling this.
A whole range of classes (a linear hierarchy) is generated by the recursive ObjectWithIface template. This is not a problem for me per se, but unfortunately I can't just do a single switch statement to map an interface ID to a pointer in getInterface. Instead, each step in the hierarchy checks for a single interface and then forwards the request to the base class.
Does anybody have suggestions how to improve this situation? Either by fixing the above two problems with the ObjectWithIface template, or by suggesting alternatives which would make the Object/Interface framework easier to use.
dynamic_cast exists within the language to solve this exact problem.
Example usage:
class Interface {
virtual ~Interface() {}
}; // Must have at least one virtual function
class X : public Interface {};
class Y : public Interface {};
void func(Interface* ptr) {
if (Y* yptr = dynamic_cast<Y*>(ptr)) {
// Returns a valid Y* if ptr is a Y, null otherwise
}
if (X* xptr = dynamic_cast<X*>(ptr)) {
// same for X
}
}
dynamic_cast will also seamlessly handle things like multiple and virtual inheritance, which you may well struggle with.
Edit:
You could check COM's QueryInterface for this- they use a similar design with a compiler extension. I've never seen COM code implemented, only used the headers, but you could search for it.
What about something like that ?
struct Interface
{
virtual ~Interface() {}
virtual std::type_info const& type() = 0;
};
template <typename T>
class InterfaceImplementer : public virtual Interface
{
std::type_info const& type() { return typeid(T); }
};
struct FooInterface : InterfaceImplementer<FooInterface>
{
virtual void foo();
};
struct BarInterface : InterfaceImplementer<BarInterface>
{
virtual void bar();
};
struct InterfaceNotFound : std::exception {};
struct Object
{
void addInterface(Interface *i)
{
// Add error handling if interface exists
interfaces.insert(&i->type(), i);
}
template <typename I>
I* queryInterface()
{
typedef std::map<std::type_info const*, Interface*>::iterator Iter;
Iter i = interfaces.find(&typeid(I));
if (i == interfaces.end())
throw InterfaceNotFound();
else return static_cast<I*>(i->second);
}
private:
std::map<std::type_info const*, Interface*> interfaces;
};
You may want something more elaborate than type_info const* if you want to do this across dynamic libraries boundaries. Something like std::string and type_info::name() will work fine (albeit a little slow, but this kind of extreme dispatch will likely need something slow). You can also manufacture numeric IDs, but this is maybe harder to maintain.
Storing hashes of type_infos is another option:
template <typename T>
struct InterfaceImplementer<T>
{
std::string const& type(); // This returns a unique hash
static std::string hash(); // This memoizes a unique hash
};
and use FooInterface::hash() when you add the interface, and the virtual Interface::type() when you query.
I'm trying to replace simple enums with type classes.. that is, one class derived from a base for each type. So for example instead of:
enum E_BASE { EB_ALPHA, EB_BRAVO };
E_BASE message = someMessage();
switch (message)
{
case EB_ALPHA: applyAlpha();
case EB_BRAVO: applyBravo();
}
I want to do this:
Base* message = someMessage();
message->apply(this); // use polymorphism to determine what function to call.
I have seen many ways to do this which all seem less elegant even then the basic switch statement. Using dyanimc_cast, inheriting from a messageHandler class that needs to be updated every time a new message is added, using a container of function pointers, all seem to defeat the purpose of making code easier to maintain by replacing switches with polymorphism.
This is as close as I can get: (I use templates to avoid inheriting from an all-knowing handler interface)
class Base
{
public:
template<typename T> virtual void apply(T* sandbox) = 0;
};
class Alpha : public Base
{
public:
template<typename T> virtual void apply(T* sandbox)
{
sandbox->applyAlpha();
}
};
class Bravo : public Base
{
public:
template<typename T> virtual void apply(T* sandbox)
{
sandbox->applyBravo();
}
};
class Sandbox
{
public:
void run()
{
Base* alpha = new Alpha;
Base* bravo = new Bravo;
alpha->apply(this);
bravo->apply(this);
delete alpha;
delete bravo;
}
void applyAlpha() {
// cout << "Applying alpha\n";
}
void applyBravo() {
// cout << "Applying bravo\n";
}
};
Obviously, this doesn't compile but I'm hoping it gets my problem accross.
Well, after giving in to dynamic_cast and multiple inheritance, I came up with this thanks to Anthony Williams and jogear.net
class HandlerBase
{
public:
virtual ~HandlerBase() {}
};
template<typename T> class Handler : public virtual HandlerBase
{
public:
virtual void process(const T&)=0;
};
class MessageBase
{
public:
virtual void dispatch(HandlerBase* handler) = 0;
template<typename MessageType>
void dynamicDispatch(HandlerBase* handler, MessageType* self)
{
dynamic_cast<Handler<MessageType>&>(*handler).process(*self);
}
};
template<typename MessageType> class Message : public MessageBase
{
virtual void dispatch(HandlerBase* handler)
{
dynamicDispatch(handler, static_cast<MessageType*>(this));
}
};
class AlphaMessage : public Message<AlphaMessage>
{
};
class BravoMessage : public Message<BravoMessage>
{
};
class Sandbox : public Handler<AlphaMessage>, public Handler<BravoMessage>
{
public:
void run()
{
MessageBase* alpha = new AlphaMessage;
MessageBase* bravo = new BravoMessage;
alpha->dispatch(this);
bravo->dispatch(this);
delete alpha;
delete bravo;
}
virtual void process(const AlphaMessage&) {
// cout << "Applying alpha\n";
}
virtual void process(const BravoMessage&) {
// cout << "Applying bravo\n";
}
};
int main()
{
Sandbox().run();
return 0;
}
It looks like you are trying to find some sort of double-dispatch system. Look into the Visitor pattern or other multiple-dispatch systems.
Your Bravo and Alpha classes are actually closures... Too bad C++ does not support them directly.
You could use a member pointer to do this:
typedef void (Sandbox::*SandboxMethod)();
struct BrAlpha {
BrAlpha(SandboxMethod method) : method(method){}
void apply(Sandbox sb){sb->*method();}
};
BrAlpha alpha(&Sandbox::applyAlpha);
BrAlpha bravo(&Sandbox::applyBravo);
(syntax may not be exact, but you know hat I mean)
I don't necessarily have an answer for your design pattern issue (though Modern C++ Design has a lot to say about it), but I do want to address your switch vs inheritance comment.
The problem with that simple swtich statement is maintainability. If that switch statement were in 1 location, then it's probably about the same amount of typing to create classes and inherit, but that switch statement is still a ticking time-bomb awaiting yet another state added without adding a case for it. If you assert the default:, you'll catch it at run time - eventually, but that's very poor. If you setup a bunch of function pointers and compile time assert on the table's size, you're doing better, but that's another level deeper than the switch statement. And this all goes out the window as soon as you have a second place in the code that needs to check state.
It's just that much easier once you have your interface class setup to let the compiler handle all the junk code of switching on states internally. You add the class need not worry about any other code as long as you follow the interface.
In my application, there are 10-20 classes that are instantiated once[*]. Here's an example:
class SomeOtherManager;
class SomeManagerClass {
public:
SomeManagerClass(SomeOtherManager*);
virtual void someMethod1();
virtual void someMethod2();
};
Instances of the classes are contained in one object:
class TheManager {
public:
virtual SomeManagerClass* someManagerClass() const;
virtual SomeOtherManager* someOtherManager() const;
/** More objects... up to 10-20 */
};
Currently TheManager uses the new operator in order to create objects.
My intention is to be able to replace, using plugins, the SomeManagerClass (or any other class) implementation with another one. In order to replace the implementation, 2 steps are needed:
Define a class DerivedSomeManagerClass, which inherits SomeManagerClass [plugin]
Create the new class (DerivedSomeManagerClass) instead of the default (SomeManagerClass) [application]
I guess I need some kind of object factory, but it should be fairly simple since there's always only one type to create (the default implementation or the user implementation).
Any idea about how to design a simple factory like I just described? Consider the fact that there might be more classes in the future, so it should be easy to extend.
[*] I don't care if it happens more than once.
Edit: Please note that there are more than two objects that are contained in TheManager.
Assuming a class (plugin1) which inherits from SomeManagerClass, you need a class hierarchy to build your types:
class factory
{
public:
virtual SomeManagerClass* create() = 0;
};
class plugin1_factory : public factory
{
public:
SomeManagerClass* create() { return new plugin1(); }
};
Then you can assign those factories to a std::map, where they are bound to strings
std::map<string, factory*> factory_map;
...
factory_map["plugin1"] = new plugin1_factory();
Finally your TheManager just needs to know the name of the plugin (as string) and can return an object of type SomeManagerClass with just one line of code:
SomeManagerClass* obj = factory_map[plugin_name]->create();
EDIT: If you don't like to have one plugin factory class for each plugin, you could modify the previous pattern with this:
template <class plugin_type>
class plugin_factory : public factory
{
public:
SomeManagerClass* create() { return new plugin_type(); }
};
factory_map["plugin1"] = new plugin_factory<plugin1>();
I think this is a much better solution. Moreover the 'plugin_factory' class could add itself to the 'factory_map' if you pass costructor the string.
I think there are two separate problems here.
One problem is: how does TheManager name the class that it has to create? It must keep some kind of pointer to "a way to create the class". Possible solutions are:
keeping a separate pointer for each kind of class, with a way to set it, but you already said that you don't like this as it violates the DRY principle
keeping some sort of table where the key is an enum or a string; in this case the setter is a single function with parameters (of course if the key is an enum you can use a vector instead of a map)
The other problem is: what is this "way to create a class"? Unfortunately we can't store pointers to constructors directly, but we can:
create, as others have pointed out, a factory for each class
just add a static "create" function for each class; if they keep a consistent signature, you can just use their pointers to functions
Templates can help in avoiding unnecessary code duplication in both cases.
I have answered in another SO question about C++ factories. Please see there if a flexible factory is of interest. I try to describe an old way from ET++ to use macros which has worked great for me.
ET++ was a project to port old MacApp to C++ and X11. In the effort of it Eric Gamma etc started to think about Design Patterns
I'd create a "base" factory that has virtual methods for creation of all the basic managers, and let the "meta manager" (TheManager in your question) take a pointer to the base factory as a constructor parameter.
I'm assuming that the "factory" can customize the instances of CXYZWManager by deriving from them, but alternatively the constructor of CXYZWManager could take different arguments in the "custom" factory.
A lengthy code example that outputs "CSomeManager" and "CDerivedFromSomeManager":
#include <iostream>
//--------------------------------------------------------------------------------
class CSomeManager
{
public:
virtual const char * ShoutOut() { return "CSomeManager";}
};
//--------------------------------------------------------------------------------
class COtherManager
{
};
//--------------------------------------------------------------------------------
class TheManagerFactory
{
public:
// Non-static, non-const to allow polymorphism-abuse
virtual CSomeManager *CreateSomeManager() { return new CSomeManager(); }
virtual COtherManager *CreateOtherManager() { return new COtherManager(); }
};
//--------------------------------------------------------------------------------
class CDerivedFromSomeManager : public CSomeManager
{
public:
virtual const char * ShoutOut() { return "CDerivedFromSomeManager";}
};
//--------------------------------------------------------------------------------
class TheCustomManagerFactory : public TheManagerFactory
{
public:
virtual CDerivedFromSomeManager *CreateSomeManager() { return new CDerivedFromSomeManager(); }
};
//--------------------------------------------------------------------------------
class CMetaManager
{
public:
CMetaManager(TheManagerFactory *ip_factory)
: mp_some_manager(ip_factory->CreateSomeManager()),
mp_other_manager(ip_factory->CreateOtherManager())
{}
CSomeManager *GetSomeManager() { return mp_some_manager; }
COtherManager *GetOtherManager() { return mp_other_manager; }
private:
CSomeManager *mp_some_manager;
COtherManager *mp_other_manager;
};
//--------------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
TheManagerFactory standard_factory;
TheCustomManagerFactory custom_factory;
CMetaManager meta_manager_1(&standard_factory);
CMetaManager meta_manager_2(&custom_factory);
std::cout << meta_manager_1.GetSomeManager()->ShoutOut() << "\n";
std::cout << meta_manager_2.GetSomeManager()->ShoutOut() << "\n";
return 0;
}
Here's the solution I thought of, it's not the best one but maybe it will help to think of better solutions:
For each class there would be a creator class:
class SomeManagerClassCreator {
public:
virtual SomeManagerClass* create(SomeOtherManager* someOtherManager) {
return new SomeManagerClass(someOtherManager);
}
};
Then, the creators will be gathered in one class:
class SomeManagerClassCreator;
class SomeOtherManagerCreator;
class TheCreator {
public:
void setSomeManagerClassCreator(SomeManagerClassCreator*);
SomeManagerClassCreator* someManagerClassCreator() const;
void setSomeOtherManagerCreator(SomeOtherManagerCreator*);
SomeOtherManagerCreator* someOtherManagerCreator() const;
private:
SomeManagerClassCreator* m_someManagerClassCreator;
SomeOtherManagerCreator* m_someOtherManagerCreator;
};
And TheManager will be created with TheCreator for internal creation:
class TheManager {
public:
TheManager(TheCreator*);
/* Rest of code from above */
};
The problem with this solution is that it violates DRY - for each class creator I would have to write setter/getter in TheCreator.
This seems like it would be a lot simpler with function templating as opposed to an Abstract Factory pattern
class ManagerFactory
{
public:
template <typename T> static BaseManager * getManager() { return new T();}
};
BaseManager * manager1 = ManagerFactory::template getManager<DerivedManager1>();
If you want to get them via a string, you can create a standard map from strings to function pointers. Here is an implementation that works:
#include <map>
#include <string>
class BaseManager
{
public:
virtual void doSomething() = 0;
};
class DerivedManager1 : public BaseManager
{
public:
virtual void doSomething() {};
};
class DerivedManager2 : public BaseManager
{
public:
virtual void doSomething() {};
};
class ManagerFactory
{
public:
typedef BaseManager * (*GetFunction)();
typedef std::map<std::wstring, GetFunction> ManagerFunctionMap;
private:
static ManagerFunctionMap _managers;
public:
template <typename T> static BaseManager * getManager() { return new T();}
template <typename T> static void registerManager(const std::wstring& name)
{
_managers[name] = ManagerFactory::template getManager<T>;
}
static BaseManager * getManagerByName(const std::wstring& name)
{
if(_managers.count(name))
{
return _managers[name]();
}
return NULL;
}
};
// the static map needs to be initialized outside the class
ManagerFactory::ManagerFunctionMap ManagerFactory::_managers;
int _tmain(int argc, _TCHAR* argv[])
{
// you can get with the templated function
BaseManager * manager1 = ManagerFactory::template getManager<DerivedManager1>();
manager1->doSomething();
// or by registering with a string
ManagerFactory::template registerManager<DerivedManager1>(L"Derived1");
ManagerFactory::template registerManager<DerivedManager2>(L"Derived2");
// and getting them
BaseManager * manager2 = ManagerFactory::getManagerByName(L"Derived2");
manager2->doSomething();
BaseManager * manager3 = ManagerFactory::getManagerByName(L"Derived1");
manager3->doSomething();
return 0;
}
EDIT: In reading the other answers I realized that this is very similar to Dave Van den Eynde's FactorySystem solution, but I'm using a function template pointer instead of instantiating templated factory classes. I think my solution is a little more lightweight. Due to static functions, the only object that gets instantiated is the map itself. If you need the factory to perform other functions (DestroyManager, etc.), I think his solution is more extensible.
You could implement an object factory with static methods that return an instance of a Manager-Class. In the factory you could create a method for the default type of manager and a method for any type of manager which you give an argument representing the type of the Manager-Class (say with an enum). This last method should return an Interface rather than a Class.
Edit: I'll try to give some code, but mind that my C++ times are quite a while back and I'm doing only Java and some scripting for the time being.
class Manager { // aka Interface
public: virtual void someMethod() = 0;
};
class Manager1 : public Manager {
void someMethod() { return null; }
};
class Manager2 : public Manager {
void someMethod() { return null; }
};
enum ManagerTypes {
Manager1, Manager2
};
class ManagerFactory {
public static Manager* createManager(ManagerTypes type) {
Manager* result = null;
switch (type) {
case Manager1:
result = new Manager1();
break;
case Manager2:
result = new Manager2();
break;
default:
// Do whatever error logging you want
break;
}
return result;
}
};
Now you should be able to call the Factory via (if you've been able to make the code sample work):
Manager* manager = ManagerFactory.createManager(ManagerTypes.Manager1);
I would use templates like this as I can't see the point of factories classes:
class SomeOtherManager;
class SomeManagerClass {
public:
SomeManagerClass(SomeOtherManager*);
virtual void someMethod1();
virtual void someMethod2();
};
class TheBaseManager {
public:
//
};
template <class ManagerClassOne, class ManagerClassOther>
class SpecialManager : public TheBaseManager {
public:
virtual ManagerClassOne* someManagerClass() const;
virtual ManagerClassOther* someOtherManager() const;
};
TheBaseManager* ourManager = new SpecialManager<SomeManagerClass,SomeOtherManager>;
You should take a look at the tutorial at
http://downloads.sourceforge.net/papafactory/PapaFactory20080622.pdf?use_mirror=fastbull
It contains a great tutorial on implementing an Abstract factory in C++ and the source code that comes with it is also very robust
Chris
Mh I don't understand a hundred percent, and I am not really into factory stuff from books and articles.
If all your managers share a similar interface you could derive from a base class, and use this base class in your program.
Depending on where the decision which class will be created will be made, you have to use an identifier for creation (as stated above) or handle the decision which manager to instantiate internally.
Another way would be to implement it "policy" like by using templates. So that You ManagerClass::create() returns a specific SomeOtherManagerWhatever instance. This would lay the decision which manager to make in the code which uses your Manager - Maye this is not intended.
Or that way:
template<class MemoryManagment>
class MyAwesomeClass
{
MemoryManagment m_memoryManager;
};
(or something like that)
With this construct you can easily use other managers by only changing the instantiation of MyAwesomeClass.
Also A class for this purpose might be a little over the top. In your case a factory function would do I guess. Well it's more a question of personal preference.
If you plan on supporting plugins that are dynamically linked, your program will need to provide a stable ABI (Application Binary Interface), that means that you cannot use C++ as your main interface as C++ has no standard ABI.
If you want plugins to implement an interface you define yourself, you will have to provide the header file of the interface to plugin programmer and standardize on a very simple C interface in order to create and delete the object.
You cannot provide a dynamic library that will allow you to "new" the plugin class as-is. That is why you need to standardize on a C interface in order to create the object. Using the C++ object is then possible as long as none of your arguments use possibly incompatible types, like STL containers. You will not be able to use a vector returned by another library, because you cannot ensure that their STL implementation is the same as yours.
Manager.h
class Manager
{
public:
virtual void doSomething() = 0;
virtual int doSomethingElse() = 0;
}
extern "C" {
Manager* newManager();
void deleteManager(Manager*);
}
PluginManager.h
#include "Manager.h"
class PluginManager : public Manager
{
public:
PluginManager();
virtual ~PluginManager();
public:
virtual void doSomething();
virtual int doSomethingElse();
}
PluginManager.cpp
#include "PluginManager.h"
Manager* newManager()
{
return new PluginManager();
}
void deleteManager(Manager* pManager)
{
delete pManager;
}
PluginManager::PluginManager()
{
// ...
}
PluginManager::~PluginManager()
{
// ...
}
void PluginManager::doSomething()
{
// ...
}
int PluginManager::doSomethingElse()
{
// ...
}
You didnt talk about TheManager. It looks like you want that to control which class is being used? or maybe you trying to chain them together?
It sounds like you need a abstract base class and a pointer to the currently used class. If you wish to chain you can do it in both abstract class and themanager class. If abstract class, add a member to the next class in chain, if themanager then sort it in order you which to use in a list. You'll need a way to add classes so you'll need an addMe() in themanager. It sounds like you know what your doing so w/e you choose should be right. A list with an addMe func is my recommendation and if you want only 1 active class then a function in TheManager deciding it would be good.
This maybe heavier than you need, but it sounds like you are trying to make a frame work class that supports plugins.
I would break it up into to 3 sections.
1) The FrameWork class would own the plugins.
This class is responsable for publishing interfaces supplied by the plugins.
2) A PlugIn class would own the componets that do the work.
This class is responsable for registering the exported interfaces, and binding the imported interfaces to the components.
3) The third section, the componets are the suppliers and consumers of the interfaces.
To make things extensible, getting things up and running might be broke up into stages.
Create everything.
Wire everything up.
Start everything.
To break things down.
Stop everything.
Destroy everything.
class IFrameWork {
public:
virtual ~IFrameWork() {}
virtual void RegisterInterface( const char*, void* ) = 0;
virtual void* GetInterface( const char* name ) = 0;
};
class IPlugIn {
public:
virtual ~IPlugIn() {}
virtual void BindInterfaces( IFrameWork* frameWork ) {};
virtual void Start() {};
virtual void Stop() {};
};
struct SamplePlugin :public IPlugIn {
ILogger* logger;
Component1 component1;
WebServer webServer;
public:
SamplePlugin( IFrameWork* frameWork )
:logger( (ILogger*)frameWork->GetInterface( "ILogger" ) ), //assumes the 'System' plugin exposes this
component1(),
webServer( component1 )
{
logger->Log( "MyPlugin Ctor()" );
frameWork->RegisterInterface( "ICustomerManager", dynamic_cast( &component1 ) );
frameWork->RegisterInterface( "IVendorManager", dynamic_cast( &component1 ) );
frameWork->RegisterInterface( "IAccountingManager", dynamic_cast( &webServer ) );
}
virtual void BindInterfaces( IFrameWork* frameWork ) {
logger->Log( "MyPlugin BindInterfaces()" );
IProductManager* productManager( static_cast( frameWork->GetInterface( "IProductManager" ) ) );
IShippingManager* shippingManager( static_cast( frameWork->GetInterface( "IShippingManager" ) ) );
component1.BindInterfaces( logger, productManager );
webServer.BindInterfaces( logger, productManager, shippingManager );
}
virtual void Start() {
logger->Log( "MyPlugin Start()" );
webServer.Start();
}
virtual void Stop() {
logger->Log( "MyPlugin Stop()" );
webServer.Stop();
}
};
class FrameWork :public IFrameWork {
vector plugIns;
map interfaces;
public:
virtual void RegisterInterface( const char* name, void* itfc ) {
interfaces[ name ] = itfc;
}
virtual void* GetInterface( const char* name ) {
return interfaces[ name ];
}
FrameWork() {
//Only interfaces in 'SystemPlugin' can be used by all methods of the other plugins
plugIns.push_back( new SystemPlugin( this ) );
plugIns.push_back( new SamplePlugin( this ) );
//add other plugIns here
for_each( plugIns.begin(), plugIns.end(), bind2nd( mem_fun( &IPlugIn::BindInterfaces ), this ) );
for_each( plugIns.begin(), plugIns.end(), mem_fun( &IPlugIn::Start ) );
}
~FrameWork() {
for_each( plugIns.rbegin(), plugIns.rend(), mem_fun( &IPlugIn::Stop ) );
for_each( plugIns.rbegin(), plugIns.rend(), Delete() );
}
};
Here's a minimal factory pattern implementation that I came up with in about 15 minutes. We use a similar one that uses more advanced base classes.
#include "stdafx.h"
#include <map>
#include <string>
class BaseClass
{
public:
virtual ~BaseClass() { }
virtual void Test() = 0;
};
class DerivedClass1 : public BaseClass
{
public:
virtual void Test() { } // You can put a breakpoint here to test.
};
class DerivedClass2 : public BaseClass
{
public:
virtual void Test() { } // You can put a breakpoint here to test.
};
class IFactory
{
public:
virtual BaseClass* CreateNew() const = 0;
};
template <typename T>
class Factory : public IFactory
{
public:
T* CreateNew() const { return new T(); }
};
class FactorySystem
{
private:
typedef std::map<std::wstring, IFactory*> FactoryMap;
FactoryMap m_factories;
public:
~FactorySystem()
{
FactoryMap::const_iterator map_item = m_factories.begin();
for (; map_item != m_factories.end(); ++map_item) delete map_item->second;
m_factories.clear();
}
template <typename T>
void AddFactory(const std::wstring& name)
{
delete m_factories[name]; // Delete previous one, if it exists.
m_factories[name] = new Factory<T>();
}
BaseClass* CreateNew(const std::wstring& name) const
{
FactoryMap::const_iterator found = m_factories.find(name);
if (found != m_factories.end())
return found->second->CreateNew();
else
return NULL; // or throw an exception, depending on how you want to handle it.
}
};
int _tmain(int argc, _TCHAR* argv[])
{
FactorySystem system;
system.AddFactory<DerivedClass1>(L"derived1");
system.AddFactory<DerivedClass2>(L"derived2");
BaseClass* b1 = system.CreateNew(L"derived1");
b1->Test();
delete b1;
BaseClass* b2 = system.CreateNew(L"derived2");
b2->Test();
delete b2;
return 0;
}
Just copy & paste over an initial Win32 console app in VS2005/2008. I like to point out something:
You don't need to create a concrete factory for every class. A template will do that for you.
I like to place the entire factory pattern in its own class, so that you don't need to worry about creating factory objects and deleting them. You simply register your classes, a factory class gets created by the compiler and a factory object gets created by the pattern. At the end of its lifetime, all factories are cleanly destroyed. I like this form of encapsulation, as there is no confusion over who governs the lifetime of the factories.