写点什么

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

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

关注

评论

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

百度高德地图JS-API学习手记:地图基本设置与省市区数据加载

zhoulujun

百度地图 高德地图

百度高德地图行政区域边界GeoJSON数据获取并绘制行政区域

zhoulujun

百度地图 高德地图

从0到1构建基于自身业务的前端工具库

京东科技开发者

前端 京东云 企业号 4 月 PK 榜

Taro架构构析(2):Taro 设计思想及架构

zhoulujun

Weex原理及架构剖析

zhoulujun

Weex ReactNative weex-vue-framework

Go 命令行参数解析工具 pflag 使用

江湖十年

后端 命令行 Go 语言

三天吃透Redis八股文

程序员大彬

redis #java

ZBC 荣登OKX涨幅榜前列,月内涨幅逾六成

鳄鱼视界

React Native UI界面还原,组件布局与动画效果

zhoulujun

ZBC 荣登OKX涨幅榜前列,生态持续发力是关键

西柚子

架构实战营 - 备选架构设计文档模板

华仔

Taro架构构析(1):多端框架分析,Taro WePY uni-app对比

zhoulujun

wepy taro uni-app

数据库原理及MySQL应用 | 数据库安全加固

TiAmo

MySQL 数据库 数据安全

开源7天Github斩获4.5万Stars!阿里2023版高并发设计实录鲨疯了

Java你猿哥

Java 面试 高并发 面经 春招

微前端项目部署方案

京东科技开发者

微前端 京东云 企业号 4 月 PK 榜

从java到JavaScript(1),看Dart:对比Java/Go/Swift/Rust

zhoulujun

Java JavaScript swift rust dart

GIS拓扑讲解点线面几何体的拓扑关系判断及运算分析_turf案例

zhoulujun

GIS Turf.js

gis经纬度坐标转换多格式兼容:支持字符串/数组/GeoJSON

zhoulujun

GIS GeoJSON 经纬度坐标转换

文本处理流程:Text Workflow 1.5.1直装版

真大的脸盆

文本处理 处理文本 文本管理工具

从java到JavaScript(2):对比Java/Go/Swift/Rust看Dart

zhoulujun

Java JavaScript dart

GIS常用npm包:GeoJSON文件合并与元素过滤\属性过滤\图形合并

zhoulujun

GIS GeoJSON

Hex Tech,一个带编程协同能力的 BI 平台的“危”与“机”

CnosDB

数据库 时序数据库 开源社区 CnosDB

Three.js 进阶之旅:全景漫游-高阶版在线看房 🏡

dragonir

JavaScript 前端 three.js

JWT 实现登录认证 + Token 自动续期方案,这才是正确的使用姿势!

Java你猿哥

Java ssm 架构师 Token JWT

selenium源码通读·3 | 从源码看引入webdriver包的原因

Python 源码 测试 自动化测试 selenium

性能测量工具-DevTools/PageSpeed/LightHouse

zhoulujun

DevTools PageSpeed LightHouse 性能测量工具

信息率失真函数与平均互信息

timerring

信息论

玩转Github:三分钟教你如何用 Github 快速找到优秀的开源项目

Java你猿哥

Java GitHub 开源 源码 ssm

GitHub Pulse 是什么?它是否能衡量 OpenTiny 开源项目的健康程度?

Kagol

开源 Vue 前端 UI组件库

selenium源码通读·2 | common/exceptions.py异常类

Python 源码 测试 自动化测试 selenium

聚焦弹性问题,杭州铭师堂的 Serverless 之路

阿里巴巴云原生

阿里云 云原生

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