写点什么

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

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

关注

评论

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

区块链预付卡APP的上线流程

北京木奇移动技术有限公司

区块链开发 软件外包公司 web3开发

Apache RocketMQ 创新论文被软件工程顶会 FM 2024 录用

Apache RocketMQ

开源 Qwen3-Coder 是顶级 AI 阳谋,阿里的野心藏不住了

程序员晚枫

开源 大模型

提示注入2.0:混合AI威胁下的新型网络安全挑战

qife122

网络安全 提示注入

企业为什么需要私有化部署的IM软件?

BeeWorks

即时通讯 IM 私有化部署

开赛 | KWDB 核心贡献挑战赛,30万奖金池等你来瓜分!

KaiwuDB

倒计时2天!合合信息WAIC黑科技剧透来袭!

合合技术团队

人工智能 算法 #大数据

如何通过自动化工具发现10+SQL注入和30+XSS漏洞

qife122

网络安全 自动化工具

即时通讯:BeeWorks私有化方案重塑企业沟通方式

BeeWorks

即时通讯 IM 私有化部署

深度剖析 RocketMQ 5.0 之架构解析:云原生架构如何支撑多元化场景?

Apache RocketMQ

RocketMQ 云原生 消息队列

BEVDet 算法详细解读-全网最全攻略

十三Tech

构建编程智能体一年实践的经验教训分享

Baihai IDP

程序员 AI AI Agent 编程智能体

大数据-51 Redis 分布式锁到哨兵机制:一文掌握Redis高可用架构

武子康

Java redis 大数据 缓存 分布式

哈尔滨二级等保测评:关注重点与实施要点

等保测评

经典MCP服务器漏洞如何威胁您的整个AI代理系统

qife122

SQL注入 漏洞挖掘

基于YOLOv8的交通车辆(12种常见车型)实时检测系统识别项目|完整源码数据集+PyQt5界面+完整训练流程+开箱即用!

申公豹

yolov8

京东零售重磅开源 | OxyGent:像搭乐高一样组装AI团队,实现群体智能

京东零售技术

CrossOver玩《幻兽帕鲁》进不去游戏、黑屏怎么办?

阿拉灯神丁

游戏卡顿 CrossOver Mac下载 如何在Mac上运行win游戏 幻兽帕鲁 雷神加速器

利用CSRF暴力破解用户ID实现批量删除用户攻击

qife122

CSRF WEB安全

让复杂 AI 应用构建就像搭积木:Spring AI Alibaba Graph 使用指南与源码解读

阿里巴巴云原生

阿里云 微服务 云原生 Spring AI Alibaba

中烟创新推出“小快轻准”应用产品,助力中小企业数字化转型

中烟创新

基于 Apache RocketMQ 的 ApsaraMQ Serverless 架构升级

Apache RocketMQ

云原生 事件驱动 消息队列

海外版“JoyLinker”来了!全家桶套件免费开放!

BeeWorks

即时通讯 IM 私有化部署

生产管理系统赋能烟草行业:激活高效生产新动能

中烟创新

区块链预付卡APP的运营策略

北京木奇移动技术有限公司

区块链开发 软件外包公司 web3开发

1688图片搜索商品API指南

tbapi

1688API接口 1688拍立淘接口 1688图片搜索API 1688拍立淘api

RocketMQ 打破锁性能瓶颈之道

Apache RocketMQ

云原生 消息队列

Mac mini玩游戏怎么样?怎么提高Mac mini玩游戏的流畅度?

阿拉灯神丁

CrossOver Mac下载 如何在Mac上运行win游戏 苹果电脑必备软件 Mac游戏推荐 虚拟机安装

哈尔滨三级等保建设:从规划到落地的关键步骤

等保测评

算法赋能再升级!非凸底仓增强算法全面上线江海证券

非凸科技

Voice AI Agent 知识库:打造你自己的语音智能体!

RTE开发者社区

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