by shigemk2

当面は技術的なことしか書かない

まとめ Refactoring in Scala #ScalaMatsuri #sm_a

@gakuzzzz

Tech to Value

Professional Null Cleanerと呼ばれるなど

値の型について

" DDDではValue Object " Scalaの表現力

case classとかtraitとか定義してる例があって、ビジネスロジックが定義されている

case class Board
case class User

このコードには問題がある。

  • Map[Long, User] は意味情報としてたいして情報が読めない(何を意味しているのか分からない)
  • 引数を間違えてもコンパイルエラーにならない(実行時例外を投げる可能性が高い)

ゆえに、怖いコードである

最初のアプローチ

type aliasを使う 型の別名

package object models {
  type UserId = Long
  type GroupId = Long
  .....
}

型の別名を使うことで、何の情報なのかコードを見て意味通りにすることが出来る

  • Map[UserId, User]→Clear semantics
  • 物理表現の変更が簡単(全部Longだと型を別のに修正しようとするときに大変)
type UserId = String

でも、引数ミスをコンパイルエラーで弾けない

次のアプローチ

Tagged Type

型にラベルをつける仕組み Scalaz/shapelessなどで提供 型引数をふたつとる型は中置記法 中置記法のための@@

type Tagged[A, T] = {type Tag = T, type Self = A}
Map[Id @@ User, User]

Tagged Typeをつかうと、@@などが使える

  • コードの意味も明白になる
  • ミスしてもコンパイルエラーになる
  • バイトコードとしてのキャストになるのでwrap/unwrapもない

注意

AnyVal(Javaだとプリミティブになるやつ)と使うとBoxing/Unboxingが起きる

次のアプローチ その2

  • Value Class
  • メモリ割り当てを削減したいときに使える
class UserId(val value: Long) extends AnyVal

http://docs.scala-lang.org/ja/overviews/core/value-classes.html

  • Map[UserId, User]になるので、意味も明白かつコンパイルエラーも弾きやすい
  • コンパイル時にinline展開してくれるので、wrap/unwrapのコストもかからない

" 間違えてメモリ割り当てされる場合がある * 値クラスが別の型として扱われるとき * 値クラスが配列に代入するとき * パターンマッチングで実行時の型検査をおこなうとき

Tagged TypeとValue Classどちらを使うべきか

自分のプロジェクトで状況に合わせてつかうべき

  • Tagged Type コンテナタイプのキャストをサポート(Value Classだとめんどい)
  • Value Class メソッド定義の追加が簡単(Tagged Typeだとめんどい)

UserId/BoardIdとかいろいろ書くのめんどくさい

次のアプローチ

  • Phantom Types
    • 値に使用されない型引数を使って制約を表現する手法 " コンパイルすると幽霊のように消える

https://www.google.co.jp/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=phantom%20types

まとめ

  • 実際の物理表現と意味表現を分離(エイリアス)
  • 間違いの検出しやすく(Tagged Typeと値クラス)
  • ジェネリクスでボイラーテンプレートをなくす(幽霊型)

  • 新しい問題 WebフレームワークとかRDB操作ライブラリなどの外部のライブラリは自分たちのオレオレ定義の型の情報を知らない
  • レイヤー境界で型変換する必要があるんだけど
  • これを手書きしてるとしんどい

これの改善が次の課題

メジャーなフレームワークは境界に型変換する機能がある

  • Play(Formatter)/Skinny/Slick(ColumnType)/ScalikeJDBC
  • 今使っているライブラリにこの機能がない場合はPRを投げるかそのプロジェクトから逃げよう
    • たとえばLongからId型への変換が自動的にフレームワーク側で行われる
  • IdとかNameとかはドメインのオブジェクト(層の責務/レイヤーわけに失敗してる)

次のアプローチ

Iso(あいそもーふぃーずむ)とPrismを使おう

Iso

  • Isomorphism ふたつの型が完全に相互変換可能なことをあらわす
    • from(to(a)) == a
    • to(from(b)) == b

Prism

  • Isoに似ているが、片方の変換が必ず成功する(失敗する可能性)とは限らない
    • from(to(a)) == a
    • to(from(b)) == b

http://the.igreque.info/posts/2015-06-09-lens-prism.html

  • Prismは生成に制約があるような値型で利用する
  • IsoはPrismのサブクラスにすることが出来る

IsoであればPrismになることが出来る

  • Iso/Prismはシンプルなやつなので、Monocleやshapelessなどのライブラリで提供されている
  • 自分でつくってもいいし、こういったライブラリを使ってもいいでしょう
  • IsoはScalazでも導入されている

  • Iso/Prismはレイヤー/アーキの表現に依存しないのがアドバンテージ。

  • ドメイン層の責務を破る心配はない

  • Prismを使って変換するのがよい

  • Iso/Prismだけを提供すれば全てのライブラリに対応できる
  • でも手書きするとボイラープレートになってしんどい

そこでimplicit macroを使用することでIsoの定義を簡略化できる implicit macroのドキュメントの具体例がIsoそのもの Scala 2.11/2.12はmacroはexperimentalな機能なので長いプロジェクトではちょっと考えるべき

まとめ

  • レイヤー境界ではフレームワーク/ライブラリに応じた変換処理
  • Iso/Prismを使ってコードの依存性を下げる DRYに出来る
  • マクロを使って定義のボイラーテンプレートをなくせる

資料

http://gakuzzzz.github.io/slides/refactoring_in_scala/

宣伝
  • Tech to Valueではこんな感じのコードレビューをオンラインでサービスとしてやっている

その他

幽霊型 http://akabe.github.io/2015/12/PhantomTypeTricks/

質疑

  • TypeAlias こんかいやりたかったのはPublicなやつであって、Path依存型の話になると面倒
  • TypeProjectionをつかうとさらに読みづらい

まとめ

  • DDD
  • Iso/Prism/Lens

まとめ なぜリアクティブは重要か #ScalaMatsuri #sm_a

@okapies

将来的にはScalaで仕事したい

スライド

  • finagle-kafka
  • sircuit
  • rx-process

など

  • ブログ記事とか翻訳とかやっている
  • 今回はプログラミング寄りの話はしない

近年のソフトウェア開発の課題

  • 非同期プログラミング
  • イベント駆動
  • 並行並列処理
  • スケーラビリティ
  • 耐障害性

なんでもリアクティブで解決しようというソリューション

  • フロントエンドからバックエンドまでリアクティブがキーワードになってる(というかバズワードになりつつある)
  • Reactive Programming Stream Manifestなど似たような言葉がホイホイ出てくる
    • マイクロサービス 例 ふたつのマイクロサービスへの非同期クエリを束ねて出力 けっこうたいへん
    • ビッグデータ処理 Hadoop Sparkなど
    • JDK9におけるReactive Streams

What is Reactive?

  • Programming model
  • Runtime engine
  • Architecture

文脈によって意味がぜんぜんちがう

重要なのはこの2つ。

  • Reactive component
  • Reactive data flow

Programming Model

  • 問題 イベント処理 並行並列処理を楽にしたい
  • 非同期処理といえばコールバックなんだけど
    • なんでそれを使わないのか
    • コールバックヘル(モジュール化しにくい/データの依存/実行順序の制御が困難)
      • 例のピラミッド

Reactive Component

  • コンポーネントの内部状態を互いに隔離
  • 独立したライフサイクルをもっているので非同期処理にむいている
    • すべてのinが一つの方向に集約している
  • 状態と時間の問題をReactive Componentで解決しうる
  • コンポーネントのなかでエラーが発生しても他のコンポーネントに波及しないのもメリット

Reactive Programming

  • 実行順序の問題
  • 説明 https://en.wikipedia.org/wiki/Reactive_programming
  • データの有向グラフ
  • 命令型のプログラミングが主流のプログラマにとって、データの有向グラフはわかりづらい
  • 命令型の実行モデルではCを計算したあとにAを変更してもなにもおきない
  • リアクティブな実行モデルではCを計算したあとにAを変更したらCの値が再計算される
  • リアクティブプログラミングというと、関数型の概念が取り込まれることが多い

突然の関数型

ここの論文が詳しい http://worrydream.com/refs/Hughes-WhyFunctionalProgrammingMatters.pdf

Why Functional Programming Matters

  • 一番重要なのはモジュール性の向上がFPにとって重要
  • モジュール化のための「糊」としての、遅延評価と高階関数
  • 問題を分割する方法は解を貼り合わせること

無限数のFizzBuzzの例

  • 遅延評価を利用することで、欲しいものが欲しいだけできる 生成器と選択器
  • 高階関数で関数に関数を渡すことで、ビジネスロジックとデータ型の文脈を分離(データ構造を関数に押し込められる)

Adopting FP glues to RP

FRPがはやるりゆう

  • 非同期イベントを生成器/選択器で少しずつ処理
  • ビジネスロジックを非同期イベントの挙動と分離
    • map/zipでビジネスロジックをパイプライン化できる
  • 実行モデルとデータを分離できる
    • WhatをDSLで記述しHowをランタイムで実行する
  • リアクティブにはプログラミングモデルとランタイムには密接な関係がある

マルチプラットフォーム性 (Portability)

  • リアクティブなプログラムは様々なアーキ上でマッピングできる

    • 書いたデータフローをランタイムが最適化できる
    • いろいろなことをランタイムで最適化できる(机上の空論のように見える?やってるんですよ)
  • (Fusing) 複数の処理ステップをひとつにまとめる融合機能

  • データフローDSLとランタイムの組み合わせは近年様々な分野で適用されている
    • TensorFlowなどはリアクティブなアーキ
    • Hadoop以降はだいたいこのような考え方で実装されている

まとめ 1

  • リアクティブなコンポーネントとイベント駆動
  • 並行並列処理も解決しうる

  • 最近は分散処理の必要性が高くなってきてる
    • 耐障害(落ちても動かす)
    • スケール(拡大)
    • マイクロサービス

Reactive Manifesto

  • 4つのアーキのなかで非同期メッセージ駆動がじゅうよう
  • responsive elastic resilient message-driven

  • バイナリ境界で隔離されたコンポーネント同士がメッセージのみでやりとり

  • メッセージ駆動で弾力性とレジリエンスを達成
    • あるコンポーネントがクラッシュしても非同期バイナリ境界で句切られているので他のコンポーネントに波及しない(let it crash) など

疑問

  • Reactive Systemはどう実現するのか
    • Manifestにも実際にはかいていなくて実装方法は議論して っていうスタンス

MicroService Architecture

  • 巨大な開発組織をスケールさせるための方法論
  • リアクティブシステムの実例のひとつとみることが出来る
    • でもマイクロサービスアーキテクチャとリアクティブシステムと同一とも言えない
  • ビジネス同士の依存関係をデータフローで表現できる
  • 最近のビッグデータ処理フレームワークはだいたいリアクティブアーキテクチャを採用してる
    • データフローの形でプログラミングしてる
  • DAGでデータ処理パイプラインを記述する " 例 AsakusaFWとか
  • データフロー定義をランタイムが最適化とスケジューリングを行う

まとめ

  1. データフローを定義
  2. クラウドレベルランタイムで翻訳(最適化とスケジューリング)
  3. リアクティブシステムでデプロイ

クラウドレベルのランタイムがデータフローをリアクティブシステムとして配備して実行する

これはWebサービスに適用できる?

  • できる。
    • でも、Dockerfileなどを見ると、命令型っぽい書き方
    • immutable infraのimmutableってFP的なimmutableとはちょっと違う

まとめ

  • 現代のプログラミングが抱えている問題を、リアクティブは解決できる
  • リアクティブはシステムのあらゆる階層で有効な概念
  • プログラミングモデルよりもランタイムの能力が重要な時代になってくるのでは

まとめ リアクティブマイクロサービス #ScalaMatsuri #sm_a

@huntchr

TypeSafeのひと。

  • リアクティブマイクロサービス
  • Play & Akkaによるマイクロサービスのりアクティブ化

  • 30人17カ国で仕事してる

  • テクノロジーの分散型だけではなくHRでも分散
  • 6人がアジア系
  • 4人がシドニー
  • NZにも人がいる

http://www.reactivemanifesto.org/ja

リアクティブマニフェスト

4つの要素のうち、2つをとりあげる

  • レジリエンス(耐障害性) ここが最も重要
  • 弾力性

  • 耐障害性がなければ他の要素は意味がなかった

    • 障害発生時の即応性
    • システム開発をやる以上障害は避けて通れない
      • 複数のインスタンスが走っている
      • ネットワークパーティション
      • スプリットブレインの問題
      • 思っている以上に障害は起きる
      • どこかのタイミングでスプリットブレインの問題が発生する
      • reactive revealed 3000人のアンケート
        • リアクティブ宣言で何が一番重要なのかということを調査したところ、弾力性が飛び抜けて重要であるという結果が得られた
        • マシンを増やすことで弾力性が高まった
        • やはり耐障害性とくらべると…という問題はある
      • 耐障害性(Resiliency)を確実にしていきたい
    • 飛行機の予約システム/銀行など、何日もオフラインになるのはつらい
      • 耐障害性を持っておきたい 障害対応に時間をさかれることもなくなる
    • 顧客マイクロサービス データストアの永続化 ローカルキャッシング 値のキャッシングもいける
    • データベースを毎回毎回取りに行くのはコスト キャッシングをすることが重要

Play Framework 2.4での例

  • サービスのinject
  • HTTP関連での処理
  • HTTPサービス 別のメッセージングシステムのサポート
    • findAll/insertのメソッド(戻り値はJSON)
  • カスタマーサービスが2つのメソッドを提供する
    • 情報をべつのところへうつす
  • 2つのシーケンスを持ってくる
  • カスタマーサービスのステートアクター

  • GetCustomer

  • カスタマーの情報をアクターに入れる
  • すべてのカスタマーを入れる
  • このときにキャッシュをつかって入れ込む(時間の値)

  • キャッシュオブジェクトを使わないで、アクターを使う

  • CustomerRepository

  • SQLとかの振る舞いをSlickを使ってカスタマーについてretrieveをかけてる
  • シングルインスタンスで起動してる

  • curlで情報をfindしたりinsertしたりする簡単なサービス

でもこのシステムはリアクティブなのか…?

  • シングルインスタンスでいいのか(データも永続的なのか JDBCのシリアル)
  • スケーラビリティはあるのか(横展開できるのか ステートをデータベースに当てはめてサービスはステートレス、というふうにしている)
  • キャッシュマネジメント(inMemoryな表現がいくつかある)

Noです。

ソリューション

  • デフォルトでクラスタリングできるようなDB たとえばPostgres BDRを使う (マスタースレーブの関係)
    • 複数ノード " 複数ノードで走らせる たとえばConduct Rにデプロイする conductrはTypeSafeの商品
  • キャッシュ更新のシグナル 例: Akka Data Replication

ConductR

  • リアクティブなアプリケーションのデプロイと管理が出来る
  • 最終的な全体像は本番稼働しないと分からなかったりする
    • コンパイル時点ではそれが分からない
  • DevOpsの役割を担っている
    • Opsの部分がインスタンスの数などを管理している
  • HA(分散型コンピューティング)
    • こういう課題があるためにConductRを使おう作ろうとした
  • たとえばNetflixでもConductRを使っている
  • ConductRの目的はAkkaを見てもわかるように、ActorSystemの延長線上にいる

Make This Reactive!

  • マシンを立ち上げる
    • visualizer
    • conductr-elasticsearch
    • postgres-bdr
  • インスタンスはひとつだけどマイクロサービスアーキであるといえる
  • まずはログの統合が必要(これがconductRでやっている)
  • サービスをクラスタにロードする 非常に短期間でスケールアップスケールアウトが出来る
  • サービスのスタートは自分自身で
    • bundleのハッシュ
  • 毎回curlを叩くためにproxyを通り、conductRを保管して、ラウンドロビンしてくれる
  • シグナルがクラスタ間で展開され、変更/削除がクラスタ間で反映される
    • これができていないとクラスタ別にデータが違うということになってしまう
  • bundle sbtのコンソール上でいろいろ出来る
    • conductr-bundleit
  • シードとなる情報をconductRが持っている
  • riak redis cassandraなどでも使えることを紹介したかったんだけれども。
    • RDBではなくNoSQLで紹介したかった
  • 強力な一貫性を実現するのは大変なので、最初は最適化にリソースを割いたほうがいい

  • サービスをReactiveにするだけで耐障害性が保たれる

まとめ

  • 耐障害性
  • 弾力性
  • キャッシュ管理

まとめ アジアから Scala OSS に貢献するということ #ScalaMatsuri #sm_b

瀬良さん

東アジアからScalaのOSSに貢献 テクニカルな話ではない

現職最後の日が昨日

Who am I

  • 2010から
  • Skinny/ScalikeJDBC
  • Playはシンプルなものよりリアクティブよりになってきている
  • Skinnyは普通のプロジェクトとして
    • scafoldingコマンド
    • テンプレートエンジン
    • ソーシャルログイン
    • DBマイグレーション
    • サーブレット環境になっているのでScalaでサーブレットやりたい人は
  • ScalikeJDBC
    • シンプルでまとまったライブラリ
    • フレキシブルなScalaAPI
    • JDBCをラップしたもの

日本でのScala人気

  • Scalaの大きなメーリスには5000人の参加者
    • 日本人向けのメーリスは700人以上
    • 日本のScalaコミュニティは積極的で大きい
    • Gitterのチャンネルでは400人いる(scalajp/public)
    • 前回のScalaMatsuriは400人くらい 今回は500人 関西もかなりホッとになってきてる
    • ScalaMatsuri関西 去年夏は200人
  • Scalaの本も結構翻訳されている 日本語でもともと書かれた本もある
  • 日本人にとって英語が難しい
    • ちょっと違う視点から見ると同じコインの両面
    • 日本人は日本語で情報を求めがち チャンネルも日本語で情報を求めている
    • 日本語でしか情報をキャッチアップできていない
    • 教育的なところもあるかも
    • 最近の会社は英語を公用語にしているのでそれはいいこと
    • 外に開けたほうがいい
  • 時差
    • 日本の朝は欧米にとって夕方
    • 日本の昼は欧米にとって深夜
    • 時差でコミュのオーバーヘッドが起きやすい
    • でも心配することはなかった
    • NZやOZでは結構ホットに開発

何をするべきか

  • すばらしいコードを書く!既存バッチでも新規開発でもどちらでもいい
  • 言語の壁はやめたれ 英語のREADMEの添付してpublishしていく
  • コード以上に英語も重要
  • 世界のコミュニティに発見してもらうためにも重要

では瀬良さんは

  • SkinnyFramework系のレポジトリ
  • ScalikeJDBC
  • その他小さなライブラリ/SDKなど
  • 既存プロジェクト

  • とても良い経験

  • 自分の作業は知られているけど、グローバルコミュニティで有名かというとそうでもない
  • ScalaDaysなどでプレゼンすると、いいかもしれない
  • サミットなどで自分の作ったものをプレゼンしていくのがいい

まとめ

  • Scalaは日本では人気が高い
  • でも英語のコミュニケーションに長けていない
  • ただそれが世界に門戸を開かない理由にはない
  • コードを書いてこう
  • Matsuriをお楽しみください

質疑

逆に英語圏が何をすべきか 横田さんみたいなひとに架け橋

ただ、日本人もグローバルコミュニティのことを知ってもらいたい

まとめ ScalaコードはJVMでどのように表現されているのか #ScalaMatsuri #sm_a

関ジャバ会

今furyu

  • JVMのバイトコード初心者向け
  • Scalaはコンパイルするとクラスファイルを作る
  • JavaのHello, World

前に似たような内容で発表しました。

  • magic cafebabeから始まる
  • major_version
  • minor_version

  • javapで逆アセンブル

  • javacでコンパイル

コンスタントプールはシンボル情報のテーブル http://www.ne.jp/asahi/hishidama/home/tech/java/bytecode.html

  • JVMの命令は200くらいある
  • JVMの初期設計は優秀
  • invoke(virtual/interface/static/special) がわかるとメソッド呼び出しもわかる
  • Traitとその実装のあるScalaコードをコンパイルすると、2つのクラスファイルが出来上がるし、TraitのクラスファイルはInterfaceになる

  • Scalaコンパイラは少ないコードから多くの機能を生成している
  • 部分適用の箇所ごとに作ってる

まとめ

  • JVMはすごい
  • クラスファイルはフォーマット
  • javapはScalaのバイトコードを理解するのにはとても良い

まとめ あなたのScalaを爆速にする7つの方法 #ScalaMatsuri #sm_c

  • アドテクスタジオのひと
  • 許諾事項 並列実行については考慮していない

EC2インスタンス メモリ30ギガ 8コア

Random Read

  • 2ギガの文字列の羅列のファイル

  • SSD

  • memcache

Aのほうがはやい!

  • SUIKAという文字列をサーチする
  • memcacheよりfileのほうが速いのはmemory mapped fileを使っているから(ユーザ空間のみでディスクの内容をバッファリングできるから)
  • memcacheのほうが遅いのはキャッシュ出来る最大量は1MBまでなので、2048回アクセスしないといけないのがしんどい
    • なお、JVMの環境だとmemory mapped fileは2GBまでしか使えない
    • Apache Spark MyLib
  • memory mapped fileを使うと高速になる

for内包表記 vs flatmapとmap

  • 答えは同じ
  • ベンチマークをとっても全く一緒
    • デコンパイルすると全く一緒の結果が出た!
    • バイトコードレベルだと全く同じだから

append & insert

  • collectionの性能特性

http://docs.scala-lang.org/ja/overviews/collections/performance-characteristics.html

  • VectorとArrayBuffer 末尾再帰はどっちがはやい
    • ArrayBufferのほうが速い
  • Vectorは既存のインスタンスにコピーしている
  • ArrayBufferはインスタンス自身をリサイズしている " ソースコードを読もう

  • var Listとval ListBuffer 先頭挿入はどっちがはやい

    • var Listのほうが速い
    • Listは結構速い
    • 先頭挿入の場合はListのほうが速い
  • Listはheadとtailをサーチして先頭挿入
  • ListBufferは内部変数の再代入してる

  • 末尾追加はArrayBuffer ListBuffer

  • 先頭挿入はListを使うと良い

remove collection

  • var List vs val ListBuffer 削除はどちらが速いか
    • ListBufferのほうが速い
  • StreamはSOになってしんどい
  • Buffer系のやつが速い
  • ListのdropRightはO(N)
  • ListBufferの削除は定数時間
  • 削除のほうが線形の増加がすごい
    • dropRightよりtakeのほうが少しだけ速い
  • 大量の要素を削除するときはListBuffer/ArrayBuffer 書き込み操作はmutableなやつのほうが速い

random read

  • Vector vs ListBufferどちらが速いか
    • Vectorのほうがはやい(ListBufferよりも速い)
    • ランダムアクセスについてはArrayBuffer Vectorのほうがはやい
  • Arrayのrandom readは定数時間 ArrayBufferとVectorは内部的にArrayが使われている
  • Arrayの仲間はrandom readのほうが速い

fibonacci sequence

  • StreamとArrayどちらが早くフィボナッチ数列を作ることができるか
    • Streamのほうが速い
    • Streamは遅延評価リストなので、呼び出したいタイミングで呼び出せる
      • take(n)がミソ 呼び出したいタイミングで計算する
      • StreamをtoListをすると圧倒的に遅くなる
      • 実際の時間は再帰よりO(N)のほうが速い
  • 遅延評価は便利だけど具現化するときはそれなりのコストがかかる

regexp

  • 正規表現はCPUリソースを食う 特に\wはやばいO(N2)
  • \wの数が増えれば増えるほど遅くなる findAllIn vs findPrefixOfとquantifier
    • findPrefixOfとquantifier
  • /.+でバックトラッキングが発生している
  • 文字列の後方をサーチするものなので、ある文字列にマッチさせたものの後ろをとるほうが速い
  • findAllInはすべてマッチさせてしまうので遅い
  • spray-routingのソースコードについて、URIのパスを区切るところがあるけど、findPrefixOfが使われている

  • 先頭から1回だけマッチさせたい場合は、findPrefixOfのほうが速い

  • バックトラッキングが発生するとおそくなることだけ覚えておこう

まとめ

  • memory mapped fileは速い
  • forとflatmap&mapは同じ
  • コレクションの更新はBuffer
  • 先頭挿入はList
  • Arrayの仲間はrandom readで速い
  • 遅延評価は便利だが、具現化するときはリソースを食う
  • findPrefixOfは便利 正規表現を使うときはその計算量を考えるべし

まとめ Playソースコード完全マスターへの道 #ScalaMatsuri #sm_c

  • ScalaもPlayもそんなに…って言う人を対象にしている
  • こうすればだいたい良い みたいなやつ

  • tototoshi

    • scala-csv
    • flyway-play
    • slick-joda-mapper
    • playのプラグインなど
    • scala.jsの怪しい情報商材など

ソースコードを読むとき

  • 「バグっている」と思った時に、自分の実装なのかフレームワークなのかわからない時がある
  • フレームワークのカスタマイズ
  • フレームワークの勉強
  • 暇つぶし

読むのは難しい

  • どこから読めばいいかわからない
  • 設計もわからない
  • ソースコードを読むのはしんどい

そういうのを取り除きたい

ゴール

  • ソースリーディングの役割とか背景などを知る
  • Playの個別のモジュールを知る

ロードマップ

  1. build.sbt
  2. パターン
  3. モジュール
  4. 完全マスター

build.sbt

  • libraryDependencies(使っているライブラリ)
  • dependsOn(sbtはマルチプロジェクトが簡単に出来るので、サブプロジェクト同士の依存関係)

2.1から2.5にかけて、だいぶ複雑になってきている

  • play-javaとplayは同じjar
  • 2.0→2.5でリファクタリングの歴史がわかる
  • 最初はコードが汚かった
    • テストもしづらかった
  • どんどん細かくなっていった
  • Play2.0のときは巨大だったのが細かく分かれていった
  • 各jarのサイズが小さくなっていった
  • ひとつひとつのコンポーネントが小さくなっていった

Playのパターンを理解する

  • dependency injection DI
  • implicit parameter a.k.a type classes

ScalaでDIってどうやるの

  • 結構難しい
  • Springあたりから拾ってきた
  • constructor injection
    • 切り離さないことには単体テスト出来ない
  • RuntimeDI

Play Module

  • Each Module is implemented as Play Module
  • DIの仕組みで作ることが出来る
  • まずはプラグインを読むことからはじめて見たらいいんじゃないでしょうか。
  • 昔あったプラグイン読み込みの優先順位を決めるファイルが、今は、ない

implicit parameter

  • 継承を使わないでimportで振るまいを分けることが出来る
  • type classes in play
    • writeable
    • contenttypeof
    • querystringbindable
    • pathbindable

モジュールの説明

  • play
    • コア部分 Action Rougingなど
  • play-java

    • ↑のJava版…
  • playを読む機会は多い

  • 読みたいjdbc系ライブラリを選んで読んだらいいと思っている
  • WS
  • play-json
  • play-server
  • play-streams(reactive-streams)
  • sbt-plugin

完璧にマスターするのは

あなたの仕事です

まとめ

  • Play2.0→2.5でだいぶ発展している
  • DIのバインディングの仕組みがわかっていれば、読みやすくなる
  • 型クラスがちょいちょい使われているのでその仕組を知っているとわかりやすい

  • モジュールなど

  • core
  • modules ws, cache,など
  • sbt-plugin

まとめ Scalaでドメイン駆動設計に真正面から取り組んだ話 #ScalaMatsuri #sm_c

MOTEXのひと

DDDのほん

DDDって難しいの?

  • DDDの本は設計思想がごちゃってて、実践ドメイン駆動設計
  • 読んで、いざやってみよう!ってなったときが圧倒的にしんどい

Layered Architecture

  • DDD本の600ページの60ページのところ

  • レイヤーの責務を明確

  • ドメインの隔離

  • ユーザーに情報を隔離する

  • MVCのすべてがユーザーのレイヤー
  • アプリケーションのレイヤー
  • インフラのレイヤー

  • どうやって実装するんだい?

  • ViewModelはMVVMパターン

  • Form→ViewModel→Entity→SQLという流れ

  • 実装→レビュー

  • ロジックとしてドメインに必要な物は外に出さない
  • 分析モデリングをイベントとして用意する
  • シーケンス図を書いて、処理の順番を追っかける

  • レイヤーの責務はごちゃりがちなので、レビューと分析モデリングをやるのが肝要

  • 曲者のサービス(3つのレイヤー)

    • アプリケーション
    • ドメイン
    • インフラストラクチャ
  • 処理が追いつかない
  • サービスの責務 ドメインのロジックはテンポラリであることを強調してリファクタする

  • スクラムとの相性は良い。リファクタリングする時間をもうける

  • ドメインを隔離することがDDDの考え方の一つ

  • 責務をわかりやすくする
  • このロジックがこの場所にあるのはいいのか悪いのか
  • 責務は分離するけどコンバージョン処理は多いな

CQRS

  • Command Query Responsibility Seperation
  • Query Model
    • 処理をシンプルにする
  • Command Model
    • 従来のアーキでやるべきじゃないかなって
    • Command Modelは少なめ
  • クエリとして分離するぶぶんは分離して、シンプルなものはシンプルにつくる

is-a Root Entity

http://masuda220.jugem.jp/?eid=315

  • 親が子の責務を知っているのはおかしいのではないか
  • いいんじゃないでしょうか
  • サービスが知っているパターンを採用する

メッセージ

  • Javaだと例外発生させたらいいんじゃないのかっていう風潮
  • Scalaでは何か起きた時のメッセージをいろいろ考える必要があると思われる
  • Low Layer
  • 復旧不可能なエラーはユーザーに見せたくないので、ログに出して終わるようにしたい
  • 処理をするために何が出来るか出来ないかを判断したい
  • なんらかのメッセージを返す実装をどうするかっていうのを話した
  • Validation Scalaz
  • エラー時のメッセージをStack

  • validationはアプリカティブ ちょいちょいscalaz使ってる メッセージのやり方を考えてる stackするならvalidation

まとめ

scala難しい 悪戦苦闘してる この上dddはさらにしんどい このしんどさをシェアして一緒に解決したい。

質疑

case classはなぜなのか ずっと悩み続けてる