写点什么

扩展方法、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:561500
用户头像

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

关注

评论

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

网络损伤工具大乱斗

声网

Dev for Dev 网络损伤 网络仿真 网络与传输

模块 8 作业

miliving

Spring Boot AOP 扫盲,实现接口访问的统一日志记录

沉默王二

Java

AI安全技术总结与展望| 社区征文

herosunly

人工智能 新春征文 2月月更

提权方式及原理简介(面试)

喀拉峻

黑客

你知道MySQL InnoDB 的内存组件有哪些吗?

程序猿阿星

MySQL MySQL InnoDB Buffer Pool

万字详解数据仓库、数据湖、数据中台和湖仓一体

五分钟学大数据

数据中台 数据仓库 数据湖 湖仓一体

如何在TypeScript/JavaScript项目里引入MD5校验和

华为云开发者联盟

JavaScript typescript npm md5 MD5校验

【架构训练营-模块三】

默光

架构训练营5期

凡泰极客加入中商联互联网应用工作委员会并荣任常务委员单位

FinClip

如何理解用户的行为?

石云升

产品经理 用户研究 用户模型 2月月更

基于CC2530(ZigBee设计)的温度报警器

DS小龙哥

2月月更

「前端CI/CD系列」第一篇:如何用建木CI往七牛云上传文件

Jianmu

CDN CI/CD 文件存储 七牛云 建木CI

java培训:JVM 的面试题

@零度

JVM JAVA开发

【营】在开局,提升【豹】发力 - vivo活动插件管理平台

vivo互联网技术

前端 插件系统 构架

学生管理系统模块4作业

刘洋

#架构实战营 「架构实战营」

从冬奥看中国科技(六):千里光伏初长成

脑极体

浅谈 AI 物联网基础常识 | 社区征文

liuzhen007

AI 新春征文 2月月更

当前主流视频编码技术浅析| 社区征文

王强

视频编解码 新春征文

IDP深度 | 企业到底需要何种数据分析挖掘工具?

Baihai IDP

人工智能 数据挖掘 商业智能

龙蜥社区一周动态 | 2.14-2.20

OpenAnolis小助手

Linux 开源 动态

系统学习 TypeScript(一)——认识 TypeScript

编程三昧

typescript

医疗保健行业如何从区块链中受益?

CECBC

再谈 AI 及未来的趋势 | 社区征文

宇宙之一粟

AI 新春征文 2月月更

面试突击24:为什么wait和notify必须放在synchronized中?

王磊

面试 java面试

扔掉 Electron,拥抱基于 Rust 开发的 Tauri

百瓶技术

rust 前端 框架开发 tauri

安卓隐私沙箱来了!Android Privacy Sandbox简介

XCG00

android

【漏洞分析】反序列化漏洞

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

netty系列之:EventExecutor,EventExecutorGroup和netty中的实现

程序那些事

Java Netty 程序那些事 2月月更

Bloom Filter 优化- CrimsonDB系列论文(一)

Emc

存储 LSM-Tree

大厂晋升指南:材料准备,PPT写作和现场答辩

邴越

大厂技能 2月月更 晋升 职级

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