假设你有一个抽象模板类IParser
,它有一个名为parse
的虚拟方法,该方法应该解析字符串并返回模板类型的对象。
您有另一个抽象类INetlinkAdapter
,它表示Netlink通信的适配器,它提供了一个虚拟方法来发送请求并使用IParser
解析其回复。
就像这样:
template<typename T>
struct IParser<T> {
std::shared_ptr<T> parse(std::string_view message) const;
};
struct INetlinkAdapter {
template<typename T>
virtual std::shared_ptr<T> sendRequestAndParseReply(int request, const IParser<T> & replyPparser);
};
这将是无效的,因为在c++中不可能有虚模板方法。
所以我在想,对于这个架构问题,哪一个解决方案既优雅又健壮。
在这种情况下,我做的第一件事就是忘记c++对象模型的存在。假设没有virtual
。
c++仍然是一个功能齐全的OO语言,没有它,你只需要用C的方式来做继承。
解析器只是一个从字节到对象实例的函数。(共享ptr需求是实现泄漏)。
网络链接适配器接受请求,生成字节,然后将其提供给解析器,解析器生成对象实例。
现在你应该看到我们正在做函数组合。
所以我们重写代码来知道这个
struct bytes; // some stream of bytes
template<class T>
using parser=std::function<std::shared_ptr<T>(bytes)>;
struct request;
using ByteProvider=std::function<bytes(request)>;
tenplate<class T>
using DataProvider=std::function<std::shared_ptr<T>(request)>;
template<class T>
DataProvider<T> GetDataProvider(ByteProvider b, Parser<T> p){
return [=](request r)){
return p(b(r));
};
}
我们可以重写这种OO风格,方法是在接口中使用一个模板方法来完成从字节到解析器的转换,而使用纯虚方法来完成字节转换。