【问题标题】:As OOAD is to OOP what is the equivalent for functional programming?正如 OOAD 之于 OOP,函数式编程的等价物是什么?
【发布时间】:2014-05-01 13:20:03
【问题描述】:

我最近涉足函数式编程 (FP) 领域,想知道如何为中等规模的应用程序“进行函数式思考”?特别是w.r.t。 FPs的分析与设计。

通过 OOP,我们可以根据对象、它们的属性和关系进行思考。我们使用类和序列图对我们的分析/设计进行建模。然而,在为 FP 设计时,相同的模型似乎不合适。函数式编程的等效建模范例是什么?看起来 DFD 可能很合适,但我可能错了。

例如:我正在考虑设计一个模拟大富翁,使用 Haskell 的棋盘游戏,只是为了学习语言。在执行 OOAD 时,您会提出像 board 这样的类,其中包含 items 附加了属性/方法。您有player 和各种其他对象及其关联关系,可以在类图中捕获。以及它们在序列图中的交互。然而,这些建模范式似乎不能很好地转移到函数式程序中。那么只是“如何”在功能上建模?

注意:我正在寻找可以解释如何分析和设计功能程序的具体参考资料/示例,因为我来自于一个高度面向对象的思维/建模方式。

【问题讨论】:

  • 我真的不认为简单的大富翁模拟可能是获得函数式编程风格的最佳项目。垄断有一种相当紧迫的感觉,我认为你可能会在尝试对其进行功能编码时绊倒自己。为什么不尝试一下解析器、正则表达式匹配器,甚至是玩具语言的编译器?

标签: oop haskell functional-programming ooad


【解决方案1】:

根据西蒙·佩顿·琼斯的说法:

您所使用的语言深刻地影响着设计 用该语言编写的程序。例如,在 OO 世界中,许多 人们使用 UML 来绘制设计草图。在 Haskell 或 ML 中,一个写类型 而是签名。功能的大部分初始设计阶段 程序包括编写类型定义。但是,与 UML 不同的是,所有 这种设计被纳入最终产品,并且是 全程机器检查。

来源:Masterminds of Programming

因此,您实际上无需绘制所有花哨的 UML 图,而是在设计阶段编写类型定义以及 undefined

【讨论】:

    【解决方案2】:

    这些天我的所有编程都由单人项目组成。如果我与其他程序员合作一个项目,我认为编写类型定义并使用undefined 将是一个好方法。

    但我收集到你真正想要的是一些关于如何学会功能思考的建议。所以这里有一些想法。

    在 Haskell 中编程时,我对正在编写的程序有两种看法。

    • 如果程序是数学的,我认为程序是一组方程。

    • 否则,我倾向于将程序视为一个或多个数据转换链。 (所以也许 DFD 会很有用。)

    因此,在您的 Monopoly 示例中,我的第一个想法是弄清楚我将如何表示董事会的状态(例如,哪些房产有房子,谁拥有它们)。然后我可能有一个功能,可以在有人购买房产时改变棋盘,以及其他玩家可能会做的事情的功能。 (还有表示状态的 monad,StateStateT。如果我觉得它们会使代码更清晰,我可能会使用它们,但我通常会保持基本的开始。)

    作为初学者,我最常犯的错误之一是创建了许多不必要的类和数据类型。

    【讨论】:

    • 另见这篇博文。这是如何进行函数式思考的一个很好的例子。 neilmitchell.blogspot.ie/2013/09/…
    • 不必要的类可能不好,但不必要的数据类型可能是品味问题或学习过程的必要部分。我不会害怕放弃一些数据类型来开始,即使它们最终证明是不必要的。在您知道使用它们的计划确实有意义之前,不要实现一堆函数来操作它们。
    【解决方案3】:

    简答:小程序的组合。

    您首先研究您面前的问题,然后开发一组您认为在该问题的上下文中有意义的小操作(通常以组合子的形式),最后围绕这些操作构建解决方案。我的印象是在 Hackage 上找到的所有软件包都遵循这种方法。

    通过这种方式,最终的解决方案(通常)是简单、清晰和优雅的。正如您所了解的,您为解决方案选择的上述一组小操作至关重要;通过练习,您将培养明智地选择它的敏感性。

    我的书建议是 Pearls of Functional Algorithm Design,作者是 Richard Bird,Google Books (preview)。在本书中,您将了解函数式编程的计算方法,我认为这是最有价值的。

    【讨论】:

      【解决方案4】:

      您可能会感兴趣的两本书:

      1. Structure and Interpretation of Computer Programs - Scheme 中 CS 教科书的经典介绍。我认为对于对 FP 感兴趣的程序员来说这是必须的。

      2. How to Design Programs - 与 SICP 类似,更现代一些,专注于设计。这里选择的语言是 Racket。

      如果你想在 Haskell 中动手实践项目,我会推荐 Write Yourself a Scheme in 48 Hours,这是一个用于实现 Scheme 解释器的精彩教程。 AST 操作是 FP(尤其是 Haskell)大放异彩的地方,所以我认为编写解释器对于新的 FP 程序员来说是一种很好的体验。

      【讨论】:

      • Scheme 和 Racket 是动态类型的。这与静态类型的 Haskell 有很大的不同。只有静态类型允许“按类型表达您的设计并对其进行机器检查”。
      • 我记得,如何设计程序计算机程序的结构和解释更具有介绍性,但可能对先略读。
      【解决方案5】:

      我对 FP 与 OO 分析和设计辩论的看法如下:

      • OOAD 和 DDD(领域驱动设计)是非常有用的软件系统分解工具;
      • FP 有类型,OO 有类和接口:它们在不同的世界中是对偶的;
      • FP 有类型实例,OO 有类实例(又名,OO 中的对象);
      • 在 FP 中使用组合,而在 OO 中则使用继承;
      • FP 和 OO 语言都带有多态结构;
      • FP 和 OO 都使用集合(集合、列表和映射)在实例(FP 中的类型和 OO 中的类)之间建立连接;
      • FP 中的关联通常作为实例 ID 的集合来实现,而在 OO 中它们是作为对对象内存位置的引用的集合来实现的。这来自于 FP 中数据结构的不变性。

      FP 中的大多数书籍,就像我之前的其他答案中提到的那些,都没有向您展示如何设计(也称为分解)复杂的现实世界问题。他们通常通过非常简短的示例来展示 FP 的功能(例如,将它们与 Craig Larman 的 Applying UML and Patterns 优秀书籍中的示例进行比较,然后自行判断)。

      对于更接近于功能导向分析和设计 (FOAD) 的东西,我推荐这些:

      DDD、OOAD 和 FOAD 可以用任何编程语言实现,但是一些编程语言提供的结构使这些方法更容易或更难实现,但它们非常实用。在 FP 的背景下讨论 DDD 的许多来源都可以证明这一点。

      博士。 Alan Kay 谈到了 OOP 的本质(here):

      对我而言,OOP 仅意味着消息传递、本地保留和保护以及 隐藏状态过程,以及所有事物的极端后期绑定。它 可以在 Smalltalk 和 LISP 中完成。可能还有其他系统 这是可能的,但我不知道。

      在此声明之后,Erlang 的创建者之一乔·阿姆斯特朗(Joe Armstrong)认为,Erlang 可能是最面向对象的语言(see this interview also featuring Ralph Johnson),这是一种在行业中有重要用途的 FP 语言(例如 WhatsApp)。

      另外,有人说 Erlang 是捕捉 OO 编程精髓的最佳语言:the passing of messages between objects

      希望这对您有所帮助。

      【讨论】:

        【解决方案6】:

        我只能从 Erlang OTP 的角度讲。我们根据具有状态和功能的过程来思考。因此,在状态下,进程将拥有所有“变量”,并且处理函数对进程在其消息队列中接收到的数据做出反应。他们对接收到的数据采取行动,可能会改变自己的状态,可能会返回一些数据和/或产生一些副作用。状态可以存储在地图或记录或任何其他有效数据类型中。通常我们定义一个称为 state() 或 loopData() 的记录。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-01-17
          • 2011-12-11
          • 1970-01-01
          • 2018-08-21
          • 2015-12-05
          • 2020-02-13
          • 2011-12-25
          • 2019-12-07
          相关资源
          最近更新 更多