Upload
eduard-antsupov
View
255
Download
1
Embed Size (px)
Citation preview
В поисках идеалаОчередная белая презентация
Про что?
● Веб-фреймворки○ Scala
■ Предыстория■ Язык■ Lift■ Play!■ Akka■ Netty
○ Ruby■ On Rails■ On JVM
История (не ищите здесь PHP)
Что они нам дали?
● REST● MVC и MVVM● ORM и ODM● Migrations● Templating● Caching● Ajax и Comet● Testing● Deployment● Components● Performance● Scalability● Community
А ещё
● Производительность разработки● Понятность функционирования
приложения● Обучаемость● Поддерживаемость продукта● Рынок разработчиков
Тренды
● Browser Wars 3.0● Mobile First● SPA● Client frameworks● Cloud Infrastructure● NoSQL <-> SQL● Comet● REST API
○ Внешние API● Scalability● Performance● Big Data● HTML5
Scala
● Martin Odersky
● 2003 год
● Erlang, Haskell, Java, Lisp, Smalltalk
● .scala
Scala● Статическая строгая типизация
● Смешанная парадигма (ООП+Функциональная)
● JVM и .NET
● Сложная система типов
○ inference
● Scalable
○ explicit selftypes
○ abstract type members and generics
○ nested methods and classes
○ mixin composition using traits
○ dependency injection
Scala
● Всё является объектами
● def - начало определения метода
● Определение переменных начинается с ключевых
слов var или val
■ val array: Array[String] = new Array(5)
● Переменные определяются как имя:тип
● Точки с запятой необязательны
Scala - ООПclass Upper { def upper(strings: String*): Seq[String] = { strings.map((s:String) => s.toUpperCase()) }}
val up = new UpperConsole.println(up.upper("A", "First", "Scala", "Program"))
Scala - Functional// Функциональный литерал(s:String) => s.toUpperCase()
// Пример примененияobject Upper { def upper(strings: String*) = strings.map(_.toUpperCase())}
println(Upper.upper("A", "First", "Scala", "Program"))
// _ - это Placeholder-индикатор, можно представить как анонимную переменную, которая // принимает в качестве значения строки из map'a
Scala - Functionaldef factorial(i: Int): Int = { def fact(i: Int, accumulator: Int): Int = { if (i <= 1) accumulator else fact(i - 1, i * accumulator) } fact(i, 1)}def countTo(n: Int):Unit = { def count(i: Int): Unit = { if (i <= n) { println(i) count(i + 1) } } count(1)}countTo(5)
Scala - Type Inferenceimport java.util.Map;import java.util.HashMap;...Map<Integer, String> intToStringMap = new HashMap<Integer, String>();
import java.util.Mapimport java.util.HashMap...val intToStringMap: Map[Integer, String] = new HashMap
import java.util.Mapimport java.util.HashMap...val intToStringMap2 = new HashMap[Integer, String]
Scala - Type InferenceКогда нужно явно указать тип
1. При объявлении переменной, если при этом ей не присваивается
значение. (e.g., val name = "Programming Scala")
2. Для любого параметра метода. (e.g., def deposit(amount: Money)…)
3. Для возвращаемых значений метода в случае:
a. Когда вы явно вызываете return.
b. Когда метод рекурсивен.
c. При перегрузке метода, в случае если один вызывает другой.
d. В случае, когда возвращаемый тип является более общим, чем
вам нужно, e.g., Any.
Scala - Actors/package shapes { class Point(val x: Double, val y: Double) { override def toString() = "Point(" + x + "," + y + ")" }
abstract class Shape() { def draw(): Unit }
class Circle(val center: Point, val radius: Double) extends Shape { def draw() = println("Circle.draw: " + this) override def toString() = "Circle(" + center + "," + radius + ")" }
class Rectangle(val lowerLeft: Point, val height: Double, val width: Double) extends Shape { def draw() = println("Rectangle.draw: " + this) override def toString() = "Rectangle(" + lowerLeft + "," + height + "," + width + ")" }
class Triangle(val point1: Point, val point2: Point, val point3: Point) extends Shape { def draw() = println("Triangle.draw: " + this) override def toString() = "Triangle(" + point1 + "," + point2 + "," + point3 + ")" }}
Scala - Actorspackage shapes { import scala.actors._ import scala.actors.Actor._
object ShapeDrawingActor extends Actor { def act() { loop { receive { case s: Shape => s.draw() case "exit" => println("exiting..."); exit case x: Any => println("Error: Unknown message! " + x) } } } }}
Scala - Actorsimport shapes._
ShapeDrawingActor.start()
ShapeDrawingActor ! new Circle(new Point(0.0,0.0), 1.0)ShapeDrawingActor ! new Rectangle(new Point(0.0,0.0), 2, 5)ShapeDrawingActor ! new Triangle(new Point(0.0,0.0), new Point(1.0,0.0), new Point(0.0,1.0))ShapeDrawingActor ! 3.14159
ShapeDrawingActor ! "exit"
Play! 2
● Full-stack MVC фреймворк● Асинхронный● Событийно-ориентированный● Stateless● Type-safe● Масштабируемый● Open Source● Поддерживает Scala и Java
Play! 2
● Компиляция в реальном времени
● Интерактивная консоль
● Отображение ошибок в браузере и в консоли
● Db Evolutions ~= Миграции
● Компиляция всего
Play! - Web Architecture
Play! - Getting startedСпособ 1:
1. Скачать и распаковать Play
2. Добавить местоположение в переменную окружения
export PATH=$PATH:/relativePath/to/play
3. Скомандовать
play new myFirstApp
Play! - Getting startedСпособ 2 (предпочтительный):
1. Установить sbt (Scala Build tool) и добавить в project/plugins.sbt
// The Typesafe repository resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
// Use the Play sbt plugin for Play projectsaddSbtPlugin("play" % "sbt-plugin" % "2.1.0")
import sbt._import Keys._import play.Project._
2. В project/Build.scala добавитьobject ApplicationBuild extends Build { val appName = "My first application" val appVersion = "1.0" val appDependencies = Nil val main = play.Project( appName, appVersion, appDependencies ) }
3. Скомандовать sbt
Play! - Application layout
Play! - Конфигурация роутов
Play! - Валидация форм
Play! and Databases● Type-safe ORM
○ Slick (http://slick.typesafe.com/)■ Стабильная версия■ Начиная с Play! 2.1■ Хорошая документация
● ODM○ ReactiveMongo (http://reactivemongo.org/)○ Примеры приложений
■ Demo app: https://github.com/sgodbillon/reactivemongo-demo-app
■ Tailable cursor app: https://github.com/sgodbillon/reactivemongo-tailablecursor-demo
Play! Templating
● Scalate (http://scalate.fusesource.org/)○ Движок шаблонизатора
○ Поддерживает форматы шаблонов
■ Scaml (== Haml)
■ Jade (nodeJS Template engine)
○ Шаблоны хорошо переносятся между разными
фреймворками
○ Независим от фреймворка
○ Хорошо документирован
Play2 - Testing
● Specs○ specs2 (http://etorreborre.github.io/specs2/)
● Функциональное тестирование○ Свой движок (Coco)
○ Интеграция с Selenium WebDriver
■ https://github.com/FluentLenium/FluentLenium
Play! - Clients libraries
● Поддерживает CoffeeScript
● Поддерживает LeSS
● Поддерживает Bootstrap
Play! Akka
● Multicore, multiple nodes message passing● Software Transactional Memory (STM)● Non-blocking IO● Remote actors● Supervisor hierarchy
Что дальше?
● Advanced Scala○ Akka tricks
● Lift framework
● Play! framework examples, tips&tricks
● Ruby○ Rails
○ Sinatra
● Итоги