Как реализовать каталог / реестр, соблюдая неизменность и "правила" функционального программирования?
Folks,
Каков наиболее подходящий способ для реализации реестра, как
trait Registry {
def registerComponent( name: String, obj : Any ) : Unit
def getComponent( name: String ) : Any
def unregisterComponent( name: String ) : Unit
}
следующие функциональные схемы. (Например, неизменность и т. Д.)
Что приходит мне в голову здесь
- State-Monad: где состояние монады представляет зарегистрированные объекты (как
Seq
или похожие) - Builder- (like) -Pattern, но с копированием текущего контекста реестра с одного этапа построения на следующий.
Например: реестр по образцу, похожему на построитель:
case class Registry(registered: Map[String, Any]) {
def register( name: String, obj: Any ) : Registry = {
copy( registered = this.registered + ( name -> obj) )
}
def unregister( name : String ) : Registry = {
copy (registered = this.registered.filterKeys( !_.equals(name)))
}
// How to deal with return values????
// Tuple return is quite ugly
//
def getComponent( name: String ) : (Registry, Option[Any]) = {
(this, registered.get( name ) )
}
}
Какие другие решения / модели являются разумными или доступными?
Ура,
Мартин
1 ответ
State Monad выглядит как наиболее подходящая вещь, если вы хотите сохранить реестр в памяти. Он будет похож на ту реализацию Builder, которую вы написали, но передаст контекст / реестр более функциональным или менее синтаксически шумным способом.
Если вы хотите перенести побочные эффекты на границы вашей программы, но при этом они сохраняются, например, сохранение реестра в базе данных или какая-либо изменяемая структура, тогда вы можете использовать Reader Monad.
Вот ссылка на хорошую статью о Scalaz, которая сначала обсуждает проблему состояния, а затем показывает, как использовать государственную монаду.