Apache thrift“TProtocol 类”设计原理——C++,为啥需要“writeBool()”

Posted

技术标签:

【中文标题】Apache thrift“TProtocol 类”设计原理——C++,为啥需要“writeBool()”【英文标题】:Apache thrift "TProtocol class" design principle - C++ ,why do we need "writeBool()"Apache thrift“TProtocol 类”设计原理——C++,为什么需要“writeBool()” 【发布时间】:2014-05-29 01:50:33 【问题描述】:

目前,我一直在阅读“Apache Thrift”的源码。具体来说,C++实现的代码放在这个路径下:“thrift-0.9.1.tar\thrift-0.9. 1\lib\cpp"。

我一直在想为什么“TProtocol 类”是这样设计的:

我们知道“TProtocol 类”是一个抽象类。而且这里有详细的分析: “developermemo”。并且说“还定义了相应的抽象工厂类,用于生产具体的协议对象,这是最常用的设计模式抽象工厂设计模式。”

不过,我想知道为什么他们定义一个函数对应的纯虚函数被调用。例如:

  virtual uint32_t writeSetEnd_virt() = 0;
  virtual uint32_t writeBool_virt(const bool value) = 0;  //Pure virtual function

  uint32_t writeBool(const bool value)                   //
  T_VIRTUAL_CALL(); 
  return writeBool_virt(value);                           //call the "interface"
  

为什么我们需要“writeBool()”。好像没什么用。 为什么不直接定义“纯虚函数”和“派生类”重写这些接口。

【问题讨论】:

【参考方案1】:

这是一种称为“模板方法”的模式。您经常拥有一个公共的、非虚拟的函数和一个私有的、虚拟的函数的组合。除了转发之外,公共的还做一些事情,比如检查前置条件和后置条件、日志记录和简单的转换。私人的、虚拟的做实际的工作。将其设为私有的理由是要明确表示您没有选择调用基本版本的选项,否则您可以通过显式的derived.base::foo() 调用来执行此操作。如果您需要扩展基本版本,您也可以改为将其设为受保护,但此处并非如此。

【讨论】:

【参考方案2】:

可以看出...writeBool 不仅仅是打电话给writeBool_virt。它执行T_VIRTUAL_CALL();,它在调试构建中跟踪执行。

仅使用虚函数是不可能创建这种行为的,因为您无法保证每个派生类都会正确调用T_VIRTUAL_CALL();

虚拟调用正在做尽可能少的工作(它们只是提供一个点来自定义TProtocol 的行为),并且不构成外部公共接口的一部分。这减少了组件之间的耦合,并使TProtocol的实现更加私密。

【讨论】:

以上是关于Apache thrift“TProtocol 类”设计原理——C++,为啥需要“writeBool()”的主要内容,如果未能解决你的问题,请参考以下文章

Apache thrift 和 cpp 代码生成

Apache Thrift 的使用

Apache Thrift系列详解- 概述与入门

Apache Avro 与 Thrift 比较

为啥我不能将 apache.thrift 导入 IntelliJ 项目?

Apache Thrift C++ typedef 问题