Я работаю над библиотекой, которая определяет клиентский интерфейс для некоторой службы. Под капотом я должен проверить данные, предоставленные пользователями, а затем передать их процессу «движка», используя класс Connection из другой библиотеки (примечание: класс Connection не известен пользователям нашей библиотеки). Один из моих коллег предложил использовать 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;
}
Однако мне очень сложно тестировать - даже если я свяжу свои тесты с какой-то имитацией реализации Connection, у меня не будет легкого доступа к нему, чтобы установить и проверить ожидания. Мне что-то не хватает, или гораздо более чистое и тестируемое решение использует интерфейс + 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();
}
Есть ли какие-то причины использовать PIMPL в такой ситуации?
Connection
(а неConnection*
), вы должны включить его определение в свой заголовок, чтобыConnection
был известен пользователям вашей библиотеки. - person ereOn   schedule 07.07.2010Connection
была частной структурой. - person ereOn   schedule 07.07.2010