Комментарии 29
Хорошая статья. Написано очень дружелюбно для Java-разработчиков — это не частое свойство статей по scala.
Но вставлю пару уточнений:
1. Адаптер:
Обычно так не делают. Используют объект типа Logger (
Если чуть изменить объявление
2. Объект-значение (Value object)
Не лучший пример. Наследование при использовании паттерна объект-значение крайне затруднительно независимо от языка. А scala обычно используют ADT где можно.
3. Null объекты (Null Object)
Автор предупредил, что не будет использовать сложные конструкции, но все-таки чтоб снять обвинение в многословности
Но вставлю пару уточнений:
1. Адаптер:
val log: Log = new Logger()
Обычно так не делают. Используют объект типа Logger (
val log = new Logger()
) и прямо на нем вызывают методы из Log
.Если чуть изменить объявление
LoggerToLogAdapter
, то его экземпляр не будет создан вообще, даже для вызова его методов.2. Объект-значение (Value object)
В добавок, case-классы являются валидными классами, а значит с ними можно работать как с обычными классами (например, наследоваться от них).
Не лучший пример. Наследование при использовании паттерна объект-значение крайне затруднительно независимо от языка. А scala обычно используют ADT где можно.
3. Null объекты (Null Object)
Автор предупредил, что не будет использовать сложные конструкции, но все-таки чтоб снять обвинение в многословности
Option
покажу как его в данном случае будет использовать любой, кто пишет на scala больше недели:for (sound <- SoundSource.getSound) {
sound.play()
}
// аналогично
SoundSource.getSound.map{ _.play }
+1
Про последний пример: мне кажется, если play возвращает Unit, лучше foreach, а не map использовать. Да и вообще во всех случаях, когда мы не планируем использовать возвращаемое значение.
+1
// аналогично SoundSource.getSound.map{ _.play }
Вы слегка ошиблись. Аналогично будет
SoundSource.getSound.foreach(_.play)
Нам же не нужно здесь коллекцию
Unit
ов строить)Всегда буду обновлять комментарии, всегда буду обновлять комментарии...
0
Если не ошибаюсь, то foreach в кишках эту же коллекцию и делает.
0
«for» без «yield» сделает foreach
«for» с «yield» сделает map
«for» с «yield» сделает map
0
Нет, не делает.
foreach
для Iterable
просто перебирает итератор, как обычный джавовский цикл for
. map
же в обязательном порядке создаёт коллекцию — он принимает неявным аргументом CanBuildFrom
, который используется для конструирования той же коллекции, как та, на которой map
вызван.0
Зря вы так про «любой, кто пишет на scala больше недели». Я вот скалашный for-синтаксис не люблю (то это map, то это foreach). Мне намного приятнее читать цепочку вызовов map, чем многострочный for. Опять же, то мне map нужен, то flatMap. И ещё мне не нравится что при чтении for-expression приходится постоянно читать то слева направо, то справа налево. Вот в вашем же примере:
SoundSource.getSound.foreach(sound => sound.play() ) // всё слево направо
А уж тем более проще
<source lang=«scala>
SoundSource.getSound.foreach(_.play() )
SoundSource.getSound.foreach(sound => sound.play() ) // всё слево направо
А уж тем более проще
<source lang=«scala>
SoundSource.getSound.foreach(_.play() )
+1
Блин, код попортился:
Вот в вашем же примере:
Вот так читабельнее:
А уж тем более проще
Вот в вашем же примере:
for (sound <- SoundSource.getSound) { // Справа налево. SoundSource.getSound - начало выражения, sound - конец
sound.play() // Слева направо
}
Вот так читабельнее:
SoundSource.getSound.foreach(sound => sound.play() ) // всё слево направо
А уж тем более проще
SoundSource.getSound.foreach(_.play() )
0
Я, похоже, непонятно выразился.
Это код из статьи:
А вот это то, что по моему мнению будут все использовать в данном случае:
Почему map вместо foreach я ответил выше (в демонстративных целях).
Это код из статьи:
for (sound <- SoundSource.getSound) {
sound.play()
}
А вот это то, что по моему мнению будут все использовать в данном случае:
// аналогично
SoundSource.getSound.map{ _.play }
Почему map вместо foreach я ответил выше (в демонстративных целях).
0
Если речь идёт о работе с коллекциями, то я с вами соглашусь – не всё так однозначно какой синтаксис более удобен. Но если речь о других типах, обладающих свойствами монада, то именно спец. синтаксис в виде «for» раскрывает всю красоту подхода. Для фьючеров, например, for-синтаксис намного более прозрачный, чем цепочки флэтмапов.
+1
но ведь
я предпочитаю
map
и for
не сработают, если там None
.я предпочитаю
someOpt.fold(defaultValue) {smthn => smthnWithSameTypeAsDefaultValue}
0
В статье и предполагается, что при
И да, я
None
ничего делать не надо.И да, я
fold
не люблю. Предпочитаю map
+ getOrElse
. Читается лучше.0
ну тут фломастеры разные. по мне так
ирл зачастую приходится все же предпринимать какие-то действия в зависимости от того, пустой
fold
более кратокирл зачастую приходится все же предпринимать какие-то действия в зависимости от того, пустой
Option
или нет.0
кстати, в примере на джабахе все же вызывается
так что это сравнение выходит не особо идентичным, что может некоторых смутить в начале пути.
play
, пусть и пустой, но вызов происходит. может я завтра туда запихну заглушку какую или логгер.так что это сравнение выходит не особо идентичным, что может некоторых смутить в начале пути.
0
А что такое «обобщённое назначение», и почему это минус?
+1
Зря написали про отсутствие минусов у кортежей и case-классов. Периодически спотыкаюсь на ограничение в 22 члена класса. Обычно при написании классов для ORM и других DTO.
Ещё не совсем удачно написан минус к декораторам, что в trait'ы нельзя передавать параметры конструктора. Фактически можно:
Ещё не совсем удачно написан минус к декораторам, что в trait'ы нельзя передавать параметры конструктора. Фактически можно:
trait Buffering extends OutputStream {
def bufferSize: Int
abstract override def write(b: Byte) {
// ... buffer for bufferSize bytes
super.write(b)
}
}
new FileOutputStream("foo.txt") with Buffering { val bufferSize = 12 }
+2
Ограничение у case-классов в 22 члена пофиксано в Scala 2.11. А вот зачем в кортежах >22 членов — не очень понятно. Опишите пример из жизни?
0
сразу вспомнил slick и его *
slick.typesafe.com/doc/2.0.0/gettingstarted.html#schema
хотя мне никогда не нравился этот инструмент
slick.typesafe.com/doc/2.0.0/gettingstarted.html#schema
хотя мне никогда не нравился этот инструмент
+1
Собственно именно это и было единственным примером из жизни в моём случае. Сейчас используем Squeryl.
0
Для преодоления ограничения в 22 члена можно использовать HList: stackoverflow.com/questions/20555304/how-can-i-use-the-new-slick-2-0-hlist-to-overcome-22-column-limit
0
Я довольно много пишу на Scala. Сравнение прикольное, но сложилось впечатление, что автор намеренно описал только те паттерны, где у Scala есть либо красивый встроенный синтаксический сахар, либо возможности, которых нет в Java. А так +1.
0
Остальные паттерны в scala хуже реализовываться точно не будут. Так что зачем показывать те, что реализовываются так же или те, для описания которых требуется много кода.
На самом деле почти все можно на скале сделать лаконичнее при помощи DSL, но не всегда это оправдывает написание отдельного DSL.
На самом деле почти все можно на скале сделать лаконичнее при помощи DSL, но не всегда это оправдывает написание отдельного DSL.
0
Предпочитаю в качестве адаптера использовать неявную функцию преобразования, но данное решение наиболее подходит если оба трейта или класса имеют реализации методов
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Классические паттерны проектирования на Scala