2009-11-30 16 views
13

Estoy aprendiendo Erlang y estoy tratando de crear un programa de blog muy muestra. Sin embargo, mi mente actualmente es atrapada en el mundo OO (var p = new Post(); p.Title = ""; p.Save();). Me gustaría entender algunos pensamientos básicos en Erlang. En lugar de crear el objeto Post, ¿qué debo hacer en términos de estructura de datos (p.Title, p.DateCreated, p.Body)? ¿Debo usar tupla? Me gustaría entender la forma recomendada de hacer tales cosas (tanto en el programa específico de Erlang como en el de programación funcional). ¿O es lo que estoy haciendo fundamentalmente mal en Erlang o FP?Erlang (programación funcional) vs programación orientada a objetos en términos de pensamiento

Requisito (en términos OO, no está seguro de cómo explicar en términos de PF sin embargo^_ ^):

  1. crear el objeto de destino (ID, título, DATE_CREATED, cuerpo, IList)
  2. crear objeto Comment (id, post_id, created_by (nombre como cadena), date_created)
  3. un mensaje puede tener varios comentarios
  4. post.AddComment (comentario)

Gracias.

Actualizado: Yo no busco a determinada forma de hacer programación orientada a objetos en Erlang a menos que sea la forma recomendada. Estoy buscando la forma estándar/recomendada de hacer lo que se describe en la pregunta, sin embargo, no estoy tratando de replicar OOP en Erlang.

+0

Puede usar una tupla en lugar de un objeto, pero el uso de registros es probablemente más claro. (Los registros se traducen en tuplas de todos modos en Erlang.) –

+0

@Nate gracias por esto ya que no sabía la palabra clave antes. Aquí hay un resultado superior de búsqueda de Google solo para referencia. http://20bits.com/articles/erlang-an-introduction-to-records/ – Jeff

+0

@Nate ¿Cómo se representa el estado privado y los métodos mediante el uso de registros? ¿Podrían explicar cómo los registros se pueden usar efectivamente como un reemplazo de clases, interfaces, etc.? –

Respuesta

5

me gustaría utilizar registros:

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

Entonces, si usted desea utilizar como base de datos mnesia:

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

Para añadir un comentario:

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). 

No he probado el código, pero esto es lo que haría. También asumí que cada título es único.

+0

¿Qué pasa con los métodos, el estado privado, etc.? –

+1

quizás cree un módulo y exporte estas funciones: publicación: guardar (Título, Cuerpo) -> Aceptar | {error, Razón}. publicación: save_comment (PostTitle, CommentBody, CreatedBy) -> ok | {error, Reason}? No estoy seguro de lo que quiere decir con estado privado –

+0

@TP La pregunta es sobre hacer OOP en Erlang. ¿Cómo se puede usar Erlang para simular objetos con estado y métodos, mientras se ocultan los detalles del usuario del objeto? (Por supuesto, no hay un estado mutable en Erlang, pero el usuario del objeto no necesita saber cómo se maneja internamente). Creo que los procesos son mejores que los registros al simular objetos reales. –

6

Erlang es un lenguaje orientado a objetos. Esta declaración tiene más poder si nos fijamos en programación orientada a objetos la manera Alan Kay describió:

programación orientada a objetos para mí significa que sólo la mensajería, retención local y la protección y ocultamiento de el estado del proceso, y la extrema enlace tardío de todas las cosas.

Como usted debe ser consciente, Erlang promueve un estilo de programación llamado concurrencia Programación Orientada a, en el que abstraer objetos como procesos independientes que se comunican mediante el paso de mensajes. Cada proceso tiene su estado local, viven en su propio mundo paralelo. El polimorfismo dinámico se logra por el hecho de que puede definir un clase de procesos que pueden responder a un conjunto común de mensajes. A medida que los 'objetos' de Erlang viven en su pequeño proceso, se convierte en un medio natural para modelar el mundo real. Puede hacer uso de sus habilidades OOP mejor en Erlang que en cualquier otro idioma.

No se puede dar una descripción completa sobre OOP en Erlang en un espacio tan pequeño. Le sugiero que lea el libro Programming Erlang: Software for a Concurrent World.

ver también estos vínculos:

+1

Pensé que Joe Armstrong nunca admitió que Erlang es un lenguaje OO. – Jeff

+2

@Jeffrey No sé si Joe Armstrong admite a Erlang como OO o no, pero si usa la definición más estricta de OOP, Erlang es uno de los idiomas excepcionales que le permite programar en ese paradigma. –

+0

Joe lo admite en el sentido más estricto de Alan Kay, pero definitivamente no en el sentido más común de clases/objetos/jerarquías, es decir, lo que comúnmente se entiende por el término OOP. ¡Acepta que hay una cruz aquí para alejar los males de OOP! :-) – rvirding

0

Su ejemplo no representa realmente un buen estilo OO.Los comentarios aparecen en las publicaciones de blog ya publicadas, por lo que para entonces solo tienes algún tipo de referencia a la identificación postal en la que se publica el comentario.

Para la programación OO, tendría más sentido tener algún tipo de objeto BlogDb al que enviar objetos de publicación y comentario. Un objeto de comentario necesita saber a qué identificación postal es un comentario. No debe crear objetos de publicación y comentario utilizando el operador 'nuevo', en su lugar la interfaz BlogDb tiene métodos que devuelven instancias nuevas de esos.

De repente, tiene una forma aceptable de implementar lo mismo en Erlang. Inicie un gen_server que es el blog_db. Hacer cosas como

Post = myblog:post(Title, Body), 
{ok, Result} = myblog:add_post(BlogDb, Post), 
... 

No es necesario conocer los detalles del valor del anuncio, por lo que la forma en que se construye está escondida en un "constructor", ya que en otro módulo.

+1

¿Por qué las personas siempre comentan qué tan malos son los ejemplos en la pregunta? Está destinado a ser un ejemplo, para una referencia rápida solamente, para ayudar a quien entiende la pregunta mejor, ¡no a algún tipo de "ejemplo bien diseñado y modelado"! – Jeff

+0

Porque OO bien diseñado es bastante similar a "CO". – Christian

0

OOP para mí significa solo mensajería, retención y protección local y ocultación del proceso de estado, y enlace extremo de todas las cosas.

Alan Kay es el creador de Smalltalk junto con Dan Ingalls. Si observa Smalltalk, queda claro a qué se refiere con los mensajes: se envía un mensaje a algún objeto receptor como aBumblebee.fly(). Desarrollé casi 10 años con Smalltalk. Sé un poco cómo está diseñado. Pero lo que se hace en Erlang es volar (aBumblebee) donde aBumblebee tampoco es una instancia de una clase.

No estoy seguro de esto, pero cuando miras a los actores en Erlang tampoco parecen intercambiar mensajes. Como entiendo Erlang hasta ahora, esta construcción de {{{}} recepción es porque los mensajes deben ser recuperados de alguna lista. No hay otra manera de enviarlo al actor receptor.

Si Erlang fuera OO, tampoco habría necesidad de estos enunciados de caso. Son necesarios, porque no hay un enlace tardío. Hay una invocación dinámica en Erlang, sí. Pero no hay un envío dinámico de mensajes y de eso se trata el enlace tardío: el puntero a la función para saltar no está definido en tiempo de compilación, sino que buscó en el tiempo de ejecución. Dado que todas las funciones en Erlang son de tipo global, no se necesita ninguna búsqueda de alguna clase. Además, no veo de qué manera existe protección en Erlang. ¿Cómo se proporciona la encapsulación si no hay clase, módulo o algo así? Para un registro, todos los campos son públicos.

Cuestiones relacionadas