写点什么

扩展方法、DSL 和连贯接口

  • 2007-12-01
  • 本文字数:1108 字

    阅读完需:约 4 分钟

内在 DSL(Internal DSL)和 API 的区别是什么?Martin Fowler 在 2004 年 2 月这样描述内在 DSL

Lisp 和 Smalltalk 社区有使用 DSL 的深厚传统,但现在他们也倾向于走其他路线。他们现在不主张定义新语言,而是把通用语言变形成 DSL。(Paul Graham 在《Programming Bottom-Up》中也描述了这种方法。)内在 DSL(也被称为嵌入 DSL)使用编程语言本身就具备的概念作为材料来定义出 DSL。这是一种在任何语言都可行的常用方式,我一直在考虑把定义函数当作是在为手中的问题提供一种 DSL,以这样的心态来定义函数。而 Lisp 爱好者们和 Smalltalk 爱好者们在这方面走得更远。描述这种 API 书写风格的另一个术语是连贯接口。

2 年半后,他说道,

对于内在 DSL 来说,API 和 DSL 之间的界线很模糊。本质来说,它们没有区别,内部 DSL 只不过是给 API 换了个漂亮的名字(正如 Bell 实验室有句老话说道的:“函数库设计就是语言设计”)。尽管这样,我觉得当你使用一个书写成 DSL 风格的 API 时,还是有点不同的感觉的。类似连贯接口这样的东西能让 API 有着完全不同的使用体验。换到 DSL 的语境中去思考,会让你思考不同方式编写出的代码的可读性,发掘宿主语言的语法去创造一些自己特别的东西出来——rake 是一个很好的这样的例子。

那么内在 DSL 到底看起来像什么?大抵的答案可以用一个连贯编程的例子来说明。在连贯编程中,所有的方法都返回同一个对象或一个新对象。这让方法调用能串在一起。

下面这个例子是我们从 Neal Ford 的 QCon 演讲《在静态语言和动态语言中构建 DSL 》中节录的。

def c = 2.days.fromToday.at(4.pm)

直到最近,要对整数这样的类进行特殊处理都需要类似 Ruby 或 Python 这样的动态语言来支持,尤其因为它们提供了一种称为“开放类”的东西。开放类允许在运行的时候添加新方法到类上。

那么这些跟使用 C#或 VB 的.NET 的开发人员有什么关系呢?这么说吧,C# 3 和 VB 9 都支持了名为扩展方法的东西。扩展方法允许用户静态地添加方法到已经存在的类中。你可以为一个整数创建一个“日子”方法来返回一个 TimeSpan 对象。

请注意 C# 2.0 和 C# 3.0 写法上的区别。

//C# 2.0

date d = Helper.At(Helper.FromToday(Helper.Days(2)), Helper.Pm(4));//C# 3.0date d = 2.Days().FromToday().At(4.Pm);

请注意,这两行代码实际上都编译成了相同的中间代码。所有繁重的活计都被编译器和 Extension 属性做完了。

最后是使用扩展方法的一个技巧。虽然官方只支持.NET 3.5,但 Jared Parsons 发现了一种在.NET 2.0 中使用扩展方法 的办法。基本原理就是创建一个“ExtensionAttribute”类的仿造品,让新编译器以为是真正的。

查看英文原文: Extension Methods, DSLs, and Fluent Interface

2007-12-01 22:561554
用户头像

发布了 254 篇内容, 共 70.5 次阅读, 收获喜欢 2 次。

关注

评论

发布
暂无评论
发现更多内容

模块一作业

陈实

「架构实战营」

从react源码看hooks的原理

flyzz177

React

北京等保备案预约平台是哪个?多久能办好?

行云管家

等保 等保测评 等保备案 北京

不让Bug陪你过年,StarRocks年终抓虫派对重金相邀!

StarRocks

#数据库

Java程序员:为了跳槽刷完1000道真题,没想到老板直接给我升职了

钟奕礼

Java 程序员 java面试 java编程

天天预约 | 2022年11月产品更新

天天预约

小程序 SaaS 软件系统 产品分析 预约工具

关于K8s中资源服务质量管理Resource Qos的一些笔记

山河已无恙

12月月更

函数计算平稳助力鱼传科技应对访问量激增

Serverless Devs

干货 | 如何快速实现BitSail Connector?

字节跳动数据平台

开源 数据引擎 12 月 PK 榜

WALLYS/dr6018 vs dr6018s/ipq6018/ipq6010/ipq6000/SFP/ OpenWRT 2x2 2.4G&5G industrial wifi6 moudle

wallysSK

IPQ6010 ipq6018 IPQ6000

令人头秃的js隐式转换面试题,你能做对吗

loveX001

JavaScript

看透react源码之感受react的进化

goClient1992

React

双机双工是什么意思?与双机热备有什么区别?

行云管家

双机热备 双机双工

Zebec联合Visa推出实体借记卡持续利好生态,生态通证$ZBC表现强劲

西柚子

React-Hooks源码深度解读

goClient1992

React

从recat源码角度看setState流程

flyzz177

React

react的useState源码分析

flyzz177

React

VoneBaaS荣获第二届中国可信区块链安全攻防大赛优秀案例奖

旺链科技

区块链 产业区块链 VoneBaaS 12 月 PK 榜

从输入URL到渲染的过程中到底发生了什么?

loveX001

JavaScript

百度前端二面常考面试题

loveX001

JavaScript

鱼传科技:函数计算,只要用上就会觉得香

Serverless Devs

公司CTO:高性能开发,你不会Netty,怎么好意思拿20K?

钟奕礼

Java 程序员 java面试 java编程

工作中常用的设计模式--适配器模式

lpe234

后端 设计模式 适配器模式 spring-boot

技术分享| anyRTC音视频与微信小程序互通实践

anyRTC开发者

小程序 音视频 WebRTC RTMP 视频格式转换

Node.js 基于区块链的游戏应用的首选

devpoint

JavaScript node.js 区块链 12月月更

老板答应了我,只要回答对几道简单的Spring问题,就给我涨3K

钟奕礼

Java 程序员 java面试 java编程

深度分析React源码中的合成事件

goClient1992

React

可观测性项目对 uprobe 的需求理解与实现

KINDLING

Linux 可观测性 ebpf uprobe

基于Lattice的干净架构实践

原力在线

中台 构架 lattice 高可扩展 干净的架构

扩展方法、DSL和连贯接口_.NET_Jonathan Allen_InfoQ精选文章