Skip to content

Instantly share code, notes, and snippets.

@suzuki-hoge
Created June 28, 2019 10:38
Show Gist options
  • Save suzuki-hoge/2f5e09809400536dd7c5538768a00882 to your computer and use it in GitHub Desktop.
Save suzuki-hoge/2f5e09809400536dd7c5538768a00882 to your computer and use it in GitHub Desktop.
scala matsuri 2019

https://2019.scalamatsuri.org/#schedule

2019 06 28

  • 並列並行の理解が数年進んでないことがよくわかった
  • メッセージングと AWS と CQRS も実践が全く進んでない
  • 知り合いが年々減るけど、知ってる人が増えていく
  • 聞いてわかる内容とやってる内容の乖離が大きくなっていく
  • 毎年来てるけど、もう少し言った後の自分に還元しないとなー

資料欲しいぞーー

(これ scala.js の話だったのか...??)

導入

  • test2 の演算が test1 に依存しているので immutable にしているのに読みにくい
  • せっかく関数型なのに
    • こういうのは辛い
  • そう言う場合は純粋関数じゃあなくても良いんだぞ
  • immutable な function の内部では muttable や procedure, var だって使って良いんだぞ
    • 読みやすければ、だゾ

可変データ構造の例 オプティマイザ変化検知のアルゴリズム

  • 前の状態をトラッキングしていって mutate する
    • それを許容できないと全てを最初からやらないといけない
  • とは言え、外から見れば純粋関数であること

インスタンスの設計

  • muttable な状態が他の invocation に引き継がれる

    • instance の中に cache している
  • 重要なのは、そのクラスの state が外から閲覧できないこと

  • 状態が観測不可能なモジュールを fp, oo procedure を組み合わせて作ろう

    • 不思議でも簡単でもないよ
    • ここがユニークな scala power だと思う
  • scala.js で使ってる例

    • the emitter
    • the optimizer
    • caches for .sjsir files
    • the all encompassing Linker.link() method
    • etc.
  • sealed trait and final class

  • oop には open class hierarchy ってのがあるぞ

  • LinkerBackend

  • 関数型でも似たことが出来るぞ

  • the M word は避けて通れません

  • custom monad というのが scala.js のコードにあります


資料

型クラスってなに

  • アドホックポリモーフィズムを実現するために使うよ
    • ???

ってなるので、砕いて言うよ

  • プログラムに振る舞いを渡すやつあるじゃん
    • ストラテジ
    • Comparator とかでよく使うよね
  • ストラテジって型が決まると大体処理は自明に決まる
    • int なら大小だし、string なら辞書順じゃんか
    • ので、出来れば自分で書きたくないぞ

っていうのを型システムがやってくるのが型クラス

ストラテジを型から自動導出できる仕組みだぞ

  • 定義が型クラス
  • 実装がインスタンス
  • 自動導出のためにインスタンス宣言が必要

scala でどうするか

  • コードは見づらいので後で手元で見れば良いかな

抜粋

  • tuple とかも t1 が comparable で t2 も comparable なら comparable だよね
  • けど compare((t1, t2), (t3, t4)) とか辛いし、結局どっちが大きいのとかなるから嫌だよね
  • なので>を生やしたりするよ
  • implicit が沢山あるのでちょっと大変だけどね
    • (hoge) -> まぁ implicit の種類が把握できていれば問題ないけど...

scalaz, cats

  • 最近は cats がスタンダードなのかなぁ
  • こいつらも同じ様に型クラスそのものとインスタンスと便利メソッドがあるよ

scala3

  • implicit 出てこないよ
    • (hoge) -> へー! delegate なんてのがあるんだ
    • (hoge) -> implicit xxx は結構見直しが入ったらしい
    • (hoge) -> arg1 > arg2って形で演算子を間に1つ置いて定義できるようになったらしい、haskell ぽいな

  • 今度触ろう
  • ソート以外に導出が自明なロジックってなんだろう...
    • domain とかではあんまり出てこないのかな、ってか、明示的にするべきだもんな
    • api 層とか ds 層とかなのかなー

資料

  • セキュリティパッチから考えてみるよ
  • 攻撃コードを再現すんなよ

path traversal

  • (hoge) -> パストラの説明はカット
  • windows の play で AssetController を使っている場合
  • /区切りしかしてなかったので\\等を対象にしたよ

server side request forgery

  • 本来攻撃者が疎通できないローカルサーバにリクエストすること
  • aws ec2 には自身の credential を取得する api がある
  • http://example.com#@evil.com/foo.txt
    • #@ってなに

unsafe deserialization

  • 評価系のみ
    • SocketAppender, ServerSocketReceiver を利用する場合だが、syslog, Elastic Stack が対応していないので本番では普通使わない
  • シリアライズしたデータに細工をされると、不正なオブジェクトをデシリアライズしてしまう
    • (hoge) -> ヤベェ
  • ObjectInputStream を new したところが内部でデシリアライズをしてた
  • デシリアライズしてる箇所を正確に把握するのが大事

xml extternal entity

  • xml には特殊な構文があるよ、それを app がパースした時に発生するよ
    • 自身のローカルディレクトリの隠しファイルを読み込んで出力に埋めてしまう
    • (hoge) -> ヤベェ
  • Document Type Definition(実体宣言)
    • 変数宣言
    • file read
  • XML Instance(実体参照)
  • パーサにセキュアな設定値を全然渡してなかった
  • どの言語でも起きやすいので、チートシートがあるから見ておけよ

まとめ

  • 毎日チェックしろ
  • レベルに応じて対応納期を決めておけ
    • 本当に致命的な者以外だと、ある程度は業界にもよるけど
  • 攻撃コードがあるか確認しろ
    • 素人に使われるので攻撃されるリスクが上がる

質疑

  • 脆弱性の数とセキュアさって相関ある?
    • spring はやっぱチェック頻度が高いのでセキュアって感じがする
    • けど逆に struts1 なんてのはもう脆弱性は報告されないけど、セキュアじゃあないじゃん?

  • コンパイルでは抜けないのばっかりだなー
  • 案外テストパターンって網羅度高くないんだな?
    • どれもそんなパターンに上がらないようなケースじゃあ無い様な気がするけど...
    • まぁ答え見てから言うのはあれだけど
  • FW のセキュリティパッチの実装見るのおもしろそうだな
  • ってかセキュリティ意識全然足りてないな、これを漏らさないのは自分で設計するとなると難しい
  • アプリのセキュリティ部門、必要なんだな

資料

  • scala には便利な糖衣構文や for がある
  • それらの恩恵を受けるには、最初の設計で型を設計しないといけない
  • こんなのがあるよ(FutureT とか見えたけど1秒しか映らなかったww)
  • Eff 使ってみてるよ
  • Future だとセマフォの制御が難しいのとエラーハンドリングが大雑把になりがちだから
  • Future-Try だと Throwable に限る点とシンタックスの複雑さ
    • Either に包むので表には出さない
  • Future-Either だとエラーハンドルしないときも型合わせが大変
  • EitherTFuture はある程度ネスとしても for がシンプルだけど、評価順に依存したり型あわせが大変だったりする
  • Eff だと煩雑さや評価順の大部分の問題を解決出来るが、多少難しい
  • 我々は Clean Architecture に Eff を導入してやっている

  • 進み早すぎww
  • 資料くれー
  • モナド変換子までは出来る様になってるはずなので、Eff の写経から入ろう

資料

JVM における基礎と純粋関数型言語における実現手段について話すよ

  • 並行処理

    • concurrency
    • 1つのスレッドでも実行可能
    • 1つの戦車で2つの砦を攻撃するイメージ
  • 並列処理

    • parallelism
    • 沢山のリソースを使い高速化する
    • 2つの戦車で1つの砦を攻撃する
  • 2つの砦が離れている場合、戦車が狙いを定めるのに時間がかかる

    • コンテキストスイッチ
    • それが大きい場合、1つずつ処理した方が早い場合があり得る

コード多めだったので詳細は資料待ち

  • Asynchronous Boundary って何...
  • ブロッキングか... その辺もずっと避けてきたな...

このセッションは要復習...

  • 公平性

    • 異なる複数のタスクを進めることが出来る蓋然性
    • 遅延のばらつきが大きくなる
  • Green Thread

    • os ではなく vm にスケジュールされる
  • Fiber

    • 軽量スレッド

  • コードが小さい...
  • 毎回 scala matsuri や haskell days で並列並行聞いてるけど、全く実践してないな...
  • Future は将来じゃあなくてフューチャーって翻訳しないといけないって、超難易度高いな...
  • twitter でちょいちょい見る monix って何さ
  • あかん、飯が多い上に短くて一気に食べたので、ちょっと眠い...

資料

  • がんちゃんと会って色々しゃべってたら部屋に入り損ねた...

    • JVM の話とか教えてもらった
    • GraalVM のセッション行くって言ってた
  • 一番聞きたかったセッションなので、仕方ないので床で...画面見えない...

  • 差別化したい箇所だけに集中出来るようにしたいねってなった

  • リニューアルが超多くて、毎回インフラから作ってた

    • 8回!
    • (hoge) -> インフラとドメインを分けたいって背景で言ってるのかな?
  • ドメインモデルが大体できて、動くモノを作ろうって段階では、5人くらいでモブプロをしたよ

    • app 層, infra 層,,, って作っていくのではなく、機能を通しで作っていった
    • aws や寺の導入を、合意しながら都度やっていった
  • 流れが出来たらモブプロを辞めて、モジュール毎にどんどんやっていった

    • その頃からアジャイルとかにした
  • 別チームが開発する可能性があったので、コンテキストマップをきっちり作っておいた

    • 責任の分界点が曖昧になるだろうと思ったので作っておいた
  • システムのあるべき構造に則ってチームをアサインしよう

  • 頭で考えなきゃいけないオブジェクトが増えてきたなって思ったら分割を考えてみる

  • エンティティが 15, VO が 300 くらいあります

    • (hoge) -> 見えない...
    • なんでもかんでもエンティティにしてきたけど、ホントにそれが id が必要で識別が必要かをよく考えるようにした
    • そうではないなら VO にしていった
    • ちなみにそれをどう永続化するかはまた別の話だぞ
  • Foundation

    • (hoge) -> 良く聞くけどこのレイヤー名(?)の出典ってどこなんだろ
    • (hoge) -> 前どっかの例でやってたニュアンスは foundation はドメインで core はプリミティブに近いイメージを感じだった
      • あれ、でもコアドメインって言うよな? core domain と foundation は違うのかしら?
  • domain に repository の io があると副作用が発生してしまうので、そうじゃあない層にした

    • domain に io とか future とか混じるの嫌
    • app 層に出した
    • (hoge) -> 面白そうだけど画面が見えねー!
  • scanamo なんてのがあるのかw

    • scala の dynamo db ライブラリ
  • ちょっと聞き逃したけど、何かをドメインに置いて良いかについて話している

    • 「〜〜」に限る場合置いて良い、「〜〜」の場合はだめ、って決めて行った
    • (hoge) -> ドメインの制約ちゃんと決めてるの、良いなー!
  • case class の詰め替えに悩んだので、ドメインイベントに関してはアリにした

    • あんまりメソッド生えないし

なんか抽象的な本が多いので、実践を共有しました

質疑

  • 失敗したことある?
    • モデリングに3ヶ月もかけたのは失敗だった
    • モデルだけやってたけど、app 層とかも作って小さく通せば良かった、そういう面のフィードバックは絶対あるから
  • メリットは?
    • 今までは発生する通信を軸に実装してたけど、複雑すぎて追い切れてなかった
    • 広告をドメインに置いたことで、ライフサイクルの可視化がとても良くできた
    • 新規参入者にも説明しやすかった

とても良い

資料

こむらさきなんて苗字珍しいな、一瞬驚いたけどw

座れたし事前に資料も手に入れられたので、すごい余裕を持って聞ける...

導入

  • scala は強力なので複雑な現代システムに対応できるぞ
  • DDD も心強いぞ
  • ドメインに技術制約や大人の事情が入ってくるのは世の常
    • 一時的だからマージして、みたいなやつとかも
  • DDD も FP もふんわりだよ

ドメイン、特にリポジトリを取り上げるよ

  • トランザクションを隠すとなると、impl 層のメソッド単位で切らないと行けない
  • けど、跨ぐトランザクションを保持するなら外から引数で渡さないといけない
    • 2 users を update する時に、トランザクションを保持したいじゃん?
  • しかも io を非同期にしたいので ExecutionContext も引数に必要

それらってドメインなの?

  • 技術的関心事がドメインに入ってるじゃん、FW 変えたらそこ変わるし
  • ピュアってのはそういうのが無いこと、ピュアな方がバグりづらいしテストを書きやすい
    • (hoge) -> 同意、ドメインのテストにトランザクション出てきたりする
  • ピュアで無いものは抽象化して隠す
    • 必要引数を受けて結果を返す関数を返す関数になるように変える
    • その部分に type alias を使って F と書き直す
    • F に高カインド型を用いる(型コンストラクタ的な)
    • repository 目線だと引数の具体型が消えた

使い方

  • repository がピュア過ぎて何も出来ないw
  • じゃあ F の具体型知らないと行けないの?

いや、みんな大好きな M を使えば大丈夫

  • 事故看守の件とかどうでも良いです
    • ひでー漢字だ... 自己関手の圏
  • Monad があれば map が出来る
  • Context bounds という scala 機能でリファクタしてみる
  • んで implicit の部分のヘルパーを作ると、良い感じで使える
  • Monad は cats でも使えよ

ついったしててちょっと聞いてなかった

  • kleisli とか出てきてた
  • Tagless Final Style な DI と言う

DDD って oop が基礎になってるって言うけど、違うとは思わないけど fp だって蚊帳の外ではないんだぞ

  • CQRS が余談で急に出てきた
  • ドメインはクライアントのビジネス要求を表現する場だよ、って思考停止してるとこうなる
    • findStatusActiveWithLimitAndOffset
    • (hoge) -> ヤベェ, 馴染み深い
  • 検索とかレポートまで含めて1モデルでやるのは無理だよ
  • 例えば更新ではドメインをピュアに保つが、参照は諦める部分があるって設計もある
    • 性能や特定 db の都合が多少入ったりする場合もあるかもしれない的な

資料

本の内容を踏まえた上でやるよ

  • あらゆるソフトウェアシステムは「方針」と「詳細」に分割できる
  • ソフトウェアを保つために、出来るだけ長い間多くの選択肢を残す
    • 残すべき選択肢は、重要ではない詳細のこと
  • レイヤードアーキテクチャも本質は同じ「関心の分離」

オニオンの外側が「詳細」で内側が「方針」

実践

  • レイヤー設計を小さいプロジェクトにして build.sbt で依存させている??
    • レイヤー毎に違うプロジェクトとして、build.sbt で依存設定をしている
    • infrastructure は db とかじゃあなくて共通ライブラリみたいなもの
    • これでレイヤー間の依存の方向を強制できるらしい
    • ついったを見てると、マルチプロジェクト構成の時に依存方向を縛るのによく用いるらしい
  • j5ik2o/scala-ddd-base オススメ
    • (hoge) -> 聞いたととあるアカウントだなぁ
  • repository は application logic とした
    • (hoge) -> さっきと同じ話?
  • interface adapter は framework や db, json みたいな詳細との変換処理
    • プラガブルに使える単位でパッケージングする
  • なにやらモナドの匂いがしてきた
    • F[_]やらモナドエラーやら出てきた
    • UseCaseMonadError
    • UseCaseError
    • UseCaseInteractor

ここまでが方針の話、ここからは詳細の話

zio ってのを使ってみたよ

  • 3つの型で表現する
  • あかん、もう疲れた...

  • 本の復習が多かった
  • ひとつ、ふたつ前の実践コード多めの内容と比べると、正直やや物足りなかった
  • と思ったら後半は結構実例が多かった
  • 下のテキストが手元だと切れてしまっていたのが残念...
  • レイヤーの依存を別プロジェクトにして縛るって思いつかなかったなー!おもしろい!

ん?これ?? -> github

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment