什么是流利语法Fluent Syntax

2024-05-03 21:38
文章标签 语法 fluent 流利 syntax

本文主要是介绍什么是流利语法Fluent Syntax,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!



出处:http://blog.csdn.net/u010019717

author:孙广东      时间:2015.3.18   23:00


编程新概念:什么是流利语法fluent syntax
首先感谢 unity的一款插件 DFTween (内容如下http://blog.csdn.net/u010019717/article/details/44359119),通过学习它知道了流利语法的概念。

Fluent interface连贯接口

在软件工程,一种Fluent interface连贯接口(作为首先由Eric EvansMartinFowler创造)是面向对象的API,旨在提供更具可读性的代码执行。

        Fluent interface通常通过使用methodcascading方法级联(具体methodchaining方法链接)context指令连续调用执行 (但Fluent interface需要不仅仅是方法链接)。通常context上下文是

·定义通过返回值(类对象)调用方法

·以自我作为参照,在新的背景下是相当于最后一个context上下文

·通过返回一个void的上下文终止。

内容

1 History

2 Examples

2.1 JavaScript

2.2 Java

2.3 C++

2.7 PHP

2.8 C#

2.9 Python

历史

术语"Fluent interface"是在 2005 年年底提出,虽然这种interface面的整体风格追溯到 1970 年代,Smalltalk 在级联的方法被发明,在上世纪 80 年代的许多例子。最熟悉的是在 c + +,使用iostream<<>> 运算符为消息传递、将多个数据发送到同一个对象和其他方法调用允许"manipulators"

 例子

JavaScript

有很多使用几种变体的 JS 库的例子:可能是最广为人知的 jQuery。通常用fluent builders流利的建设者来实现 'DB 查询',例如https://github.com/Medium/dynamite :

// getting an item from a tableclient.getItem('user-table').setHashKey('userId', 'userA').setRangeKey('column', '@').execute().then(function(data) {// data.result: the resulting object})

简单的办法做到这一点在 javascript 中使用prototype inheritance原型继承和 this

// example from http://schier.co/post/method-chaining-in-javascript// define the classvar Kitten = function() {this.name = 'Garfield';this.color = 'brown';this.gender = 'male';};Kitten.prototype.setName = function(name) {this.name = name;return this;};Kitten.prototype.setColor = function(color) {this.color = color;return this;};Kitten.prototype.setGender = function(gender) {this.gender = gender;return this;};Kitten.prototype.save = function() {console.log('saving ' + this.name + ', the ' +this.color + ' ' + this.gender + ' kitten...');// save to database here...return this;};// use itnew Kitten().setName('Bob').setColor('black').setGender('male').save();

更通用的方式做到这一点是在mu-ffsm中实现.

var mkChained = function(spec) {return function(init) {var s = spec[0] ? spec[0](init) : 0;var i = function(opt) {return spec[1] ? spec[1](s, opt) : s;}Object.keys(spec).forEach(function(name){// skip `entry` and `exit` functionsif(/^\d+$/.test(name))return;// transition 'name : (s, opt) -> s'i[name] = function(opt) {s = spec[name](s, opt);return i;};});return i;}};var API = mkChained({0:    function(opt)    {return ;/* create initial state */},then: function(s, opt) {return s; /* new state */},whut: function(s, opt) {return s; /* new state */},1:    function(s, opt) {return ;/* compute final value */}});// We create an instance of our newly crafted API,var call = API() // entry.whut()       // transition.then()       // transition.whut();      // transition// And call itvar result0 = call() // exit, result1 = call() // exit
 

Java

JOOQ型号的库作为 fluent API Java 中的 SQL

Author a = AUTHOR.as("a");create.selectFrom(a).where(exists(selectOne().from(BOOK).where(BOOK.STATUS.eq(BOOK_STATUS.SOLD_OUT)).and(BOOK.AUTHOR_ID.eq(a.ID))));

Op4j库使fluent流畅代码,用于执行辅助任务结构迭代、 数据转换、 过滤等。

String[] datesStr = new String[] {"12-10-1492", "06-12-1978"};...List<Calendar> dates = Op.on(datesStr).toList().map(FnString.toCalendar("dd-MM-yyyy")).get();

Fluflu注释处理器可以使用 Java 注释 fluent API创建。

JaQue使 Java 8 lambda 时必须表示为表达式目录树在运行时,使它能够即创建类型安全连贯接口,而不是窗体中的对象:

Customer obj = ... obj.property("name").eq("John")一种学法:method<Customer>(customer -> customer.getName() == "John")

C + +

C + +中,一个fluentinterface常见用途是的标准iostream,其中链重载的运算符.

以下是提供在更传统的界面,在 c + + 中的fluent interface包装程序的示例:

 

// Basic definitionclass 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 usageint main(int argc, char **argv) {GlutApp app(argc, argv);app.setDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_ALPHA|GLUT_DEPTH); // Set framebuffer paramsapp.setWindowSize(500, 500); // Set window paramsapp.setWindowPosition(200, 200);app.setTitle("My OpenGL/GLUT App");app.create();}// Fluent wrapperclass FluentGlutApp : private GlutApp {public:FluentGlutApp(int argc, char **argv) : GlutApp(argc, argv) {} // Inherit parent constructorFluentGlutApp &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 *thisvoid create() {GlutApp::create();}};// Fluent usageint main(int argc, char **argv) {FluentGlutApp(argc, argv).withDoubleBuffer().withRGBA().withAlpha().withDepth().at(200, 200).across(500, 500).named("My OpenGL/GLUT App").create();}

PHP

PHP 中,一个人可以通过使用$this 特殊的变量所表示的实例返回当前对象。因此返回 $this ;将使返回的实例的方法。下面的示例定义一个类Employee和三种方法来设置其name, surname salary。每个返回Employee类允许对链方法的实例。

<?phpclass Employee{public $name;public $surName; public $salary;public function setName($name){$this->name = $name;return $this;}public function setSurname($surname){$this->surName = $surname;return $this;}public function setSalary($salary){$this->salary = $salary;return $this;}public function __toString(){$employeeInfo = 'Name: ' . $this->name . PHP_EOL;$employeeInfo .= 'Surname: ' . $this->surName . PHP_EOL;$employeeInfo .= 'Salary: ' . $this->salary . PHP_EOL;return $employeeInfo;}}# Create a new instance of the Employee class:$employee = new Employee();# Employee Tom Smith has a salary of 100:echo $employee->setName('Tom')->setSurname('Smith')->setSalary('100');# Display:# Name: Tom# Surname: Smith# Salary: 100

 

C#

C# 使用fluentLINQ中广泛编程来生成使用标准查询运算符的查询。基于扩展方法.

var translations = new Dictionary<string, string>{{"cat", "chat"},{"dog", "chien"},{"fish", "poisson"},{"bird", "oiseau"}};// Find translations for English words containing the letter "a",// sorted by length and displayed in uppercaseIEnumerable<string> query = translations.Where   (t => t.Key.Contains("a")).OrderBy (t => t.Value.Length).Select  (t => t.Value.ToUpper());// The same query constructed progressively:var filtered   = translations.Where (t => t.Key.Contains("a"));var sorted     = filtered.OrderBy   (t => t.Value.Length);var finalQuery = sorted.Select      (t => t.Value.ToUpper());Fluent interface也可以用于链设置方法,其中operates/shares相同的对象。而不是创建一个customer类我们可以创建一个data context数据上下文,可以用fluent interface,如下所示://defines the data contextclass Context{public string fname { get; set; }public string lname {get; set;}public string sex { get; set; }public string address { get; set; }}//defines the customer classclass Customer{Context context = new Context(); //initializes the context// set the value for propertiespublic Customer FirstName(string firstName){context.fname = firstName;return this;}public Customer LastName(string lastName){context.lname = lastName;return this;}public Customer Sex(string sex){context.sex = sex;return this;}public Customer Address(string address){context.address = address;return this;}//prints the data to consolepublic void Print(){Console.WriteLine("first name: {0} \nlast name: {1} \nsex: {2} \naddress: {3}",context.fname,context.lname,context.sex,context.address);}}class Program{static void Main(string[] args){//object creationCustomer c1 = new Customer();//using the method chaining to assign & print data with a single linec1.FirstName("vinod").LastName("srivastav").Sex("male").Address("bangalore").Print();}}

Python

Python 返回 'self' 中的实例方法是实现fluent pattern的一种方法。

class Poem(object):def __init__(self, content):self.content = contentdef indent(self, spaces):self.content = " " * spaces + self.contentreturn selfdef suffix(self, content):self.content = self.content + " - " + contentreturn selfPoem("Road Not Travelled").indent(4).suffix("Robert Frost").content'    Road Not Travelled - Robert Frost'

更详细的内容观看维基百科:https://en.wikipedia.org/wiki/Fluent_interface



这篇关于什么是流利语法Fluent Syntax的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/957699

相关文章

mysql递归查询语法WITH RECURSIVE的使用

《mysql递归查询语法WITHRECURSIVE的使用》本文主要介绍了mysql递归查询语法WITHRECURSIVE的使用,WITHRECURSIVE用于执行递归查询,特别适合处理层级结构或递归... 目录基本语法结构:关键部分解析:递归查询的工作流程:示例:员工与经理的层级关系解释:示例:树形结构的数

Java使用Stream流的Lambda语法进行List转Map的操作方式

《Java使用Stream流的Lambda语法进行List转Map的操作方式》:本文主要介绍Java使用Stream流的Lambda语法进行List转Map的操作方式,具有很好的参考价值,希望对大... 目录背景Stream流的Lambda语法应用实例1、定义要操作的UserDto2、ListChina编程转成M

Python正则表达式语法及re模块中的常用函数详解

《Python正则表达式语法及re模块中的常用函数详解》这篇文章主要给大家介绍了关于Python正则表达式语法及re模块中常用函数的相关资料,正则表达式是一种强大的字符串处理工具,可以用于匹配、切分、... 目录概念、作用和步骤语法re模块中的常用函数总结 概念、作用和步骤概念: 本身也是一个字符串,其中

Mysql用户授权(GRANT)语法及示例解读

《Mysql用户授权(GRANT)语法及示例解读》:本文主要介绍Mysql用户授权(GRANT)语法及示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql用户授权(GRANT)语法授予用户权限语法GRANT语句中的<权限类型>的使用WITH GRANT

HTML5表格语法格式详解

《HTML5表格语法格式详解》在HTML语法中,表格主要通过table、tr和td3个标签构成,本文通过实例代码讲解HTML5表格语法格式,感兴趣的朋友一起看看吧... 目录一、表格1.表格语法格式2.表格属性 3.例子二、不规则表格1.跨行2.跨列3.例子一、表格在html语法中,表格主要通过< tab

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Python基础语法中defaultdict的使用小结

《Python基础语法中defaultdict的使用小结》Python的defaultdict是collections模块中提供的一种特殊的字典类型,它与普通的字典(dict)有着相似的功能,本文主要... 目录示例1示例2python的defaultdict是collections模块中提供的一种特殊的字

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

C++语法知识点合集:11.模板

文章目录 一、非类型模板参数1.非类型模板参数的基本形式2.指针作为非类型模板参数3.引用作为非类型模板参数4.非类型模板参数的限制和陷阱:5.几个问题 二、模板的特化1.概念2.函数模板特化3.类模板特化(1)全特化(2)偏特化(3)类模板特化应用示例 三、模板分离编译1.概念2.模板的分离编译 模版总结 一、非类型模板参数 模板参数分类类型形参与非类型形参 非类型模板