I'm working on a library that defines a client interface for some service. Under the hood I have to validate the data provided by users and then pass it to "engine" process using Connection class from another library (note: the Connection class isn't known to the users of our library). One of my colleagues proposed using PIMPL:
class Client {
public:
Client();
void sendStuff(const Stuff &stuff) {_pimpl->sendStuff(stuff);}
Stuff getStuff(const StuffId &id) {return _pimpl->getStuff(id);}
private:
ClientImpl *_pimpl;
}
class ClientImpl { // not exported
public:
void sendStuff(const Stuff &stuff);
Stuff getStuff(const StuffId &id);
private:
Connection _connection;
}
However, I find it very hard to test - even if I link my tests to some mocked implementation of Connection, I don't have an easy access to it to set and validate expectations. Am I missing something, or the much cleaner and testable solution is using interface + factory:
class ClientInterface {
public:
void sendStuff(const Stuff &stuff) = 0;
Stuff getStuff(const StuffId &id) = 0;
}
class ClientImplementation : public ClientInterface { // not exported
public:
ClientImplementation(Connection *connection);
// +implementation of ClientInterface
}
class ClientFactory {
static ClientInterface *create();
}
Are there any reasons to go with PIMPL in this situation?
AFAIK the usual reason to use the Pimpl idiom is to reduce compile/link time dependencies to the implementation of the class (by removing the implementation details from the public header file altogether). Another reason may be to enable the class to change its behaviour dynamically (aka the State pattern).
The second does not seem to be the case here, and the first can be achieved with inheritance + a factory as well. However, as you noted, the latter solution is much easier to unit test, so I would prefer this.
GoTW15
GoTW28
From Herb Sutter. Good pointers to get you started.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With