Erlang(功能编程)与面向对象编程的思维方式

时间:2009-11-30 04:49:55

标签: functional-programming erlang oop

我正在学习Erlang,我正在尝试创建一个非常示例的博客程序。然而,我的思想目前被困在OO世界 var p = new Post(); p.Title =“”; p.Save(); )。我想了解Erlang中的一些基本思路。而不是在数据结构方面创建Post对象( p.Title,p.DateCreated,p.Body )?我应该使用元组吗?我想了解推荐的做这种事情的方法(特定于Erlang和/或特定于功能编程)。或者我在Erlang或FP中做的根本错误是什么?

要求(以OO术语,不确定如何用FP术语解释^ _ ^):

  1. 创建Post对象(id,title,date_created,body,IList)
  2. 创建评论对象(id,post_id,created_by(名称为字符串),date_created)
  3. 一个帖子可以有多个评论
  4. post.AddComment(注释)
  5. 感谢。

    更新: 我不是在寻找在Erlang中进行OOP的具体方法,除非它是推荐的方式。我正在寻找标准/推荐的方式来做问题中描述的内容,但我并不是想在Erlang中复制OOP。

4 个答案:

答案 0 :(得分:6)

Erlang 面向对象的语言。如果你像Alan Kay描述的那样看OOP,这个陈述就有了更大的力量:

  

OOP对我来说只意味着本地消息   保留,保护和隐藏   国家进程和极端   所有事情的后期约束。

正如您必须意识到的那样,Erlang提升了一种称为 Concurrency Oriented Programming 的编程风格,在这种编程风格中,您将对象抽象为通过消息传递进行通信的独立进程。每个进程都有它的本地状态,它们生活在自己的并行世界中。动态多态性是通过以下事实实现的:您可以定义可以响应消息的公共集的进程的。由于Erlang'对象'生活在他们自己的微小过程中,它成为现实世界建模的自然媒介。您可以在Erlang中比任何其他语言更好地利用您的OOP技能。

无法在如此小的空间内完整描述Erlang中的OOP。我建议你阅读这本书Programming Erlang: Software for a Concurrent World

另见这些链接:

答案 1 :(得分:5)

我会使用记录:

-record(post, {title, date_created, body, comments = []}).
-record(comment, {created_by, date_created, content}).

然后,如果你想使用mnesia作为数据库:

Post = #post{title = "", body = "", date_created = erlang:universaltime()},
mnesia:transaction(fun() -> mnesia:write(Post) end).

添加评论:

Comment = #comment{created_by = "", content = "", date_created = erlang:universaltime()},
mnesia:transaction(fun() ->
    [Post] = mnesia:read(post, Title),
    PostWithNewComment = Post#post{comments = [Comment | Post#post.comments]},
    mnesia:write(PostWithNewComment)
end).

我没有测试过代码,但这就是我要做的。我还假设每个标题都是独一无二的。

答案 2 :(得分:0)

您的示例并不代表良好的OO风格。评论出现在已发布的博客文章中,因此到那时您只需要对评论发布到的帖子ID进行某种引用。

对于面向对象编程,拥有某种发送帖子和评论对象的BlogDb对象会更有意义。评论对象需要知道它是评论的帖子ID。您不应该使用'new'运算符创建post和comment对象,而是BlogDb接口具有返回这些对象的新实例的方法。

突然间你有一种可行的方法在Erlang中实现同样的东西。启动一个gen_server,即blog_db。做像

这样的事情
Post = myblog:post(Title, Body),
{ok, Result} = myblog:add_post(BlogDb, Post),
...

您不需要知道Post值的详细信息,因此它的构造方式隐藏在另一个模块中的“构造函数”中。

答案 3 :(得分:0)

  

OOP对我来说只意味着消息传递,本地保留和保护以及隐藏状态进程,   所有事情的极端后期绑定。

Alan Kay与Dan Ingalls一起创建了Smalltalk。如果你看一下Smalltalk,就会发现它对消息的意义很明显:消息被发送到某个接收器对象,如aBumblebee.fly()。我用Smalltalk开发了近10年。我知道它是如何设计的。但是在Erlang中做的是fly(aBumblebee),其中aBumblebee也不是类的实例。

我不确定这一点,但是当你看到Erlang的演员时,他们似乎也没有交换消息。据我所知,Erlang到目前为止接收{case {...}}构造是因为必须从某个列表中检索消息。没有其他方法可以将其发送给收件人。

如果Erlang是OO,那么也不需要这些if-case语句。它们是必要的,因为没有后期绑定。在Erlang中有动态调用,是的。但是没有动态分派消息,这就是后期绑定的意思:跳转到的函数指针不是在编译时定义的,而是在运行时查找。由于Erlang中的所有函数都是全局函数,因此无论如何都不需要查找某些类。另外,我没有看到Erlang中保护的方式。如果没有类,模块或其他什么,你如何提供封装?记录所有字段都是公开的。