Паттерны, архитектура ПО при использовании Scala
От: Аноним  
Дата: 03.07.08 09:45
Оценка:
Существует ли в природе описание паттернов, техник проектирования в контексте Scala ? На сайте Scala рассмотрены только неск. простейших паттернов.
Re: Паттерны, архитектура ПО при использовании Scala
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 05.07.08 11:48
Оценка: 4 (1)
Аноним,

А>Существует ли в природе описание паттернов, техник проектирования в контексте Scala ? На сайте Scala рассмотрены только неск. простейших паттернов.


Мартин утверждает, что в Скале лучше всего делать высокоуровневые объекты в соответствии с декомпозицией на объекты и обобщая классы до трейтов (и возможно, параметризуя их и выделяя зависимые типы). Набор методов в трейтах необязательно должен быть минимальным. Подход на самом деле немного отличается от "интерфейсного" подхода (оригинальная статья [url=http://www.iam.unibe.ch/~scg/Archive/Papers/Scha03aTraits.pdf]Traits: Composable Units of Behaviour[url]). Реализацию по-возможности делать в функциональном стиле, то есть использовать алгебраические типы данных, а методы в классах будут оперировать над этими АТД. Передачи интерфейсов и всяких коллбэков по-возможности заменять на ФВП.

Я приведу пример, который можно найти в стандартной библиотеке, маленький, но тем не менее общий. Трейт InputChannel описывает нечто, что умеет принимать сообщения, трейт OutputChannel описывает нечто, что умеет отправлять сообщения. Они определены как
trait InputChannel[+Msg] {
  // получить сообщение
  def receive[R](f: PartialFunction[Msg, R]): R
}
trait OutputChannel[-Msg] {
  // отправить сообщение
  def !(msg: Msg): Unit
}

(в этих трейтах конечно ещё есть методы, но это неважно). Теперь сущность, которая умеет принимать и отправлять сообщения можно описать как
// используется в методе Channel.!
// ещё один ! определён в классе Actor
case class ! [a](ch: Channel[a], msg: a)

class Channel[Msg] extends InputChannel[Msg] with OutputChannel[Msg] {
  private var recv: Actor = {...}

  // конструктор
  def this(recv: Actor) = {
    this()
    this.recv = recv
  }
...
  def !(msg: Msg) {
    recv ! scala.actors.!(this, msg)
  }
...
  def receive[R](f: PartialFunction[Msg, R]): R = {
    val C = this.asInstanceOf[Channel[Any]]
    recv.receive {
      case C ! msg if (f.isDefinedAt(msg.asInstanceOf[Msg])) => f(msg.asInstanceOf[Msg])
    }
  }
...
}

Теперь этот класс можно инстанцировать и использовать
    val channel = new Channel[Any](anActor)
    channel ! "message"
    channel receive {
      msg => Console.println(msg)
    }

Как видишь, здесь присутствует как-бы множественное наследование. На самом деле конечно просто mixin composition, с последним, в отличие от МН проблем бы не возникло даже, если бы receive и ! имели реализации в трейтах InputChannel & OutputChannel соответственно.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
scala patterns
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.