2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

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

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

关注

评论

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

mock 请求分发

blueju

JavaScript React Mock umi umijs

萌新不看会后悔的C++基本类型总结(二)

花狗Fdog

LeetCode题解:714. 买卖股票的最佳时机含手续费,动态规划,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

虚拟化存储

lenka

产品经理 3月日更

kvm

梅花鹿鹿

kvm

程序员必须知道的数据结构:队列与栈

老王说编程

数据结构 队列

程序员必须知道的数据结构:HashMap 与 LinkedHashMap

老王说编程

Java 数据结构 hashmap

MySQL 数据查询语言(DQL)& 事务控制语言(TCL)详解

若尘

MySQL

开源镜像仓库Harbor的镜像安全

运维研习社

Docker Harbor 漏洞扫描 镜像安全 私有仓库

硬件设计必备,电子元器件高清矢量图

不脱发的程序猿

硬件产品 28天写作 硬件设计 电子元器件矢量图 3月日更

话题讨论 | 又一家大厂进入汽车领域,"百车大战"即将来临?

程序员架构进阶

话题讨论 七日更 28天写作 话题王者 3月日更

如何设计三极管控制继电器电路

不脱发的程序猿

28天写作 电路设计 继电器电路设计 三极管 3月日更

常用工具幕布高级会员获取

白贺BaiHe

用c++创作一个简单小游戏

张鹤羽

28天写作 3月日更

简单工厂模式、工厂模式、抽象工厂模式比较

良知犹存

设计模式

恋物志(二):独居者的智能生活指南

脑极体

金三银四程序员面试必备:2021最新 最全面Java复习路线!已收录GitHub

比伯

Java 编程 程序员 架构 面试

新业务团队应用数字化的4个能力

boshi

数字化转型 七日更

常见的设计模式原则

一个大红包

设计模式 设计原则 28天写作 3月日更

程序员必须知道的数据结构:线性表与链表

老王说编程

Java 链表 线性表

架构学习(2021年03月06日)

张小胖

最全Hive SQL语法、Hive函数及使用注意事项(一)

五分钟学大数据

大数据 Hive SQL 28天写作 3月日更

翻译:《实用的Python编程》04_00_Overview

codists

Python

Redis 与 I/O 多路复用模型

大海

redis

Oracle table()函数的合理运用,提高工作效率

xiezhr

oracle table() Oracle函数 3月日更

写作平台的一些乱象

ES_her0

28天写作 3月日更

Docker部署ClickHouse监控平台

wjchenge

Wireshark数据包分析学习笔记Day3

穿过生命散发芬芳

Wireshark 数据包分析 3月日更

简易项目搭建 Models层封装

happlyfox

学习 28天写作 3月日更

力扣(LeetCode)刷题,简单题(第21期)

不脱发的程序猿

面试 LeetCode 28天写作 算法面经 3月日更

18 个 Java8 日期处理的实践,太有用了!

xcbeyond

Java java8 日期处理 3月日更

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