软件设计之美
郑晔
推文科技技术VP,前火币网首席架构师
立即订阅
3244 人已学习
课程目录
已更新 25 讲 / 共 35 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 软件设计,应对需求规模的“算法”
免费
课前必读 (3讲)
01 | 软件设计到底是什么?
02 | 分离关注点:软件设计至关重要的第一步
03 | 可测试性: 一个影响软件设计的重要因素
了解一个软件的设计 (4讲)
04 | 三步走:如何了解一个软件的设计?
05 | Spring DI容器:如何分析一个软件的模型?
06 | Ruby on Rails:如何分析一个软件的接口?
07 | Kafka:如何分析一个软件的实现?
设计一个软件—程序设计语言 (5讲)
08 | 语言的模型:如何打破单一语言局限,让设计更好地落地?
09 | 语言的接口:语法和程序库,软件设计的发力点
10 | 语言的实现:运行时,软件设计的地基
11 | DSL:你也可以设计一门自己的语言
加餐 | 再八卦几门语言!
设计一个软件—编程范式 (9讲)
12 | 编程范式:明明写的是Java,为什么被人说成了C代码?
13 | 结构化编程:为什么做设计时仅有结构化编程是不够的?
14 | 面向对象之封装:怎样的封装才算是高内聚?
15 | 面向对象之继承:继承是代码复用的合理方式吗?
16 | 面向对象之多态:为什么“稀疏平常”的多态,是软件设计的大杀器?
17 | 函数式编程:不用函数式编程语言,怎么写函数式的程序?
18 | 函数式编程之组合性:函数式编程为什么如此吸引人?
19 | 函数式编程之不变性:怎样保证我的代码不会被别人破坏?
加餐 | 函数式编程拾遗
设计一个软件—设计原则与模式 (3讲)
20 | 单一职责原则:你的模块到底为谁负责?
21 | 开放封闭原则:不改代码怎么写新功能?
22 | Liskov替换原则:用了继承,子类就设计对了吗?
软件设计之美
15
15
1.0x
00:00/00:00
登录|注册

11 | DSL:你也可以设计一门自己的语言

郑晔 2020-06-17
你好!我是郑晔。
在前面,我们花了三讲的篇幅探讨程序设计语言,一方面是为了增进我们对程序设计语言的理解,另一方面,也希望从中学习到软件设计方面做得好的地方。除了借鉴一些语言特性之外,我们还能怎样应用程序语言,来帮我们做设计呢?
讲到程序设计语言模型时,我说过,程序设计语言的发展趋势,就是离计算机本身越来越远,而离要解决的问题越来越近。但通用程序设计语言无论怎样逼近要解决的问题,它都不可能走得离问题特别近,因为通用程序设计语言不可能知道具体的问题是什么。
这给具体的问题留下了一个空间,如果我们能把设计做到极致,它就能成为一门语言,填补这个空间。注意,我这里用的并不是比喻,而是真的成为一门语言,一门解决一个特定问题的语言。
这种语言就是领域特定语言(Domain Specific Language,简称 DSL),它是一种用于某个特定领域的程序设计语言。这种特定于某个领域是相对于通用语言而言的,通用语言可以横跨各个领域,我们熟悉的大多数程序设计语言都是通用语言。
我在第 8 讲说过,它们都是图灵完备的,但 DSL 不必做到图灵完备,它只要做到满足特定领域的业务需求,就足以缩短问题和解决方案之间的距离,降低理解的门槛。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《软件设计之美》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(15)

  • 蓝士钦
    SQL也是一种DSL,他屏蔽了计算机存储的底层实现,提供了易于操作数据的接口。
    一些ORM框架对SQL这些DSL进行了进一步的封装提供了声明式注解,相当于构建在DSL之上的DSL翻译器。面向对象编程将面向关系的DSL进行更高层次的封装,使得在编程这个特定领域更加易于使用。

    作者回复: 很好的分享!

    2020-06-17
    9
  • 泡泡龙
    我觉得markdown应该算一个

    作者回复: 嗯,好有趣的角度!

    2020-06-17
    5
  • Jxin
    1.k8s和docker-compose的yml文件,就是声明试编程。算是外部dsl。

    2.本章疑问: dsl和接口有何异同点?

    首先dsl和接口都做了一件事,就是意图和实现的分离。但是dsl的语义(意图)是可以灵活组织的,而接口的语义基本靠接口命名和方法命名来阐述,在灵活性上明显是不足的。

    如何去实现dsl?第一感觉就是建造者模式。这里实现就有分支。第一种是将要执行的业务逻辑(实现)写在dsl实体bean内部。在所有业务功能都由实体内部属性决定时,这是可行的(领域模型的行为);第二种是将执行的业务功能注入要创建的dsl实体,然后回调。毕竟复杂业务流程的组织不该是单个实体能够囊括的,而且我们的功能代码大部分还是面向过程的(java就是一个service注入一个service,然后嵌套调用);第三种就是将dsl实体作为入参传入接口方法,然后通过其属性调整业务流向,控制代码逻辑。这种方式我认为是开发维护成本最低的(面向过程不好,但他简单呀,不需要什么设计知识背书,懂语法就能看懂),但是我在某本书看到过,“程序的逻辑不该由入参去控制”。是定制多个接口方法。还是提供统一方法由入参调度逻辑,真的不好说孰好孰劣。

    作者回复: 后面我们就来谈结构化编程和面向对象编程。

    2020-06-17
    5
  • 被雨水过滤的空气
    高级编程语言是低级编程语言的DSL。

    作者回复: 哈哈,确实可以这么理解。

    2020-06-18
    3
  • happychap
    drone.io用的.drone.yml,jenkins用的pipefile都算是轻量级的dsl。uml算不算是一种重量级的dsl呢?

    作者回复: UML可能不算,因为它不能执行。

    2020-06-17
    3
  • 阳仔
    DSL是为了解决某个特定领域的程序设计语言。
    作为一个客户端APP开发者,最常用到的莫过于gradle。
    现在JAVA后端程序主要是通过pom配置构建,它其实就是通过xml来实现DSL,
    我觉得后端程序通过gradle构建也将会成为主流。它比xml更加灵活,表达性更强
    要设计一个DSL就要构建一个模型,通过接口将能力暴露出来。
    如何暴露接口就可以分为内部DSL和外部DSL,内部DSL使用编程语言如JAVA来实现,外部则使用类似xml语言来实现,或者自己设计语法
    实现内部DSL要将意图与实现区分开,这在程序设计中一个重要的原则

    作者回复: 非常好的总结!

    2020-06-17
    3
  • escray
    我还没有到“设计一个 DSL”的高度,而且可能日常工作中遇到的问题也没有需要一门新的 DSL 来解决。

    正则表达式、配置文件和 SQL 都可以算作 DSL,这些都是受众比较广泛的,如果是自己设计一个,使用的人没有那么多,还有意义么?

    看了内部 DSL 的 Computer 的例子,感觉 DSL 不那么可怕了;顺便理解了为什么这“一连串的方法调用”可以被接受——因为这是一段声明 What。

    反之,如果是一连串的动作,就应该避免了。

    虽然短时间内估计不会有设计 DSL 的机会,不过“编写有表达性的代码”,“分离意图和实现”是我可以追求的目标。

    看到留言里面有同学说可以把 Markdown 也当做一种 DSL,那么其针对的领域是什么呢,排版?

    作者回复: Markdown 并不能执行。

    2020-06-18
    2
  • 再来二两杜康酒
    lambda,网络协议描述算不算是dsl呢?

    作者回复: DSL 首先是一门语言,能够执行的那种。单独的 Lambda 和协议都是不可执行的。

    2020-06-17
    2
  • PM2
    1、redis的指令应该不算是dsl,而只是接口吧
    2、linux的awk应该算是一种dsl。

    作者回复: AWK已经是一门正经的语言了。

    2020-06-22
    1
  • 春去春又来
    全文读完就感觉 DSL 其实就是个间接层,为什么要有这个间接层,为了就是能更简单的更快捷的解决问题。

    作者回复: 是的,接口也很重要。

    2020-06-19
    1
  • NIU
    如果这么说,移动端开发常用的Cocoapods也是一种DSL。

    作者回复: 嗯,也算。

    2020-06-17
    1
  • 三生
    sdk也应当是一种dsl

    作者回复: 这个?有点太泛化了。

    2020-07-05
  • 蜗牛不会飞
    Quartz等调度框架常用的Cron表达式也是一种DSL吧

    作者回复: 嗯,还真是。

    2020-07-01
  • 小学一年级
    普通程序员的关注点只在于功能如何实现,而优秀的程序员会懂得将不同层次的代码分离开来,将意图和实现分离开来,而实现可以替换。

    老师 意图和实现具体指什么还是不太明白,

    作者回复: 意图,做什么,实现,怎么做。

    意图可以理解成方法命名,实现可以理解成方法里的每行代码。

    意图可以理解成接口定义,实现可以理解成实现类。

    2020-06-28
  • 董松涛
    ansible-playbooks的yml文件应该也能看成dsl

    作者回复: 某种程度上,算。

    2020-06-23
收起评论
15
返回
顶部