In C++ I often use RAII-style objects to make code more reliable and allocate them on stack to make code more performant (and to avoid bad_alloc).
But creating an object of concrete class on stack violates the dependency inversion (DI) principle and prevents mocking this object.
Consider the following code:
struct IInputStream
{
virtual vector<BYTE> read(size_t n) = 0;
};
class Connection : public IInputStream
{
public:
Connection(string address);
virtual vector<BYTE> read(size_t n) override;
};
struct IBar
{
virtual void process(IInputStream& stream) = 0;
};
void Some::foo(string address, IBar& bar)
{
onBeforeConnectionCreated();
{
Connection conn(address);
onConnectionCreated();
bar.process(conn);
}
onConnectionClosed();
}
I can test IBar::process
, but I also want to test Some::foo
, without creating real Connection object.
Surely I can use a factory, but it will significantly complicate code and introduce heap-allocation.
Also, I don't like to add the Connection::open
method, I prefer to construct completely initialized and fully functional objects.
I would make Connection
type a template parameter for Some
(or for foo
if extract it as a free function), but I'm not sure that it's right way (templates look like a black magic to many people, so I prefer to use dynamic polymorphism)