48
Язык программирования Scalа для создания успешных Интернет- проектов Успенский Владимир

Язык программирования Scala / Владимир Успенский (TCS Bank)

  • Upload
    ontico

  • View
    418

  • Download
    2

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Язык программирования Scala / Владимир Успенский (TCS Bank)

Язык программирования Scalа для создания успешных Интернет-проектов

Успенский Владимир

Page 2: Язык программирования Scala / Владимир Успенский (TCS Bank)

О нашем проектеСтарт — сентябрь 2011Запуск — май 2012Итого 9 месяцев

▶ Сразу лучший Интернет-банк в России▶ Хорошие отзывы клиентов▶ Бешенное развитие в течение года:

функционал, безопасность, интерфейс

и это не конец...

Page 3: Язык программирования Scala / Владимир Успенский (TCS Bank)
Page 4: Язык программирования Scala / Владимир Успенский (TCS Bank)
Page 5: Язык программирования Scala / Владимир Успенский (TCS Bank)

Общие слова о ScalaОдин из альтернативных языков на JVM,привносит функциональный подход

ООП и ФП дополняют друг друга

ООП чище чем в Java: все значения — объекты, все операции — вызов метода

Функциональный != Процедурный

Page 6: Язык программирования Scala / Владимир Успенский (TCS Bank)

Book

Итак, мы начинаем проект...

BookStore

sell

Author

Money accept

Придумаем модель предметной области:

Просто, правда?

has

Page 7: Язык программирования Scala / Владимир Успенский (TCS Bank)

Количество кода, обозримость

case class Money(amount: Long, currency: Currency)case class Author(name: String)case class Book(name: String, author: Author)

trait BookStore { def buy(bookName: String, money: Money): Book}

Чтобы иметь интерфейсы под рукой, можно объявить всё в одном файле:

Всё ещё просто!

Page 8: Язык программирования Scala / Владимир Успенский (TCS Bank)

Количество кода, обозримость

WAT?

Page 9: Язык программирования Scala / Владимир Успенский (TCS Bank)

Вывод типовMap<String, List<String>> booksAuthors =

new HashMap<String, List<String>>();

List<String> authors = new ArrayList(1);

authors.add("Herman Melville");booksAuthors.put("Moby-Dick", authors);

for(Map.Entry<String, List<String>> bookAuthors :

booksAuthors.entrySet()) {String book = bookAuthors.getKey();String authors = bookAuthors.getValue();...

}

Page 10: Язык программирования Scala / Владимир Успенский (TCS Bank)

Вывод типов

val booksAuthors = Map("Moby-Dick" ->List("Herman Melville"))

for((book, authors) <- booksAuthors) {...

}Ничего лишнего!

Page 11: Язык программирования Scala / Владимир Успенский (TCS Bank)

Коллекции

val somethingToRead = books.filter(isPhysics) .groupBy(_.author).map({ case (author, books) => books.sortBy(rating(author)).head }).headOption

Console.print(somethingToRead.firstPage)

Стандартные методы на все случаи жизни:

Page 12: Язык программирования Scala / Владимир Успенский (TCS Bank)

Коллекции

val somethingToRead = books.filter(isPhysics) .groupBy(_.author).map({ case (author, books) => books.sortBy(rating(author)).head }).headOption

Console.print(somethingToRead.firstPage)

Стандартные методы на все случаи жизни:

Page 13: Язык программирования Scala / Владимир Успенский (TCS Bank)

Коллекции

val somethingToRead = books.filter(isPhysics) .groupBy(_.author).map({ case (author, books) => books.sortBy(rating(author)).head }).headOption

Console.print(somethingToRead.map(_.firstPage) .getOrElse("Nothing is there!"))

Стандартные методы на все случаи жизни:

Page 14: Язык программирования Scala / Владимир Успенский (TCS Bank)

JSONcase class Address(street: String, city: String)case class Person(name: String, address: Address)

val json = parse("""{ "name": "joe", "address": { "street": "Boulevard", "city": "Helsinki" } }""")

assert (json.extract[Person] == Person(joe, Address("Buolevard", "Helsinki"))

(Scala 2.10, Json4s)

Page 15: Язык программирования Scala / Владимир Успенский (TCS Bank)

XMLval xml = <root><tag attr="value">text</tag></root>

val xml = XML.loadString("""<root> <tag attr="value">text</tag> </root>""")

XPathassert ((xml \\ "tag").text == "text")assert ((xml \\ "tag" \ "@attr").text == "value")

Page 16: Язык программирования Scala / Владимир Успенский (TCS Bank)

Pimp my library!

import ru.tcs.db.extensions._

val userId = resultSet.getId[User]("user_id")// userId: Id[User]

val balance = resultSet.getMoney("balance")// balance: MoneyAmount

Берём обычный java.sql.ResultSet

Retroactive extension для любого типа!

Page 17: Язык программирования Scala / Владимир Успенский (TCS Bank)

Абстракция▶ Способность находить и описывать общее, чтобы

- экономить время, переиспользуя, или при правках - и недопускать разного поведения и ошибок

▶ Обычно применяются: наследование, параметризация, параметризация типа (generics)

▶ Замыкания и функции над функциями позволяют параметризовать код другим кодом,давая доступ к новому механизму абстракции

Page 18: Язык программирования Scala / Владимир Успенский (TCS Bank)

Функции высшего порядка

// где-то в определениии Iterable[T]...

def filter(predicate: T => Boolean):Iterable[T]

def map[A](transform: T => A): Iterable[A]

Операции с коллекциями так удобно использовать, как раз потому, что стандартные функции можно параметризировать своим поведеднием

Page 19: Язык программирования Scala / Владимир Успенский (TCS Bank)

Примеси/Mixinsclass Animal

trait Philosophical { def philosophize() { Console.println(

"It ain't easy being " + toString) }}

class Frog extends Animal with Philosophical { override def toString = "green"}

new Frog().philosophize()// It ain't easy being green

Помогают выносить общий функцинал без недостатков множественного наследования

Page 20: Язык программирования Scala / Владимир Успенский (TCS Bank)

Higher Kinds

trait Factory[T] { def create(): T}

Параметр типа первого порядка:

trait Functor[H[_]] { def map[A,B](fn: A => B)(fa: H[A]): H[B]}

Параметр типа высшего порядка:

Page 21: Язык программирования Scala / Владимир Успенский (TCS Bank)

Корректность и тотальностьВсё никогда не бывает хорошо

"A good programmer is someone who looks both ways before crossing a one-way street." ~ Doug Linder

Тотальность — свойство программы, быть определённой для всех входных параметров

Scala использует типизацию (type-safety) для проверки корректности при компилляции, где это возможно

Page 22: Язык программирования Scala / Владимир Успенский (TCS Bank)

Маленький мотивирующий примерBook book = bookShelf.get("Moby-Dick");Reader reader = readersQueue.peek();

if(reader.favorite.equals(book.author)) {reader.read(book);

}

Page 23: Язык программирования Scala / Владимир Успенский (TCS Bank)

Маленький мотивирующий примерBook book = bookShelf.get("Moby-Dick");Reader reader = readersQueue.peek();

if(reader.favorite.equals(book.author)) {reader.read(book);

}

Значения может просто не быть!

Если значение необязательно, лучше предусмотреть это в модели типов

Page 24: Язык программирования Scala / Владимир Успенский (TCS Bank)

Маленький мотивирующий примерval book: Option[Book] = bookShelf.get("Moby-Dick")val reader: Option[Reader] = readersQueue.peek

if(reader.favorite.equals(book.author)) {reader.read(book)

}

Теперь программа просто не собралась

Разработчик узнал об ошибках сразу, до передачи в тестирование или переноса в бой

Page 25: Язык программирования Scala / Владимир Успенский (TCS Bank)

Управление непредвиденнымПри выполнении вычислений возможно:

Возможностью таких исходов можно управлятьс помощью типа возвращаемого значения.

Такие значения можно создавать и связывать.Тип вместе с операциями называется Монадой.

▶ ничего не получить, — Option▶ получить исключение, — Try▶ занимать время, — Future▶ работать с диском — IO

etc.

Page 26: Язык программирования Scala / Владимир Успенский (TCS Bank)

Более строгие ограничения на типы

▶ Параметр типа обязательно должен бытьВсегда List[T], но не List

▶ Higher KindsНе надо переходить к Object

▶ ВариантностьНе обязательно переходить к List[_]

Page 27: Язык программирования Scala / Владимир Успенский (TCS Bank)

Вариантность

case class Invariant[T]() case class Covariant[+T]() case class Contravariant[-T]()

val in: Invariant[Object] = Invariant[String] val in: Invariant[String] = Invariant[Object] val co: Covariant[Object] = Covariant[String] val co: Covariant[String] = Covariant[Object] val contra: Contravariant[Object] = Contravariant[String] val contra: Contravariant[String] = Contravariant[Object]

Scala позволяет указать вариантность для параметров типа:

Page 28: Язык программирования Scala / Владимир Успенский (TCS Bank)

Immutability

▶ Возможность изменения выбирается явно:

▶ Коллекции по умолчанию immutable

val immutable = ...var mutable = ...

List, Set, Map,

▶ Immutability — невозможность изменить объект или ссылку после создания.

есть также mutable версии

Page 29: Язык программирования Scala / Владимир Успенский (TCS Bank)

Достоинства Immutability

▶ Меньше ошибок из-за переиспользования переменных для разных целей

▶ Операции проще и однороднее:нет особенностей, связанных с изменением

▶ Просто работать в многопоточной среде,нет расходов на синхронизацию,возникающих из-за concurrent mutable state

Page 30: Язык программирования Scala / Владимир Успенский (TCS Bank)

Адаптация к изменениям

Когда, проект запущен

Клиенты начали пользоваться и писать отзывы

Бизнес хочет зарабатывать на продукте

А несколько раз в год, запускаются крупные проекты

Вам нужно быть очень гибкими!

Page 31: Язык программирования Scala / Владимир Успенский (TCS Bank)

Адаптация к изменениямЕсли приходится что-то серьёзно менять, когда меньше кода, лучше видны последствия, а, благодаря типам, изменения ещё и проверяются компиллятором — меньше вероятность сломать.

Выше уровень абстракциии и однородный код — нет необходимости влезать в низкоуровневые детали реализации, можно охватить больше случаев меньшими усилиями.

Page 32: Язык программирования Scala / Владимир Успенский (TCS Bank)

Группировка запросов и параллельная обработкаЗадача: «Сделать возможность параллельной обработки запросов, когда все запросы обработаны, нужно собрать результаты»

Page 33: Язык программирования Scala / Владимир Успенский (TCS Bank)

Группировка запросов и параллельная обработка

ThreadPool? CyclicBarrier?

CountDownLatch?

Задача: «Сделать возможность параллельной обработки запросов, когда все запросы обработаны, нужно собрать результаты»

Похоже,это сложная

задача!

Page 34: Язык программирования Scala / Владимир Успенский (TCS Bank)

Группировка запросов и параллельная обработка

val responses = requests.par.map(processRequest).seq

Задача: «Сделать возможность параллельной обработки запросов, когда все запросы обработаны, нужно собрать результаты»

Page 35: Язык программирования Scala / Владимир Успенский (TCS Bank)

Нужно собирать информацию со множества бекендов

Продукты

CRM

Операционные данные

Предложения

Page 36: Язык программирования Scala / Владимир Успенский (TCS Bank)

Нужно собирать информациюсо множества бекендов

Продукты

CRM

Операционные данные

Предложения

Очень долго!

Page 37: Язык программирования Scala / Владимир Успенский (TCS Bank)

Нужно собирать информацию со множества бекендов

Продукты

CRM

Операционные данные

Предложения

Отлично!

Page 38: Язык программирования Scala / Владимир Успенский (TCS Bank)

Нужно собирать информацию со множества бекендов

Продукты

CRM

Операционные данные

Предложения

Отлично!

ThreadPool? CyclicBarrier?

CountDownLatch?

Похоже это сложная задача!

Мне нужно несколько дней!

Page 39: Язык программирования Scala / Владимир Успенский (TCS Bank)

Нужно собирать информацию со множества бекендов

Распараллелить долгие вызовы для одного, не самого простого, случая удалось за 30 минут

val (operations, offers) = Await.result( future { operationsRepo.readOperations(userId) } zip future { offersRepo.readOffers(userId) }, 60 seconds)

Page 40: Язык программирования Scala / Владимир Успенский (TCS Bank)

Расширение команды

Новые сотрудники втягиваются за пару недель: - всё не так сильно отличается,- меньше кода и неявных контрактов

почти за два года команда

люди менялись в процессе

выросла почти с нуля,

Page 41: Язык программирования Scala / Владимир Успенский (TCS Bank)

Недостатки▶ Есть неочевидные местаx

Надо читать документацию и писать тесты

▶ Длинные цепочки вызовов тяжело отлаживать,что заставляет выносить переменные и разделять код на небольшие методы

Page 42: Язык программирования Scala / Владимир Успенский (TCS Bank)

Недостатки▶ Есть неочевидные местаx

Надо читать документацию и писать тесты

▶ Длинные цепочки вызовов тяжело отлаживать,что заставляет выносить переменные и разделять код на небольшие методы

Что? тесты и небольшие методы? да ладно!

Page 43: Язык программирования Scala / Владимир Успенский (TCS Bank)

Недостатки▶ Есть неочевидные местаx

Надо читать документацию и писать тесты

▶ Длинные цепочки вызовов тяжело отлаживать,что заставляет выносить переменные и разделять код на небольшие методы

▶ Ограниченная поддержка генерации кода в IDE,впрочем генерировать код не очень актуально

▶ На рынке не так много специалистов по Scala,приходится искать заинтересованных ребят,которые хотят делать что-то новое

Page 44: Язык программирования Scala / Владимир Успенский (TCS Bank)

▶ Та же платформа

▶ Те же среды разработки

▶ Та же релизная политика

▶ Доступен код на Java, все библиотеки JVM, старое доброе ООП и императивность

мало того, с этого стоит начать

Перейти просто

администраторам всё знакомо

не нужны новые лицензии

тестировщики и администраторы в покое

если что, всегда есть к чему вернуться,

Page 45: Язык программирования Scala / Владимир Успенский (TCS Bank)

Итог▶ Проще код

▶ Меньше ошибок

▶ Меньше времени на типовые вещи

▶ Простая работа с потоками

▶ Просто поддерживать рост

▶ Легко попробовать и перейти

Page 46: Язык программирования Scala / Владимир Успенский (TCS Bank)

Итог

Scala — отличный инструментдля успешного проекта!

scala-lang.org/downloads

Page 47: Язык программирования Scala / Владимир Успенский (TCS Bank)

scala> questions

Page 48: Язык программирования Scala / Владимир Успенский (TCS Bank)

e-mail: [email protected]: tcs_uspenskiy