2010-05-18 10 views
6

¿Qué son exactamente las funciones de despacho? Los busqué en Google y todo es vago. ¿Parecen simplemente bloques/cierres anidados dentro de otras funciones? Hablando desde un punto Scala/Lift ... pero supongo que es universal, también los he mencionado en ruby.Despacho funciones

+0

Enlace de blog obligatorio: http://cleverlytitled.blogspot.com/2010/01/dynamic-dispatch-in-scala.html –

Respuesta

7

El objetivo del envío es decidir dinámicamente qué hacer en su función.

Cuando tiene una función de despacho (dinámica) es principal (o solo, si no necesita conversión u otras conversiones) la responsabilidad es decidir a qué otra función llamar. La decisión a menudo se basa en el tipo de instancia al que se llama el método, o el tipo de algunos de los parámetros, pero también puede depender, p. sobre el valor de los parámetros, o algunos valores de configuración.

La regla de envío se puede codificar (utilizando, por ejemplo, coincidencia de patrón en scala), o puede provenir de una tabla de envío.

Como mencionó hay varias variaciones, como envío único (el método concreto depende de la instancia en que se invoca el método original, que es un mecanismo OO básico), despacho doble (distribuye una llamada de función a diferentes funciones concretas dependiendo de los tipos de tiempo de ejecución de múltiples objetos involucrados en la llamada).

Un patrón de diseño relacionado es el visitante, que le permite agregar un conjunto de funciones dinámicamente a las clases existentes y que también tiene un despacho dinámico en su núcleo.

Los bloques/cierres anidados aparecen cuando se define el método concreto dentro del método de envío, o en algún código de inicialización (por ejemplo, para la tabla de envío).

Un ejemplo sencillo para el caso en el despacho se basa en el valor del parámetro, con la decisión codificado y con mesa de despacho:

class Dispatch { 

    def helloJohn(): String = "Hello John" 

    def helloJoe(): String = "Hello Joe" 

    def helloOthers(): String = "Hello" 

    def sayHello(msg: String): String = msg match { 
     case "John" => helloJohn() 
     case "Joe" => helloJoe() 
     case _ => helloOthers() 
    } 


    val fs = Map("John" -> helloJohn _, "Joe" -> helloJoe _) 

    def sayHelloDispatchTable(msg: String): String = fs.get(msg) match { 
     case Some(f) => f() 
     case _ => helloOthers() 
    } 
    } 
3

TIG es el término Lift utiliza para el envío de solicitudes de servicios web.

La forma más fácil de definir la función de despacho utilizando RestHelper (ver http://www.assembla.com/wiki/show/liftweb/REST_Web_Services)

Por ejemplo:

object MyRestService extends RestHelper { 
    serve { 
    case "api" :: "user" :: AsLong(id) :: _ XmlGet _ => <b>ID: {id}</b> 
    case "api" :: "user" :: AsLong(id) :: _ JsonGet _ => JInt(id) 
    } 
} 

Luego, en Boot.scala:

LiftRules.dispatch.append(MyRestService) 

Espero que esto ayude.

Cuestiones relacionadas