C++链式编程fluent interface

引言

在查看OCCT项目源码的时候看到这种C++链式编程方法,查看维基百科正好有例子,于是作此记录。

见解

这种方法通过返回this 或者 self当前指针对象,使得代码以方法链的形式一直书写下去
形如:

const bool okImport =read().mode().transfer().dosomething().execute();

在C++中有个专业术语叫fluent interface ,属于API设计模式中的一种,这种方法其实在JavaScript中大量使用。实验表明,虽然多多少少给阅读代码带来不便性,使用起来倒是挺丝滑的。

历史:

术语 “fluent interface” 是在2005年末创造的,尽管这种接口的整体风格可以追溯到20世纪70年代Smalltalk中方法级联的发明,以及20世纪80年代的大量例子。 一个常见的例子是c++中的iostream库,它使用<<或>>操作符进行消息传递,向同一个对象发送多个数据,并允许对其他方法调用使用“操纵符”。 其他早期的例子包括Garnet系统(在Lisp中始于1988年)和Amulet系统(在c++中始于1994年),它们使用这种风格来创建对象和赋值属性。

例子:

===C++===

 // Basic definition
 class GlutApp {
 private:
     int w_, h_, x_, y_, argc_, display_mode_;
     char **argv_;
     char *title_;
 public:
     GlutApp(int argc, char** argv) {
         argc_ = argc;
         argv_ = argv;
     }
     void setDisplayMode(int mode) {
         display_mode_ = mode;
     }
     int getDisplayMode() {
         return display_mode_;
     }
     void setWindowSize(int w, int h) {
         w_ = w;
         h_ = h;
     }
     void setWindowPosition(int x, int y) {
         x_ = x;
         y_ = y;
     }
     void setTitle(const char *title) {
         title_ = title;
     }
     void create(){;}
 };
 // Basic usage
 int main(int argc, char **argv) {
     GlutApp app(argc, argv);
     app.setDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_ALPHA|GLUT_DEPTH); // Set framebuffer params
     app.setWindowSize(500, 500); // Set window params
     app.setWindowPosition(200, 200);
     app.setTitle("My OpenGL/GLUT App");
     app.create();
 }

 // Fluent wrapper
 class FluentGlutApp : private GlutApp {
 public:
     FluentGlutApp(int argc, char **argv) : GlutApp(argc, argv) {} // Inherit parent constructor
     FluentGlutApp &withDoubleBuffer() {
         setDisplayMode(getDisplayMode() | GLUT_DOUBLE);
         return *this;
     }
     FluentGlutApp &withRGBA() {
         setDisplayMode(getDisplayMode() | GLUT_RGBA);
         return *this;
     }
     FluentGlutApp &withAlpha() {
         setDisplayMode(getDisplayMode() | GLUT_ALPHA);
         return *this;
     }
     FluentGlutApp &withDepth() {
         setDisplayMode(getDisplayMode() | GLUT_DEPTH);
         return *this;
     }
     FluentGlutApp &across(int w, int h) {
         setWindowSize(w, h);
         return *this;
     }
     FluentGlutApp &at(int x, int y) {
         setWindowPosition(x, y);
         return *this;
     }
     FluentGlutApp &named(const char *title) {
         setTitle(title);
         return *this;
     }
     // It doesn't make sense to chain after create(), so don't return *this
     void create() {
         GlutApp::create();
     }
 };
 // Fluent usage
 int main(int argc, char **argv) {
     FluentGlutApp(argc, argv)
         .withDoubleBuffer().withRGBA().withAlpha().withDepth()
         .at(200, 200).across(500, 500)
         .named("My OpenGL/GLUT App")
         .create();
 }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HiramChen9

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值