Factory method pattern & data abstraction in C++ - c++

I try to implement the Factory Method Pattern in C++ while keeping a good level of abstraction. In the sample provided in the link, all derived classes are in the same file, but this is usually not the case.
Without header files for derived classes:
To keep implementation details, I didn't provide a header file for the derived class (declaration & definition in the source file), then I don't see how to implement the factory method because the derived classes are not visible and forward declaration is not possible.
With header files for derived classes:
I can implement the factory method, but the implementation details of derived classes leak because the private members and methods have to be declared in the header.
Maybe using the PImpl idom can help to solve the problem in case 2) but I wonder if this is correct/reasonable approach. What is the usual/best way to implement this pattern in C++ ?
Here is my code:
//graphic-api.hpp
class GraphicApi {
public:
enum class Type {
//OPENGL,
//DIRECTX,
VULKAN
};
virtual void render() = 0;
virtual ~GraphicApi() {};
static std::unique_ptr<GraphicApi> make(const Window& window, Type type);
};
//graphic-api.cpp
//need to include headers for derived classes
std::unique_ptr<GraphicApi> GraphicApi::make(const Window& window, GraphicApi::Type type) {
switch (type) {
case GraphicApi::Type::VULKAN:
return std::make_unique<VulkanApi>(window);
default:
assert(0 && "Unsupported Graphic API");
}
return nullptr;
}
//vulkan-api.hpp
class VulkanApi : public GraphicApi {
public:
VulkanApi(const Window& window);
virtual void render() {};
private:
// lot of private members & methods related to Vulkan API (not nice to see here)
vk::UniqueInstance instance;
...
};

Related

How to get rid of these static_casts?

I'm trying to create a C++ class hierarchy of UI "view" classes that wrap platform-specific UI classes. My classes use the pimpl idiom to hide the implementation from the header file. The Impl structs contain another pointer, to classes in the platform hierarchy.
(I used "PS" to abbreviate "platform specific".)
In the code below, I try to show a boiled down example of the base class (View), and one derived class (Button), along with the classes that they wrap. There is a static cast in the Button's implementation. All of the subclasses of View will have a lot of these casts. Is there way define the Impl struct so that the compiler understands the types better here, so I don't need to use the static casts?
// In .hh file
class View {
public:
virtual ~View() = default;
...
protected:
struct Impl;
Impl *impl;
View();
View(Impl *impl);
};
class Button: public View {
public:
Button();
void setText(const string &text);
};
// In .cc file
View::View() :impl(nullptr) {}
View::View(Impl *impl) :impl(impl) {}
struct View::Impl {
PSView *psView;
};
void View::doStuff() {
... impl->psView ... // fine, no cast needed here
}
Button::Button() {
PSButton *b = new PSButton();
impl = new Impl{b};
}
void Button::setText(const string &text) {
PSButton *myImpl = static_cast<PSButton*>(impl->psView);
myImpl->setTitle(text);
}
In my real code, it's a bit weirder, because the platform specific types are Apple's Objective-C classes. I'm putting that aside for now to try and clean up and simplify this question.

Design pattern: inheritance and encapsulated inheritance

I got problems formulating it precisely so I left more general description in the title (if you have more precise description of the problem, please comment, I'll edit the title).
The problem: Two classes AudioStream and VideoStream are derived from base class MediaStream which has some common for audio and video stream methods, but is not intended to be used as-is. Consequently, there are two classes AudioStreamSettings and VideoStreamSettings which are derived from MediaStreamSettings and passed to the constructors of their corresponding stream classes. MediaStreamSettings stores settings common for audio and video, and base class MediaStream accesses this data. The question is: what would be the best way to design this hierarchical relationship between base classes of streams and settings?
I can think of a quick solution like the following:
class MediaStream {
public:
MediaStream(const MediaStreamSettings& settings){
// do nothing, let derived classes initialize settings_
// note: I feel guilty for doing this...
}
virtual ~MediaStream(){}
protected:
std::shared_ptr<MediaStreamSettings> settings_;
};
class VideoStream : public MediaStream {
public:
VideoStream(const VideoStreamSettings& settings):
MediaStream(settings)
{
settings_ = std::make_shared<VideoStreamSettings>(settings);
}
void doSomething(){
int s1 = std::dynamic_pointer_cast<VideoStream, MediaStream>(settings_)->getVideoStreamSetting1();
...
}
};
class AudioStream : public MediaStream {
public:
AudioStream(const AudioStreamSettings& settings):
MediaStream(settings)
{
settings_ = std::make_shared<AudioStreamSettings>(settings);
}
}
To summarize I'm not comfortable with two things in this approach:
not initializing settings_ in base class (should I make it abstract to calm myself?)
using dynamic_pointer_cast every time I need to access settings in derived classes (should I make a method wrapper for this?)
One solution is to not store data in MediaStream and add a virtual method
virtual const MediaStreamSettings& GetMediaStreamSettings() const = 0;
Since MediaStream should not be used as-is, making it an abstract class should be acceptable (and desirable).
Thus providing implementation (which includes class members) is pointless.
class IMediaStream {
public:
virtual ~IMediaStream() {}
virtual void play() = 0;
virtual std::shared_ptr<MediaSettings> getSettings() = 0;
private:
IMediaStream() {}
};
template<Setting>
class MediaStream : public IMediaStream {
public:
MediaStream(const Setting& settings){
settings_ = std::make_shared<Setting>(settings);
}
virtual ~MediaStream() {}
virtual void play() override {
// Implementation here
}
virtual std::shared_ptr<MediaSettings> getSettings() override {
return std::dynamic_pointer_cast<Setting, MediaSettings>();
}
private:
std::shared_ptr<Setting> settings_;
}
// Alternatively you can inherit or specialize
// the template to add your implementation
typedef MediaStream<VideoStreamSettings> VideoStream;
typedef MediaStream<AudioStreamSettings> AudioStream;

Derive from class declared in private scope

I am currently refactoring some legacy code and would like to factorize a multiple if...elseif... statement into a series of classes implementing various strategies.
Since I have to access the original object's internals, I'm going to declare the new classes as nested classes; since nobody from the external world should access them, I'd prefer to declare them in private scope.
For the sake of exposing as few implementation details as possible, I was wondering whether it's possible to only forward-declare the base strategy class in the header file, and place all subclasses declaration in the implementation file. Code example as follows:
-- header file
class MyUglyClass
{
private:
class IStrategyBase;
IStrategyBase* sPtr;
// class ActualImplementation; // this is what I'd like to avoid
// class YetAnotherImplementation; // as above
// blah blah blah
};
-- implementation file
class MyUglyClass::IStrategyBase
{
virtual ResultType DoSomething(SomeType someParameter) = 0;
// could expose some MyUglyClass members, since
// derived classes wouldn't inherit friendship
};
class ActualImplementation: public MyUglyClass::IStrategyBase
{
ResultType DoSomething(SomeType someParameter) override
{
// Do actual work
}
}
class YetAnotherImplementation: public MyUglyClass::IStrategyBase
{
ResultType DoSomething(SomeType someParameter) override
{
// Doing something really tricky & clever for corner cases
}
}
Of course the compiler complains since IStrategyBase is not accessible; I could work around this by fwd-declaring ActualImplementation and YetAnotherImplementation into the header file together with IStrategyBase, but I'd rather avoid this, since I would need to change the header if a new strategy was needed.
I could also declare IStrategyBase in public scope, however I would prefer to keep it private to avoid other people messing with it.
Of course I'm assuming that non-fwd-declared subclasses wouldn't inherit friendship with MyUglyClass, so I would have to expose relevant data the IStrategyBase protected members.
Is there any way to achieve this I could be missing?
EDIT:
Thanks to all folks who commented, I realized that nobody could mess with IStrategyBase class even if declared in public scope, since class definition would be buried in the implementation file as well. What I'm wondering now is if I could make derived classes access internals of MyUglyClass without having to fwd declare them together with IStrategyBase. I guess answer is "no", since friendship is not inherited, but perhaps there is some more C++ perk I'm missing.
One possibility (this is not the pimpl idiom, just an accessibility hack):
class MyUglyClass
{
private:
struct Impl; // Is automatically "friend struct Impl;"
class IStrategyBase;
IStrategyBase* sPtr;
// class ActualImplementation; // this is what I'd like to avoid
// class YetAnotherImplementation; // as above
// blah blah blah
};
class MyUglyClass::IStrategyBase
{
public:
virtual int DoSomething(int someParameter) = 0;
// could expose some MyUglyClass members, since
// derived classes wouldn't inherit friendship
};
struct MyUglyClass::Impl
{
class ActualImplementation: public MyUglyClass::IStrategyBase
{
int DoSomething(int someParameter) override
{ (void) someParameter; return 1;}
};
class YetAnotherImplementation: public MyUglyClass::IStrategyBase
{
int DoSomething(int someParameter) override
{ (void) someParameter; return 2; }
};
};
int main() {}
If you want to conceal any imlementation details you can use pImpl idiom (pointer to implementation) aka Opaque pointer https://en.wikipedia.org/wiki/Opaque_pointer So you can change your code like this
-- header file
#include <memory>
class MyUglyClass
{
MyUglyClass();
~MyUglyClass(); // destructor must be only declared to avoid problems
// with deleting just forwarded inner class
private:
class Impl;
std::unique_ptr<Impl> pImpl;
};
-- implementation file
class MyUglyClass::Impl
{
class IStrategyBase;
IStrategyBase* sPtr;
class ActualImplementation; // now these classes safely hidden inside .cpp
class YetAnotherImplementation; // Nobody can reach them.
};
class MyUglyClass::Impl::IStrategyBase
{
virtual ResultType DoSomething(SomeType someParameter) = 0;
// could expose some MyUglyClass members, since
// derived classes wouldn't inherit friendship
};
class ActualImplementation: public MyUglyClass::Impl::IStrategyBase
{
ResultType DoSomething(SomeType someParameter) override
{
// Do actual work
}
};
class YetAnotherImplementation: public MyUglyClass::Impl::IStrategyBase
{
ResultType DoSomething(SomeType someParameter) override
{
// Doing something really tricky & clever for corner cases
}
};
MyUglyClass::MyUglyClass() : pImpl(new Impl()) {}
MyUglyClass::~MyUglyClass() {} // let the unique_ptr do its work

Factory pattern with private constructors in C++

I am trying to implement a factory pattern that consists of
a factory class
an abstract class with protected constructor
inherited classes with private constructors and virtual public
destructors.
I want to make sure that
No other one than the factory can not create any instance
If a new inherited class is defined it will not require any modification on interface class and already defined inherited classes. Juts new class implementation and adding into factory classes create method.
I also do not want to write same-like code(like static factory method per inited) for every inherited class and leave the future developers much work for factory connections.
i.e with pseduo code
class Factory;
class Interface
{
protected:
Interface(){/*Do something*/};
public:
virtual ~Interface(){/*Do something*/}
/*I wish I could do below and it is valid for all inherited
classes but friendship is not inherited in C++*/
//friend Interface* Factory::create(Type)
};
class InheritedA:public Interface
{
private:
InheritedA(){/*Do something*/};
public:
virtual ~InheritedA(){/*Do something*/}
/*I dont want to do below two lines for every inherited class*/
//friend Interface Factory::create(Type)
//public: Interface* factoryInheritedA(){return new InheritedA();}
};
class InheritedB:public Interface
{
private:
InheritedB(){/*Do something*/};
public:
virtual ~InheritedA(){/*Do something*/}
};
class Factory
{
static Interface* create(Interface type)
{
switch(type)
{
case A:
return new InheritedA();
case B:
return new InheritedB();
default:
//exceptions etc
}
}
}
int main()
{
Interface* I = Factory::create(A/*or B*/);
return 0;
}
Above code is the cloest I put out. Any suggestions (a speciality of C++, a different design,...) is welcome.
I don't think this a good idea, but here is a way to do this. You create a Tag type which can only be created by the Factory and make all the constructors take a parameter of that type.
class Factory;
class Tag
{
Tag() {}
friend Factory;
};
class Interface
{
public:
Interface(Tag t) {}
virtual ~Interface() {}
};
struct Impl1: public Interface
{
Impl1(Tag t): Interface(t) {}
};
class Factory
{
public:
Interface* makeInstance()
{
return new Impl1( Tag{} );
}
};
void foo()
{
Impl1 i( Tag{} );
}
You will get a compiler error in foo() because Tag::Tag is private.
You could have a templated function:
template<typename Type>
std::unique_ptr<Interface> make_interface() {
// exceptions etc..
}
template<>
std::unique_ptr<Interface> make_interface<InheritedA>() {
return std::make_unique<InheritedA>();
}
template<>
std::unique_ptr<Interface> make_interface<InheritedB>() {
return std::make_unique<InheritedB>();
}
but I really don't see the point in all of this Javaesque boilerplate. Not to mention that you are transforming a compile time information (the type) into a runtime one (via exceptions) for no reason really.
I would just go with:
std::unique_ptr<Interface> ptr_a = std::make_unique<InheritedA>();
std::unique_ptr<Interface> ptr_b = std::make_unique<InheritedB>();
when needed.
It is rarely a good practice to use Factory. I count it as an anti-pattern together with the Singleton. In good design, classess do not concern themselves on how they are created. In your case, when used in Factory, how do you create your class using custom allocator? On stack? In shared memory? In memory-mapped file? From the buffer? In place? This is all really hard to cover in Factory, but do not despair - the simple and elegant solution is ditch the factory!

Registering derived classes in C++

EDIT: minor fixes (virtual Print; return mpInstance) following remarks in the answers.
I am trying to create a system in which I can derive a Child class from any Base class, and its implementation should replace the implementation of the base class.
All the objects that create and use the base class objects shouldn't change the way they create or call an object, i.e. should continue calling BaseClass.Create() even when they actually create a Child class.
The Base classes know that they can be overridden, but they do not know the concrete classes that override them.
And I want the registration of all the the Child classes to be done just in one place.
Here is my implementation:
class CAbstractFactory
{
public:
virtual ~CAbstractFactory()=0;
};
template<typename Class>
class CRegisteredClassFactory: public CAbstractFactory
{
public:
~CRegisteredClassFactory(){};
Class* CreateAndGet()
{
pClass = new Class;
return pClass;
}
private:
Class* pClass;
};
// holds info about all the classes that were registered to be overridden
class CRegisteredClasses
{
public:
bool find(const string & sClassName);
CAbstractFactory* GetFactory(const string & sClassName)
{
return mRegisteredClasses[sClassName];
}
void RegisterClass(const string & sClassName, CAbstractFactory* pConcreteFactory);
private:
map<string, CAbstractFactory* > mRegisteredClasses;
};
// Here I hold the data about all the registered classes. I hold statically one object of this class.
// in this example I register a class CChildClass, which will override the implementation of CBaseClass,
// and a class CFooChildClass which will override CFooBaseClass
class RegistrationData
{
public:
void RegisterAll()
{
mRegisteredClasses.RegisterClass("CBaseClass", & mChildClassFactory);
mRegisteredClasses.RegisterClass("CFooBaseClass", & mFooChildClassFactory);
};
CRegisteredClasses* GetRegisteredClasses(){return &mRegisteredClasses;};
private:
CRegisteredClasses mRegisteredClasses;
CRegisteredClassFactory<CChildClass> mChildClassFactory;
CRegisteredClassFactory<CFooChildClass> mFooChildClassFactory;
};
static RegistrationData StaticRegistrationData;
// and here are the base class and the child class
// in the implementation of CBaseClass::Create I check, whether it should be overridden by another class.
class CBaseClass
{
public:
static CBaseClass* Create()
{
CRegisteredClasses* pRegisteredClasses = StaticRegistrationData.GetRegisteredClasses();
if (pRegisteredClasses->find("CBaseClass"))
{
CRegisteredClassFactory<CBaseClass>* pFac =
dynamic_cast<CRegisteredClassFactory<CBaseClass>* >(pRegisteredClasses->GetFactory("CBaseClass"));
mpInstance = pFac->CreateAndGet();
}
else
{
mpInstance = new CBaseClass;
}
return mpInstance;
}
virtual void Print(){cout << "Base" << endl;};
private:
static CBaseClass* mpInstance;
};
class CChildClass : public CBaseClass
{
public:
void Print(){cout << "Child" << endl;};
private:
};
Using this implementation, when I am doing this from some other class:
StaticRegistrationData.RegisterAll();
CBaseClass* b = CBaseClass::Create();
b.Print();
I expect to get "Child" in the output.
What do you think of this design? Did I complicate things too much and it can be done easier? And is it OK that I create a template that inherits from an abstract class?
I had to use dynamic_pointer (didn't compile otherwise) - is it a hint that something is wrong?
Thank you.
This sort of pattern is fairly common. I'm not a C++ expert but in Java you see this everywhere. The dynamic cast appears to be necessary because the compiler can't tell what kind of factory you've stored in the map. To my knowledge there isn't much you can do about that with the current design. It would help to know how these objects are meant to be used. Let me give you an example of how a similar task is accomplished in Java's database library (JDBC):
The system has a DriverManager which knows about JDBC drivers. The drivers have to be registered somehow (the details aren't important); once registered whenever you ask for a database connection you get a Connection object. Normally this object will be an OracleConnection or an MSSQLConnection or something similar, but the client code only sees "Connection". To get a Statement object you say connection.prepareStatement, which returns an object of type PreparedStatement; except that it's really an OraclePreparedStatement or MSSQLPreparedStatement. This is transparent to the client because the factory for Statements is in the Connection, and the factory for Connections is in the DriverManager.
If your classes are similarly related you may want to have a function that returns a specific type of class, much like DriverManager's getConnection method returns a Connection. No casting required.
The other approach you may want to consider is using a factory that has a factory-method for each specific class you need. Then you only need one factory-factory to get an instance of the Factory. Sample (sorry if this isn't proper C++):
class CClassFactory
{
public:
virtual CBaseClass* CreateBase() { return new CBaseClass(); }
virtual CFooBaseClass* CreateFoo() { return new CFooBaseClass();}
}
class CAImplClassFactory : public CClassFactory
{
public:
virtual CBaseClass* CreateBase() { return new CAImplBaseClass(); }
virtual CFooBaseClass* CreateFoo() { return new CAImplFooBaseClass();}
}
class CBImplClassFactory : public CClassFactory // only overrides one method
{
public:
virtual CBaseClass* CreateBase() { return new CBImplBaseClass(); }
}
As for the other comments criticizing the use of inheritance: in my opinion there is no difference between an interface and public inheritance; so go ahead and use classes instead of interfaces wherever it makes sense. Pure Interfaces may be more flexible in the long run but maybe not. Without more details about your class hierarchy it's impossible to say.
Usually, base class/ derived class pattern is used when you have an interface in base class, and that interface is implemented in derived class (IS-A relationship). In your case, the base class does not seem to have any connection with derived class - it may as well be void*.
If there is no connection between base class and derived class, why do you use inheritance? What is the benefit of having a factory if factory's output cannot be used in a general way? You have
class CAbstractFactory
{
public:
virtual ~CAbstractFactory()=0;
};
This is perfectly wrong. A factory has to manufacture something that can be used immediately:
class CAbstractFactory
{
public:
virtual ~CAbstractFactory(){};
public:
CBaseClass* CreateAndGet()
{
pClass = new Class;
return pClass;
}
private:
CBaseClass* pClass;
protected:
CBaseClass *create() = 0;
};
In general, you're mixing inheritance, virtual functions and templates the way they should not be mixed.
Without having read all of the code or gone into the details, it seems like you should've done the following:
make b of type CChildClass,
make CBaseClass::Print a virtual function.
Maybe I'm wrong but I didn't find any return statement in your CBaseClass::Create() method!
Personally, I think this design overuses inheritance.
"I am trying to create a system in which I can derive a Child class from any Base class, and its implementation should replace the implementation of the base class." - I don't know that IS-A relationships should be that flexible.
I wonder if you'd be better off using interfaces (pure virtual classes in C++) and mixin behavior. If I were writing it in Java I'd do this:
public interface Foo
{
void doSomething();
}
public class MixinDemo implements Foo
{
private Foo mixin;
public MixinDemo(Foo f)
{
this.mixin = f;
}
public void doSomething() { this.mixin.doSomething(); }
}
Now I can change the behavior as needed by changing the Foo implementation that I pass to the MixinDemo.