设计模式是编程语言本身太弱的表现?

设计模式常被视为编程高手的标志,但有人批评它们是弥补面向对象语言缺陷的权宜之计。Peter Norvig指出,在Lisp等动态语言中,许多模式要么不必要的,要么实现更简单。Paul Graham认为模式可能是编程语言不够强大导致的,而Slava Akhmechet认为函数式语言的强大表达力使得设计模式变得多余。尽管GoF认可其模式在某些语言中的不适用,但在函数式语言中,如Erlang,仍然存在模式的概念,只是形式不同。学习新语言,尤其是函数式语言,可能有助于程序员理解和应用设计模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 这是给《程序员》2009年12期所写的一个补白。这一期我自己感觉最精彩的,是《设计模式》15周年这个专题。敬请关注。

 


 

在国内一般程序员的眼中,设计模式曾经是高手的代名词,是超越具体程序设计语言的神功秘诀。但是,大家也许不知道的是,设计模式几乎一出生就伴随着批评甚至嘲笑。

不要以为这是无知者的无畏举动。早在1996 年,软件技术界最顶尖的大牛之一、Google 工程总监Peter Norvig 就做过名为“ Design Patterns in Dynamic Programming ”的演讲 ,其中他敏锐地指出:

设计模式某种意义上是为解决面向对象语言(当时主要是指 C++ )本身缺陷的一种权宜之计。在 Lisp 这样的动态(函数)语言中,由于不需要管理类和对象,不需要解决类给设计上带来的限制, GoF 23 种模式中,有 16 种要么用不着,用语言本身提供的机制就可以了,要么实现起来要简单得多。比如, Factory Singleton 可以用 MetaClass 实现, Factory Command 可以用闭包实现,等等。

无独有偶,2002 年,另一位著名程序员 Paul Graham (他开发了历史上第一个 Web 应用,也是著名创业投资公司 Y Combinator 的合伙人)也在自己访问量巨大的博客上发文 Revenge of the Nerds ,为他的最爱 Lisp 语言(以及类似的 Smalltalk Perl JavaScript )大唱赞歌。文中他对编程语言有非常精彩的论述:

“如果你要解决一个困难的问题,要考虑的不是要不要用一种足够强大的语言,而是面临这样的选择: 1.  使用一种强大的语言; 2.  实际上为语言写一个解释器; 3.  自己成为语言的人肉编译器。”他认为模式其实就是人肉编译器的表现。程序里出现的模式,往往是一种坏味。

最激烈的批评来自一位年轻但非常有才华的程序员 Slava Akhmechet ,他曾经用 Common Lisp 开发了Web 框架 Weblocks ,目前正在开发针对 SSD 优化的 MySQL 引擎 RethinkDB ,并以此创办了一家新公司。他在 2006 年写过一篇文章 Functional Programming For The Rest of Us ,其中明确表示:“模式适用于所有软件开发?……这绝非事实。……函数式语言表达力极强。在函数式语言中不需要设计模式,因为语言足够高级,你可以直接用语言概念完成编程,完全消除设计模式。”他以 Adapter 模式为例子(同时不忘嘲笑一句,这和 Facade 有啥区别?估计得写上几页纸才说得清吧),认为如果语言支持 curry ,这个模式就无用武之地了。而善用模式匹配,可以简单地修改条件,又干掉了一大批设计模式。

GoF 在《设计模式》出版 15 周年的访谈中可以看出,他们对 GoF 设计模式不适用于某些语言并无异议。那么,是否函数式语言中真的就不需要或者没有设计模式了呢?

其实不然。我们知道,模式实际上是一种思想,GoF 模式和亚历山大的建筑模式之间就只有一些哲学上的共同性。在函数式语言中,只要存在某些特定的上下文中有似曾相识的美妙的解决方案,那么模式也就出现了。事实上,这方面已经技术界已经做了不少工作。比如 Eugene Wallingford 的模式语言 Roundabout Envoy Darrell Ferguson Dwight Deugo Call with Current Continuation 模式,而 Thomas Kuehne 则总结了一套函数式语言的模式系统,可以生成良好的面向对象设计。更引人注目的,则是 OTP 小组撰写的 Erlang 设计原则 其中,设计模式被提到一个极为中心的地位。用来设计新应用的最佳方式是通过所谓的行为( behaviour ),包括 application sup bridge supervisor 等,而这个行为就是设计模式的代称……

了解这些对一般程序员有什么意义呢?《程序员修炼之道》书中说过“每年学一种新语言”,看来,该下手了。

<think>好的,我需要详细介绍一下Forth语言。首先,Forth是一种编程语言,但用户可能对它的了解有限,我需要从基础开始讲起。 Forth语言有什么特点呢?我记得它是基于堆栈的,这意味着它使用后进先出的数据结构来处理数据。这可能让它在某些方面效率很高,但语法可能不太直观。另外,Forth是交互式的,用户可以直接在命令行中编写和执行代码,这有点像Python的REPL环境,但更底层。 然后,Forth被用于嵌入式系统和固件开发,比如Open Firmware。用户之前问过Open Firmware,所以可能需要关联一下两者的关系。Forth的简洁性和低资源消耗可能适合这类场景,但需要具体说明。 接下来是Forth的历史。它由Charles H. Moore在1960年代末期开发,最初用于天文望远镜的控制系统。后来被应用到其他领域,比如计算机固件。这部分历史能帮助用户理解它的设计初衷和应用背景。 语法结构方面,Forth是逆波兰表示法(RPN),也就是运算符后置。例如,传统的2 + 3在Forth中是2 3 +。这种结构需要解释清楚,可能对不熟悉的用户来说有点挑战,但堆栈操作是其核心。 Forth的词汇包括原语(基本命令)和用户自定义的单词。用户可以组合这些单词来创建更复杂的功能。这种可扩展性使得Forth非常灵活,但学习曲线可能较高。 在运行时环境方面,Forth通常自带编译器和解释器,允许即时编译和执行代码。这对嵌入式系统来说很有用,因为可以快速测试和调整代码。 应用领域方面,除了嵌入式系统,Forth还用于工业控制、科学仪器等需要实时性和高效资源管理的领域。这里可以举一些实际例子,比如在航天器或机器人控制中的应用。 Forth的优点包括高效、灵活、占用资源少,适合资源受限的环境。缺点可能是语法晦涩,社区较小,学习资料相对较少。需要平衡地介绍优缺点,让用户全面了解。 可能用户想知道与其他语言如C或Python的区别,可以简要对比,但重点还是放在Forth本身的特性上。此外,用户可能对如何开始学习Forth感兴趣,可以推荐一些资源或简单的代码示例。 最后,总结Forth的独特之处和适用场景,帮助用户判断是否适合他们的需求。需要确保内容结构清晰,技术细节准确,同时用通俗易懂的语言解释概念,避免过于晦涩的专业术语。</think>Forth 是一种**基于堆栈的、可扩展的编程语言**,以其极简主义设计、高效性和对硬件的直接控制能力著称。它由 Charles H. Moore 在 1968 年发明,最初用于控制射电望远镜,后广泛应用于嵌入式系统、固件开发(如 Open Firmware)和实时控制领域。以下从核心设计、语法特性、应用场景及优劣等方面详细解析: --- ### 一、核心设计理念 #### 1. **堆栈驱动模型** - **数据传递方式**:所有操作通过**数据堆栈(Data Stack)**和**返回堆栈(Return Stack)**完成,无需显式变量。 - **示例**: ```forth 2 3 + . \ 计算 2+3=5 并输出(输出结果为5) ``` - `2` 和 `3` 被压入堆栈,`+` 弹出两者相加后压回结果,`.` 弹出并打印。 #### 2. **逆波兰表示法(RPN)** - **运算符后置**:如 `5 3 -` 表示 `5 - 3`。 - **消除括号**:通过堆栈顺序明确运算优先级,例如 `(3+4)*5` 写成 `3 4 + 5 *`。 #### 3. **可扩展性** - **通过“单词”(Word)定义功能**:用户可组合基础操作符(Primitives)创建新功能。 ```forth : square ( n -- n^2 ) dup * ; \ 定义计算平方的单词 5 square . \ 输出25 ``` --- ### 二、语法与运行时特性 #### 1. **交互式开发环境** - **即时编译与执行**:输入代码逐行解释或编译,支持快速调试。 - **直接硬件访问**:可通过底层操作控制内存、寄存器等。 #### 2. **极简内核** - **核心词汇仅约30个**:如 `dup`(复制栈顶)、`swap`(交换栈顶两项)、`drop`(丢弃栈顶)。 - **自举能力**:可用 Forth 自身编写编译器,实现语言自举。 #### 3. **元编程能力** - **编译时控制**:通过 `IF...THEN`、`BEGIN...UNTIL` 等控制编译流程。 - **示例:条件编译** ```forth DEBUG [IF] : log ( str -- ) cr type ; \ 调试模式下启用日志 [ELSE] : log ( str -- ) drop ; \ 非调试模式忽略日志 [THEN] ``` --- ### 三、应用场景 #### 1. **嵌入式系统与固件** - **资源受限环境**:如 Open Firmware 使用 Forth 编写设备驱动(FCode)。 - **实时控制**:工业机器人、航天器(如 NASA 的 DS-1 探测器使用 Forth)。 #### 2. **科学仪器** - **快速原型开发**:射电望远镜、实验室设备控制。 #### 3. **教育研究** - **计算机架构教学**:通过 Forth 虚拟机理解堆栈机原理。 --- ### 四、代码示例 #### 1. **阶乘计算** ```forth : factorial ( n -- n! ) dup 1 > if dup 1 - recurse * else drop 1 then ; 5 factorial . \ 输出120 ``` #### 2. **硬件寄存器操作** ```forth \ 定义内存地址常量 HEX 3F8 constant COM1_PORT \ 串口1地址 : send-byte ( byte -- ) COM1_PORT c! ; \ 将字节写入串口 : receive-byte ( -- byte ) COM1_PORT c@ ; \ 从串口读取字节 ``` --- ### 五、优势与局限性 #### **优势**: - **高效性**:直接操作堆栈,无中间层开销。 - **低资源占用**:内核可小至数KB,适合嵌入式设备。 - **灵活控制**:可精确管理内存和硬件。 #### **局限性**: - **学习曲线陡峭**:堆栈操作需逆向思维。 - **可读性差**:代码高度紧凑,维护成本高。 - **生态薄弱**:社区和库资源较少。 --- ### 六、与其他语言对比 | 特性 | Forth | C语言 | Python | |---------------|------------------------|---------------------|---------------------| | **执行模型** | 堆栈驱动 | 寄存器/内存驱动 | 解释器虚拟堆栈 | | **资源占用** | 极低(KB级) | 中等(MB级) | 高(数十MB) | | **实时性** | 强(无垃圾回收) | 强 | 弱(有GC延迟) | | **硬件控制** | 直接操作 | 通过指针/内联汇编 | 依赖外部库 | --- ### 七、学习资源 1. **经典书籍**: - 《Starting Forth》 by Leo Brodie(入门必读) - 《Thinking Forth》 by Leo Brodie(深入设计思想) 2. **实现工具**: - **gforth**:GNU 开源 Forth 解释器(跨平台)。 - **amForth**:针对 AVR 单片机的轻量级实现。 3. **社区**: - [Forth Interest Group](https://www.forth.org/)(国际组织) - [comp.lang.forth](https://groups.google.com/g/comp.lang.forth)(讨论组) --- ### 八、总结 Forth 通过**堆栈抽象**和**极简内核**,在嵌入式控制、实时系统等领域展现了独特价值。其设计哲学强调**程序员对机器的完全掌控**,适合需要精细优化或硬件直接操作的场景。尽管现代软件开发中较少使用,但理解 Forth 有助于掌握**底层计算模型**和**语言设计范式**。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值