简体   繁体   English

OOAD是OOP的功能编程的等价物是什么?

[英]As OOAD is to OOP what is the equivalent for functional programming?

I've recently forayed into the world of functional programming (FP) and am wondering how to "think functionally" for even moderately sized applications? 我最近进入函数式编程(FP)的世界,我想知道如何为中等大小的应用程序“思考功能”? Especially wrt the analysis and design of FPs. 特别是FP的分析和设计。

With OOP we're trained to think in terms of objects, their attributes and relations. 通过OOP,我们受过训练,可以根据对象,属性和关系进行思考。 We model our analyses/designs using class and sequence diagrams. 我们使用类和序列图对我们的分析/设计进行建模。 However, the same models seem to be a bad fit when designing for FPs. 但是,在设计FP时,相同的模型似乎不合适。 What are the equivalent modeling paradigms for functional programming? 函数式编程的等效建模范例是什么? It seems DFDs maybe a good fit but I maybe wrong. 看起来DFD可能很合适,但我可能错了。

For example: I was thinking of designing a simulation of Monopoly, the board game using Haskell, just to learn the language. 例如:我正在考虑设计一个使用Haskell的棋盘游戏Monopoly的模拟,只是为了学习语言。 When doing OOAD you come up with classes like board contains items that have attributes/methods attached to it. 在做OOAD时,你会想出像board这样的类包含附加了属性/方法的items You have player and various other objects and their associated relations that can be captured in a class diagram. 您可以在类图中捕获player和各种其他对象及其关联关系。 And their interactions in a sequence diagram. 以及它们在序列图中的相互作用。 However, these modeling paradigms doesn't seem to transfer well for functional programs. 但是,这些建模范例似乎并不适用于功能程序。 So just "how" do you model functionally ? 那么只是“如何”在功能上建模?

Note: I'm looking for concrete references/examples that can explain how to analyze and design functional programs given that I'm coming from a heavily object-oriented way of thinking/modeling. 注意:我正在寻找可以解释如何分析和设计功能程序的具体参考/示例,因为我来自面向对象的思维/建模方式。

According to Simon Peyton Jones: 根据Simon Peyton Jones的说法:

The language in which you write profoundly affects the design of programs written in that language. 您编写的语言会严重影响用该语言编写的程序的设计。 For example, in the OO world, many people use UML to sketch a design. 例如,在OO世界中,许多人使用UML来绘制设计。 In Haskell or ML, one writes type signatures instead. 在Haskell或ML中,人们会写入类型签名。 Much of the initial design phase of a functional program consists of writing type definitions. 功能程序的大部分初始设计阶段包括编写类型定义。 Unlike UML, though, all this design is incorporated in the final product, and is machine-checked throughout. 然而,与UML不同,所有这些设计都包含在最终产品中,并且在整个过程中都经过机器检查。

Source: Masterminds of Programming 资料来源: 编程大师

So instead of drawing all the fancy UML diagrams, you actually write type definitions coupled with undefined in the design phase. 因此,您实际上在设计阶段编写了undefined类型定义,而不是绘制所有花哨的UML图。

All of my programming these days consists of single-person projects. 这些天我的所有编程都包含单人项目。 If I were collaborating on a project with other programmers, I think that writing type definitions and using undefined would be a good approach. 如果我与其他程序员合作开发项目,我认为编写类型定义并使用undefined将是一个很好的方法。

But I gather what you're really looking for is some advice about how you can learn to think functionally. 但我收集你真正想要的东西是关于如何学习如何功能上思考的一些建议。 So here are some thoughts. 所以这里有一些想法。

When programming in Haskell, there are two ways I think about the program I'm writing. 在Haskell中编程时,我有两种方式来思考我正在编写的程序。

  • If the program is mathematical, I think of the program as a set of equations. 如果程序是数学的,我认为程序是一组方程。

  • Otherwise, I tend to think of the program as one or more chains of of data transformations. 否则,我倾向于将程序视为一个或多个数据转换链。 (So perhaps DFDs would be useful.) (所以也许DFD会很有用。)

So in your Monopoly example, my first thought would be to figure out how I'm going to represent the state of the board (eg, which properties have houses, who owns them). 所以在你的垄断例子中,我的第一个想法是弄清楚我将如何代表董事会的状态(例如,哪些房产有房屋,谁拥有房屋)。 Then I might have a function that transforms the board when someone buys a property, and other functions for other things players might do. 然后我可能有一个功能,当有人购买房产时改变董事会,以及玩家可能做的其他事情的其他功能。 (There's also monads for representing state, State and StateT . I might use them, if and when I feel they will make the code clearer, but I usually keep things basic to start.) (还有monad用于表示州, State StateT我可能会使用它们,如果我觉得它们会使代码更清晰,但我通常会保持基本的开始。)

One of the mistakes I made most often as a beginner was to create a lot of unnecessary classes and data types. 我最初作为初学者犯下的错误之一是创建了许多不必要的类和数据类型。

Short answer: composition of smaller programs. 简短回答:组成较小的程序。

You first study the problem before you, then you develop a set of small operations (often in the form of combinators) that you reckon make sense in that problem's context, and finally you build the solution around those operations. 您首先要研究这个问题,然后开发一组小的操作(通常以组合器的形式),您认为在该问题的上下文中有意义,最后围绕这些操作构建解决方案。 I'm under the impression that all packages found on Hackage follow this approach. 我的印象是Hackage上发现的所有软件包都遵循这种方法。

In this way the final solution is (more often than not) simple, clear and elegant. 通过这种方式,最终的解决方案(通常不是)简单,清晰和优雅。 As you can appreciate the aforementioned set of small operations you choose for your solution is critical; 您可以理解您为解决方案选择的上述一系列小型操作非常重要; with practice, you'll develop the sensibility to pick it wisely. 通过练习,你会发展出明智的选择感受。

My book suggestion is Pearls of Functional Algorithm Design , by Richard Bird, Google Books (preview) . 我的书建议是Richard Bird, Google Books(预览版)的 Pearls of Functional Algorithm Design In this book you'll learn about the calculational approach to functional programming, which I think is most valuable. 在本书中,您将了解函数式编程的计算方法 ,我认为这是最有价值的。

Two books you might be interested in: 您可能感兴趣的两本书:

  1. Structure and Interpretation of Computer Programs - a classic intro to CS textbook in Scheme. 计算机程序的结构与解释 - 方案中CS教科书的经典介绍。 I think it's a must for programmers interested in FP. 我认为这对于对FP感兴趣的程序员来说是必须的。

  2. How to Design Programs - similar to SICP, slightly more modern and focuses on design. 如何设计程序 - 类似于SICP,稍微更现代化,专注于设计。 The language of choice here is Racket. 这里选择的语言是Racket。

If you want a hands-on project in Haskell, I'd recommend Write Yourself a Scheme in 48 Hours , a wonderful tutorial for implementing an interpreter for Scheme. 如果您想在Haskell进行实践项目,我建议您在48小时内自己编写一个方案 ,这是一个实现Scheme解释器的精彩教程。 AST manipulation is where FP (and especially Haskell) shines, so I think writing an interpreter is a good experience for new FP programmers. AST操作是FP(特别是Haskell)闪耀的地方,所以我认为编写一个解释器对于新的FP程序员来说是一种很好的体验。

My perspective regarding the FP vs OO analysis and design debate is the following: 我对FP与OO分析和设计辩论的看法如下:

  • OOAD and DDD (Domain-Driven Design) are very useful tools for software systems decomposition; OOAD和DDD(域驱动设计)是用于软件系统分解的非常有用的工具;
  • FP has types, OO has classes and interfaces: they are dual in different worlds; FP有类型,OO有类和接口:它们在不同的世界中是双重的;
  • FP has type instances, OO has class instances (aka, objects in OO); FP有类型实例,OO有类实例(也就是OO中的对象);
  • Use composition in FP, where in OO you would use inheritance; 在FP中使用组合,在OO中你可以使用继承;
  • Both FP and OO languages come with polymorphic constructs; FP和OO语言都带有多态结构;
  • Both FP and OO use collections (sets, lists and maps) to make connections between instances (of types in FP, and of classes in OO); FP和OO都使用集合(集合,列表和映射)在实例之间建立连接(FP中的类型和OO中的类);
  • Associations in FP are typically implemented as collections of instance IDs, whereas absensein OO they are implemented as collections of references to the memory locations of objects. FP中的关联通常实现为实例ID的集合,而absensein OO实现为对象的内存位置的引用集合。 This comes from the immutability property of data structures in FP. 这来自FP中数据结构的不变性。

Most books in FP, like those referred in the other answers before mine, do not show you how to design (aka, decompose) complex real-world problems. FP中的大多数书籍,就像我之前的其他答案中提到的那些书籍,并未向您展示如何设计(又称,分解)复杂的现实世界问题。 They generally demonstrate FP's features with very short examples (eg, compare them with the examples in Craig Larman's Applying UML and Patterns excelent book, and judge yourself). 他们通常用非常简短的例子来展示FP的特征(例如,将它们与Craig Larman的应用UML和模式优秀书中的例子进行比较,并自我评判)。

For something more close to what could be called Functional-Oriented Analysis and Design (FOAD), I recommend these: 对于更接近可称为面向功能的分析和设计(FOAD)的东西,我推荐这些:

DDD, OOAD, and FOAD, can be implemented in any programming language, however some programming languages offer constructs that make these approaches easier or harder to implement, but they are perfectly practical. DDD,OOAD和FOAD可以用任何编程语言实现,但是一些编程语言提供的结构使这些方法更容易或更难实现,但它们非常实用。 This is evident by the many sources you can find discussing DDD in the context of FP. 很明显,你可以在FP的背景下找到讨论DDD的许多来源。

Dr. Alan Kay said this regarding the essence of OOP ( here ): Alan Kay博士谈到OOP的本质( 这里 ):

OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. OOP对我来说意味着只有消息传递,本地保留和保护以及隐藏状态进程,以及所有事物的极端后期绑定。 It can be done in Smalltalk and in LISP. 它可以在Smalltalk和LISP中完成。 There are possibly other systems in which this is possible, but I'm not aware of them. 可能还有其他可能的系统,但我不知道它们。

Following this statement, Joe Armstrong, one of Erlang's creator, an FP language with important uses in the industry (eg, WhatsApp), argues that Erlang is perhaps the most OO language around ( see this interview also featuring Ralph Johnson ). 在此声明之后,Erlang创建者之一的Joe Armstrong,一种在行业中具有重要用途的FP语言(例如,WhatsApp),认为Erlang可能是最具OO语言的( 参见此次采访也以Ralph Johnson为特色 )。

Also, some say that Erlang is the best language that captured the essence of OO programming: the passing of messages between objects . 另外,有人说Erlang是捕获OO编程本质的最佳语言: 在对象之间传递消息

Hope this was helpful. 希望这有用。

I can only speak from the perspective of Erlang OTP. 我只能从Erlang OTP的角度讲。 We think in terms of processes, which have a state and functions. 我们从流程的角度思考,流程具有状态和功能。 So in the state the process will have all the "variables" and handler functions react to data the process receives in its message queue. 因此,在该状态下,进程将使所有“变量”和处理函数对进程在其消息队列中接收的数据作出反应。 They act on the received data, possibly alter their own state, possibly return some data and/or have some side effects. 它们对接收的数据起作用,可能改变它们自己的状态,可能返回一些数据和/或有一些副作用。 The state can be stored in a map or a record or any other valid data type. 状态可以存储在地图或记录或任何其他有效数据类型中。 Usually we define a record called state() or loopData(). 通常我们定义一个名为state()或loopData()的记录。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM