Диспетчерские функции - PullRequest
6 голосов
/ 18 мая 2010

Что такое диспетчерские функции? Я гуглил их, и все расплывчато. Они кажутся просто вложенными блоками / замыканиями внутри других функций? Говоря из точки скала / лифта ... но я предполагаю, что это универсально, я видел, что они также упоминаются в рубине.

Ответы [ 2 ]

7 голосов
/ 18 мая 2010

Цель диспетчеризации - динамически решать, что делать в вашей функции.

Когда у вас есть (динамическая) диспетчерская функция, ее главная (или единственная, если вам не нужна приведение или другие преобразования) задача - решить, какую другую функцию вызвать. Решение часто основывается на типе экземпляра, к которому вызывается метод, или типе некоторых параметров, но оно также может зависеть, например, от на значение параметра (ов), или некоторые значения конфигурации.

Правило диспетчеризации может быть жестко задано (с использованием, например, сопоставления с образцом в scala) или может быть получено из таблицы диспетчеризации.

Как вы упомянули, есть несколько вариантов, например, одиночная отправка (конкретный метод зависит от экземпляра, в котором вызывается исходный метод, который является базовым механизмом OO), двойная диспетчеризация (отправляет вызов функции различным конкретным функциям в зависимости от типы времени выполнения нескольких объектов, участвующих в вызове). * +1007 *

Связанный шаблон проектирования - Visitor, который позволяет динамически добавлять набор функций к существующим классам и который также имеет динамическую диспетчеризацию в своей основе.

Вложенные блоки / замыкания появляются, когда вы определяете конкретный метод внутри метода отправки или в некотором коде инициализации (например, для таблицы отправки).

Простой пример для случая, когда диспетчеризация основана на значении параметра, с жестко заданным решением и с таблицей диспетчеризации:

   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 голосов
/ 18 июня 2010

Отправка - это термин, используемый Lift для отправки запросов веб-служб.

Самый простой способ определить функцию отправки с помощью RestHelper (см. http://www.assembla.com/wiki/show/liftweb/REST_Web_Services)

Например:

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

Затем в Boot.scala:

LiftRules.dispatch.append(MyRestService)

Надеюсь, это поможет.

...