Software engineering from east direction

六本木一丁目で働くソフトウェアエンジニアのブログ

Laravel JP Conference 2019 にて、設計についてスピーカーの知見をたくさんいただけて感無量でした(聴講レポート)

Laravel JP Conference 2019にて聴講したセッションのレポートを書いていきます。

conference2019.laravel.jp

Laravel JP Conference

田町にて開催されました。

f:id:khigashigashi:20190216102538j:plain
入り口

エコバック・ネックトラップ・Tシャツが素敵です。

f:id:khigashigashi:20190216102616j:plain
戦利品

名札が素敵ですね!

f:id:khigashigashi:20190216102736j:plain
素敵な名札

聴講したセッションです

フレームワークとの付き合い方

@shin1x1さんより

blog.shin1x1.com

聴講メモ

  • フレームワークを使うのは「楽をするため」
  • 楽をするために
    • 理解しやすく変更しやすい
    • 利用できる便利なものは使う
    • テストを書く
    • 自動化する
    • ノウハウをチーム・コミュニティに共有、共有していくと自分にも回り回って集まってくる
  • フレームワークはHowである
    • What: アプリケーション(ドメイン、関心事、仕様)
    • How = Whatをどの技術でどう実装するか(HTTP, RDBMS, Mail, KVS...etc)
    • アプリケーションが主で、フレームワークが従
  • フレームワークは汎用的
  • SQLを書くか問題
    • 集計系の複雑なクエリをORMで実現する不毛感
    • 必要ならSQL文を書く
    • Laravelではそれ用のメソッドが用意されている
  • フレームワークのライフタイム
    • メジャーバージョンアップ対応
  • フレームワークとの適切な距離
    • 選択肢を残しておく
    • 決定を遅らせる
  • 距離のとり方
    • 独自ディレクトリを活用
    • 独自namespace
    • アプリケーションのレイヤを分ける
      • コントローラはフレームワークとの密結合になりがち
      • コントローラとアプリケーションロジックを分離
  • 事例:Laravel upgrade

感想&もやっと考えていたこと

  • フレームワークを使うモチベーションを「楽をするため」と身近な表現を使用しているのでとても共感しました。
  • フレームワークをHowと定義しているのが明確でいい
  • 集計してデータを取得したいというWhatに対して、RDBMSに対して複雑なSQLを発行することも一手段として考えて、ORMの利用などに縛られずにやっていくのがいいんだろうなとおもった。
    • MySQLからPostgreSQLに移行したいみたいなときにORMがwrapしてないところがあるみたいなのがデメリットな感じがあるけど、そもそも長くメンテナンスするシステムがその変更発生するの相当稀なんだろうなという感触。
    • パッケージシステムとかを提供している場合はORMの利点を活用したほうがいいという判断でSQL書かない選択肢もあるのかも。
  • フレームワークとの適切な距離、Howは適切に「捨てれる」状態を保ち続けることが大事だよなぁ

Ask the speakerで聞いた事

Q: CakePHPだとORMがガラッと変わるのだが変更が多い道をいくしかないのだろうか

- ORM利用している箇所を抽象にしていくとか?
    - ORM部分を抽象にしていくとかなりの数の抽象ができてテストがモックにあふれる怖さもある感じがする
  • 理想は、ORMからアプリケーションロジックを分離していくこと
  • ただし、現実解とはいえないので、後方互換性を保つためのBridgeを作るのが一つの手としてある
    • AppModel などにBridgeを定義
    • ただし、長続きはしない手法なので、とにかく動くようになったら綺麗にしていく
  • インハウスフレームワークを使ったアプリケーションをLaravelに移行する事例で使えるか考えてらっしゃること
    • アプリケーション部分を引っ剥がしていって、Howの部分を書き換えていく
    • テストは、APIレベルで書いていってそのテストが通っていればOKという確認の仕方

Q: WhatのアプリケーションレイヤとHowのフレームワーク部分のテスト

Q: アプリケーションレイヤが抽象への依存が基本となると思うが、モックがたくさんになると、モックでがんじがらめになる感覚があってこのバランス感覚はどうされてるか

  • データベースを用意してテストに必要なレコードを用意するといったコストよりかは、モックを用意するほうが辛さが少ないように感じている
  • 複雑度によるが、複雑でなければAPIレベルのテストで十分な部分もある

Q: モックに差し替える依存オブジェクトが感覚的に4つ以上超えると脳内アラートが上がる感覚がある by 川島さん

  • モックの数で考えたことはあまりなかった
  • あまりに多い場合は、クラス自体を分ける選択を考えたほうがいいかも、設計自体を見直す必要性

更に疑問を持ったところ

  • APIのテストではどのくらいの責務をテストしているのだろう、リクエストに対して期待したレスポンスが変えるというIN/OUTのみ?
    • テストの結合度をよしとするのであれば、データベース部分まで含めた広いカバレッジのテストになるかな?

Webアプリケーションが今こそ知るべき、RDBMSのパフォーマンスチューニングの勘所 ~ 未踏の速度を目指して~

soudai.hatenablog.com

聴講メモ

  • 開発速度・実行速度はどちらも大事
  • パフォーマンスの問題は、RDBMSのことが多い
  • Webサービスはクライント・インターネット・サーバーサイドと広い
  • RDBMSの基本的な仕組みを知る
  • SQL実行時
    • パーサ・リライタが構文を解析・構文木の作成
    • プランタ・オプティマイザによる最適な実行計画生成
    • エグゼキュータがクエリを実行、データ取得
  • 遅いのはエグゼキュータになる
  • 実行計画の読み方
    • EXPLAIN
  • RDBMSが苦手な実行計画になっていることが原因
    • リレーショナルモデルで表現できる情報ではない
    • 履歴やツリーは苦手
  • RDBMSが苦手じゃないけど遅い → 活用できていない
    • INDEXの活用できていない
    • 不要に大きいデータを取得してる
      • 使っていないカラムを取得してるとか(ex. TEXTの記事本文)
      • インプリシットカラムの1例
      • → クエリを扱うデータを小さくする
      • WHEREで小さく・FROMで小さく・不要なJOIN句をなくす
    • 複数回実行
      • N+1問題
      • loopでSQLを発行していたり
      • 実行するクエリを知ることが大事
    • テーブル設計
      • データベース設計は積み木
  • B+Tree INDEXの仕組み
  • テーブルスキャン
    • 1回で全行を取得
    • シーケンシャルI/O
  • INDEXがある場合
    • 人を探すときに出席簿があるイメージ
  • 設定したINDEXが効かない
    • 検索結果が多い、全体件数が少ない
    • カーディナリティの低い列
    • 曖昧な検索
    • 統計情報と実テーブルの乖離
      • バッチの大量
    • SQLパフォーマンス詳解 という本が良い
  • MySQLはNested Loop Join
    • 掛け算
    • テーブルスキャンの場合、1000行 * 1000行 = 100万行
    • INDEXがある場合 1000 + 1000*1 = 2000
  • フレームワーク依存症
  • より良い抽象化でwrappingする
  • 抽象化する箇所を忘れてはいけない

感想

  • 失敗から学ぶRDBの正しい歩き方 を買いました!
  • 抽象化されていることを理解した上で、その仕組みをどう使うのがよいかを考える
  • CQRSなどの設計概念も関連して検討すると良さそう。ORMを使う箇所とそのまま抽象化されていないSQLを利用するか

疑問

  • 積み木になってるテーブル設計とマジカルなテーブル設計の違いと避け方
  • マジカル設計に追加された丸いテーブル設計の例どういうイメージだろう
  • → あとでSQLアンチパターンとか復習しよう

Laravelで学ぶ、ウェブアプリケーションチューニングの基本

聴講メモ

  • 「遅い」とは?「遅い」は主観、曖昧なため改善できない
  • コンテキスト・数値の説明によって具体的な状況が浮き彫りになる
  • 「推測するな計測せよ」
  • ウェブアプリケーション全体像を見る
    • 自分の領域(ウェブアプリ)の狭さを知る
    • アンコントローラブルな領域があることを知る
  • パフォーマンスを科学する
    • レイテンシー
      • 待つためにかかった時間を計測した値
        • ex. HTTPリクエストからレスポンスまで
    • ウェブアプリ以外の遅さ(大陸間・速度制限・共有LAN)
  • ウェブアプリの責任
    • 大陸間の遅さは、ウェブアプリでは改善できない、CDN等の対策
    • ウェブサービスの「レスポンスタイム」で正確にすることができる
  • Webサーバメトリクス
    • ウェブサーバの「遅さ」が本当にウェブアプリのせいなのか
    • メモリ使用量・CPU使用率・ディスクI/O ...etc
    • sysstat package, CloudWatch, Mackarel, netdata ...etc
    • 継続的にデータをとって傾向を見る
  • Webアプリから原因を探す
    • レスポンスタイムが遅いURLを探す
    • alp ...etc
    • New RelicなどのWeb Tool
  • プロファイリングする
  • 改善ループを回す
  • よくある問題と対処
    • HTTPのAPIコール
      • 1コール1秒くらい遅くなると思うくらい
      • 更新頻度によってはCache
      • 自前APIであれば専用APIを用意
    • メール送信
    • Slack通知
      • 同期的に処理すると遅くなる
      • Queueを使おう
    • SQLクエリ実行
      • 単発なクエリ遅い場合
      • N+1クエリ
    • 計算量がムダに多い
  • サーバ・インフラを支える技術
    • 第一章を読もう

感想

  • 普段Mackarelだけど、昔sarコマンド実行してたことあったなと懐かしくなった
  • ウェブアプリ全体を見渡してパフォーマンスを見るというのがすごくわかりやすかった。
  • よくある問題と対処ありがたい情報、slack通知を非同期はぐさっと刺さった。
  • パフォーマンスチューニングをやる思考プロセスが言語化されてて、この進め方で一度やってみようと思う内容でした。

抽象化って何?

blog.hidenorigoto.com

聴講メモ

  • 抽象化 Abstraction
  • 設計の問題はソースコードの中にこそある
  • 数独」アプリの「正解チェック機能」の実装を担当するシチューエーションを想定
  • 依存関係逆転の原則の使い所
    • CheckableMatrixInterfaceを作ったが、、、?
    • なにかが間違ってる...
  • 現実世界の抽象
    • 抽象化とは
      • 抽象 = ある部分だけを取り出すこと
      • 捨象 = 取り出した結果捨てられるもの
    • 抽象のハシゴ
    • 抽象化における変化
      • 特徴量が少なくなり対象の数が多くなる
    • 抽象レベルがおかしい文
      • 別の抽象レベルが混在するとおかしくなる
  • プログラミングにおける抽象
    • 道具: プログラミング言語・構文・語彙
    • 数独アプリ」を表現するための
    • 扱っている問題や概念を抽象化すること
    • 達成するために機能を用いる(Interface, Abstract)
  • 抽象の指針
    • 適切な命名
    • 抽象度の統一
    • 狭い範囲
  • CheckableMatrixInterfaceはどうだった?
    • 適切な名前か?
      • ChackableなtoArrayとは
    • 抽象度の統一
      • toArray()、arrayを使う前提?
    • 狭い範囲
      • 一つだけ
      • Checker -> check: CheckerとCheckableMatrixInterfaceの関係では狭い範囲になっていない
      • Matrix -> toArray: せまくなってる?
  • 依存関係の本質を見極める
    • 本質に迫っていく
    • Checkerは最低限何があれば責務が果たせる?
      • Checkerは数字の列を扱う
        • NumberCollectionから数字の列を受け取る形
        • checkNumbersのコードのみになる
      • 数字の列生成
        • アダプターで吸収、データの形を「数字の列」に変換
  • Afterの評価
    • MatrixからNumberCollectionになり狭い範囲になった

感想

  • プログラマとしてのシチュエーションから入るのが話に入りやすくて、さすがわかりやすい発表だなと思いました。発表の仕方参考にさせてもらおう。
  • 重要なポイントじゃないけど、array_intersect知らなかったのでほーとなった。
  • 抽象とはなにかと、実現するための手段(Interfaceなど)がごっちゃになってる自分の理解が不足している点を気がつけて「なるほど!」でした。

Ask the speakderで聞いたこと

Q: 狭い範囲について改めて聞く

  • 抽象のレベルが上がるほど特徴量が少なくなる
    • 目の前のペイジ → 仔牛
    • 仔牛 では、「乳が絞れる」という機能を持った、細かい特徴を捨象したものが見つかるかも
  • 目の前のものだけを見ると、目の前のものに引っ張られてしまう
  • 複数同じようなものが出現した際に抽象を見つけるきっかけになる

Q: 設計について学んだ経緯

  • 設計はまだ形式知的になりきれてない部分
  • 設計の師匠を見つける
  • 設計のベテランがいる設計コミュニティ
  • 渡辺 幸三さんの考え方、データモデル・業務モデル・機能モデルの3要素で考える手法
  • 帳簿の世界は、MicroService的に世界が切られている
    • 現実世界を観察していくことは、非常に有用

Q: 設計に興味を持ってもらうには?

  • (筆者個人的に)社内でオブジェクト指向設計勉強会をやっていて、どの業界から来たかで設計に対する興味の度合いが変わる気がする
  • システム性質上、データが重要になるとデータモデリングなどに対しての興味が強くなることもあったり、確かにバックボーンによって変わるのはある

SimpleとEasyは違う

聴講できなかったのですがTLで流れてきてすごいしっくり言語化されてて参考になりました。 Simpleは客観でEasyは主観という言葉がすごい刺さりました。

カンファレンスを通して

今回はスピーカー・スポンサー・スタッフなしの完全聴講者としての参加だったけど、がっつりスピーカーの方々の話を聞けて、もやもや悩んでいたことを言語化していただいてとても勉強になりました。 Ask the speakderで直接質問できる場があるのもとても良かったです! カンファレンス行くと、新しく興味を持って深めたい分野が出てくるのでやっぱりいいですね。パフォーマンスチューニング系の話についてもPHP勉強会でLTくらいできる内容を一度ガッツリ時間をとって実践したいと思います!

とても明日から意識・実践できることが増えてとても楽しいカンファレンスでした!スタッフの皆様運営ありがとうございました!