かきあげせいろはラーメンがたべたい

技術プログラミングいろいろ記録メモ備忘にゃーん!

最高に楽しいカンファレンスbuilderscon tokyo 2019に参加してきました(自分用メモ&感想)

昨年初めてbuilderscon2018に参加した際、楽しく技術発表するお祭りといった珍しい雰囲気のカンファレンスだったので好きになり、光の速度でチケットを購入しました。 カミオカンデコンパイラライブコーディングの話は聞けなかったのですが、がすごく盛り上がっていたらしく、動画が後ほど公開されるのであればみたいです。

Ruby (off|with) the Rails

  • マルチパラダイムデザイン
  • Railsの解決したい問題と解決
    • 素早くきれいに
    • アクティブレコードを中心にHTMLからDBまで一気通貫
      • 高い開発効率
      • DBのエラーをそのままViewに
        • データモデルを中心に各層が密結合
        • 同一データモデルに複数のユースケース
          • 条件によってスキップされるバリデーション
          • でかいサービス
          • コントローラーが複数のモデルを触る状態
            • デコレータパターンで対象している?
              • Railsでは存在しない?
          • データモデルと1:1になる場合は
            • 小さいサービス(マイクロサービス
            • ユースケースにデータモデルが引きずられる

データモデルと一対一にできない?

  • ソフトウェア設計でかいけつしてみよう
    • ブログメディア
    • 公開時にセンシティブな内容を編集する処理が必要だが。別カテゴリのときは不要
      • この状態の場合はコールバックをスキップとかしてしまうようになる
      • つまりデータモデルとユースケースが仲良しでない
      • データも出るを歪めるん発送をは基本NG
        • データはアプリより寿命が長いので
      • データモデルはデータの整合性を守るため
  • データモデル中心の設計では破滅になる
    • Rialsを離れて考えてみる
    • ドメインオブジェクト
      • コンテキストに寄って役割が違えば。データモデルは同じでも別のデータオブジェクトになる
      • コンテキストBからは見たくないデータモデルが存在することもある
      • Repositoryそうの導入
        • データモデルからドメインオブジェクトを引っ張ってくる君
        • データの永続化する君
        • これらに寄ってテーブル構造の関心分離
      • Railsではこれができない?
        • アクティブレコードはデータモデルに対してロジックを書いていくやり方
          • 同じデータモデルから別のアクティブレコードをつくる
            • Articleを継承したクラスが2つ存在する
            • STIではないですよ
              • コンテキストが違うとSTIつかえないので

諦めていること

データモデルを引きずっている テーブルが変更されるとARmodelは影響を受ける

コントローラーの破滅

  • 複数のARmodelを触っている
    • Rialではない場合は複数ドメインを触るときはドメインサービスを触っている
    • Railsではできない
      • 2つ目のARもデータと密結合している
      • サービスのなかでARのupdateメソッドとか触るとサービすを切った意味がなくなる
      • ARでupdateをファサード
    • MVCはテスタビリティが大きな問題(解決したい
    • RailsのCはテスタブル
    • ARモデルにロジックが書かれている場合はコントローラーに複数AR呼び出しを記述するのでも行ける

まだデータモデルから独立できていない

バリデーションの破滅

  • バリデーションはARと一対一ではなくなる
    • フォームクラスを作ってユーザーからもらったデータをシステム用に変換する君
      • 突き合わせエラーは検知できない(組み合わせ
        • ユニークではない値だった場合
        • ナイトに装備できない武器が送られてきた場合
        • 業務ルールが関わってきているのでModelに書く
      • 成績上位者にメッセージをおくりたい場合で、名前順にしたくなった
        • 「成績上位者にメッセージをおくりたい」とは関係ない
          • 複数の関心
      • 参照系と更新系を分離する
        • 別の問題は別の設計をしよう
      • コントローラーで更新系の窓口を呼ぶ
      • コントローラーで参照系を呼ぶ
    • 更新系はSQL直書きか、クエリビルダーてきな処理でいい
  • 学習記録

    • 更新系
      • コメントをつけられる
      • お知らせに新着通知
      • お知らせの種類によって入れるテーブルが変わってきたりする
        • 場合によってはプッシュ通知
      • ユースケースで以下を呼び出し
        • コメント残すサービス
        • プッシュ通知サービス
      • サービスでは複数のARModelをさわる
        • 通知タイプごとに切り出されたModelを触る
        • テーブル名そのままではなく関心ごとのModelを触る
    • 参照系
      • ページネーションとか
        • サンプルではクエリビルダー
      • 更新系のARModelを触らないようにする
  • 問題に対して解決となるような構造を与える

  • いったん利用しているフレームワークを外して考えてみて、そのあとフレームワークありで考えてみる
  • まずは何が問題なのか
    • それらに対応する解決法の知識を増やす。練習する。
  • 誰かと同じ問題にぶち当たった時
    • クラッシーに入ってほしい

Q

  • レイヤーを重ねるごとにコードが増えていくけど許容している?

    • なぜコード量を増やす選択肢を取るのか?
      • 問題に対して解決するってこと
  • 問題を認識できていない場合はどうするか?

    • その場合でもレイヤー構造にするべきか?
    • 問題を先に認識するべきか?
      • なぜ不安になっている?
      • 構造によって問題が解決できることの実感がない
    • 不要な構造にする必要はない
      • つまり現状が良い構造になっている
  • 参照系RailsのViewをつかうことを前提としているので、グラフQLや別のなにかを叩く(DB以外)

    • グラフQLにデータを詰め込む部分は必要

感想

去年の内容は"コードの良し悪し"が暗黙知になっていて、「デザインパターンと設計原則を用いて、直面している問題を解決するコードを削り出していく」という方法で"コードの良し悪しが暗黙知になっている"という問題を解決する構造を示していました。

今回ではコードより大きい粒度である技術要素の選定に起因する問題はそもそも何なのか、ということを明確にした上でその問題に対し「技術要素を変えれば良い」という短絡的な結論ではなく、現実的に取れるであろう対策を示したものでした。

①問題を捉え、②自分が持っている武器をあてはめて問題が解決したかを確認し、③まだ残っていたり新たに発生した問題をまた捉える。という①②③のサイクルを回す事自体を「"問題に対する解決法"が暗黙知になっている問題」を解決する構造を与えるという、目の前にある問題を上位レイヤーの視点を持って解決する方法を取ることで、チーム(や組織)の次の問題を上位レイヤーに移動させていく。 という方法は両方の発表で共通しており、この内容を理解した我々はとにかく問題解決のための武器を増やせば良くなるので頭が透き通る気分です。


ソースコードを堪能せよ

  • 動的解析

    • gotrace
    • Race Detector
      • go test -d
    • ゴルーチンの可視化ができる
  • 関数を見つけるときにgrepで行けるかどうか

    • grepは文字列としての検索
    • ソースコードとして理解する必要がある
      • golint
      • go vet
      • reviewdog
        • ぷるりく時に検査
  • 字句解析

  • 構文解析
    • 抽象構文木になる
      • この時点では方の不一致はわからない
      • 変数の定義場所は使用場所もわからない
  • 型チェック
    • 型情報にアンル
  • SSA形式へ変換
    • 性的単一代入(SSA)になる
      • 変数への代入が複数の場合、コンパイラの中で2回めの代入は、別の変数に入れたこととする技術
  • ポインター解析
  • 静的解析ツール
    • ケルトンというツールを使うと簡単に作れる

感想

ASTを解析し複雑になりすぎてしまったソースコードの依存関係をグラフィカルに表示するアプリケーションの開発案件に参加させていただいたことがありました。それまで言語がどのように変換されているか意識したことはほとんどなかったため、コンピューターに理解させるための構造に変換されていく過程に感動した覚えがあります。

今回の発表はASTのみではなくもっと広い範囲でソースコードが変換される過程を丁寧に解説されていて、いつも利用している静的型付け言語の強い部分をより意識できました。 また、ソースコードの品質のためのアプローチとして通常の静的解析はよく採用されるように思いますが、この発表で得た知識をもとに解析ツールを選定(もしくは自前で開発?)する際の考慮が深まることは間違いないと感じます。


ビジネスの構造を扱うアーキテクチャとユーザとの接点を扱うアーキテクチャ

  • SoR
    • 記録
    • 堅牢整合性
  • SoE
    • 利用者との関係
    • UX
  • Modelとは
    • 解決したい問題領域から必要だと思われる情報を記号化・可視化したもの
      • 地図の例
        • 地球儀はほぼ正しい
        • 一般的な地図→方角はあっているが、面積などを諦めている
  • SRPを再定義
    • 変更理由をアクターとする
      • 変更してほしいと誰かに言われたはず。それがアクター
      • アクターは利害関係者すべてがなりうる
      • アクターが違うのにモデルが同じケースは極めて低い?
  • SoRは複数のアクターから触られるモデル(ドメイン
  • SoEはアクターに紐付いたモデル(プレゼンテーションモデル)
  • ドメインプレゼンテーションの分離
    • 顧客が供給者に依存
      • アプリケーションを利用する
    • 供給者が顧客に依存
      • ドメインがもたらす銭は顧客からもたらされるので、アプリケーションの設計は顧客に依存?
  • ペリフェリックアンチパターン
    • パリの高速道路らしい
      • パリを迂回する形
    • ドメインを経由せずに処理するのは良くない
  • CSRSに似ている?

実装

  • SoEには
    • キャッシュストア配置
    • 入力値単体のバリデーション
  • SoRには
    • stateも含めた突き合わせバリデーション
  • 事業の変更条件(バリデーション)と、アクターから通す(View)の変更条件はライフサイクルがちがう
  • SoEトランザクション的でなくていい。
    • いいねボタンは色が変われば良くて、いいねカウントがインクリメントされることに関心を(もつこともあるかもだけど)持たなくていい
      • 結果整合性だけあればいい
        • 時間軸がずれていていい
  • 決済処理は与信(オーソリ)を確保してから、買い物の確定(キャプチャ)(非同期でもいい)の関係
    • SoEがユーザーに不快感を与えない責務を果たし、SoRが整合性の責務を果たす
  • 記事の公開ステータス
    • 下書き
    • レビュー中
    • 公開(SoE的に関心があるのはここだけ)
      • 別アクターの関心に含まれたタイミングで、別の場所にデータを作成するほうがいい
        • 別テーブル、DBのView、別データストアなど

キャッシュの話

  • データをライフサイクルごとに分離しておく
  • キャッシュ戦略
    • 毎回問い合わせ
    • PubSubリフレッシュ
    • 一時的に許容

まとめ

Q

  • BtoBであってもオペレーターが存在する
  • SoRにはUIは存在しない?
    • ない(全部JsonかグラフQL)
    • SoRを使って何かするオペレーターがいるはず
  • SoEの要求に合わせてSoRが出力を変えなければいけないのでは?
    • SoRが複数に分割される?
    • SoEが1つのSoRからデータをもらう
      • SoE独自のデータストアに持っておく?

感想

SoEとSoRという考え方をはじめて知りました。アーキテクチャーとしては発表されていた方であってもまだ試行錯誤しつつといったことでしたが、考え方自体はJavaでいうパッケージ分割方法や、コーディング時の責務を意識するといった小さいレベルでも適用できるのではないかと思います。

また、Modelの説明で「解決したい問題領域から必要だと思われる情報を記号化・可視化したもの」という捉え方の話も知りませんでした。必要ではない情報を削ぎ落とすこととほぼ同義であり、今までも意識的かどうかはわかりませんが、ある程度は実践できていたような気がします。 しかし意識することでモデリングをうまくできるような気がします。


クレジットカードの通信プロトコルISO8583と戦う

  • アクワイア
    • 利用できる店舗を増やす
  • イシュア
    • カード会員を増やす
  • 決済フェイズ
    • オーソリ
    • クリアリング(売上確定
  • ISOのパーサは各社独自の拡張を加えているので存在しない
  • 承認番号はイシュアが発行してコンビニのレシートに印字される
    • 返品時とかに利用してる

Q

  • 各社によっての拡張が変更される可能性はどうか
    • 半年に1回の各社とのMTGで事前連絡される
  • エラーハンドリングむずかしい?
    • 2重で処理しないようにするのは気を使っている
      • レスポンス返した時に、同じリクエストを処理しない
    • 不正なリクエストとかは?
      • 普通に弾く
        • 400
      • 買い物時はOKで、返品でフォーマットエラーの場合
        • 返品フォーマットエラーは大目に見る
  • 重要かどうかの判断
    • カード会社側に委ねられてしまっている
      • 大目に見る対応
  • 誤り訂正は下位プロトコル
    • 伝聞自体に機構は存在しない
    • 長さチェックぐらいはできる
  • 既存スタックと内製スタックで切り替える時は段階的にやった?
    • 10時間ぐらいメンテでデータ移行テスト向き先切り替え
  • テスト環境どうしてる?
    • テスト用アプリにテスト用データを入れると、いったんブランド側にデータ送信、レスポンスとして受け取る
      • ブランド側でテスト用データを本番に乗せることを許容しているってことか
  • ABCDICはいっかいユニコードに変換している?

感想

クレジットカードの電文などを扱った経験はないのですが、利用方法が危ういフレーム、重要度が先方に委ねられてしまっている状態、トリッキーなテスト環境など、他人事ではないと感じる泥臭い話でした。 自分たちのチームで裁量がない部分というものはどうしても発生してしまう事であるにも関わらず、どのように折り合いをつけていくのかはチーム固有のものであり、外部公開しづらくされづらい話のため聞けるのは嬉しいです。

こういった話はたくさん聞いた上で自分たちのチームの当てはめ、バランスの良い選択ができるように努めたいです。


Elixirを支える技術 -「落ちない」システムの秘密に迫る

  • Erlang(アーラン)
    • プロセス起動と破棄が軽量
    • 別プロセスへはメッセージ(Goのチャネルに似ている?)
  • Elixir
    • 実行前の抽象構文木の操作
    • フェニックスというライブラリ
      • ルーティング処理
  • 落ちないシステム
    • プロセスが落ちても他プロセスに影響しない
    • 別プロセスのエラーを検知できる
      • それをトリガーとしてエラー処理を書いたりできる
    • GCはプロセス単位
  • JIT
    • OSネイティブコードに変換する手法
    • 実行時に変換(ジャストインタイム)
      • traceingJIT

        Q

  • メモリ不足で落ちた時はどんな障害
    • 2Gのアプリで4G領域展開した
    • 大きめのメモリ確保したプロセスが長い間居座ってしまったりすることに気をつける
  • Elixir勉強で挫折した
    • 問題分割手法がわからない
      • ドキュメントとかライブラリのオススメ
        • Erlangであればある
        • すごいErlangゆかいに学ぼう
  • スーパーバイザーの設定
    • あんまり設定しないようにする
      • 下手に使うとパフォーマンスがおちたり
        • それでもできない場合のみ利用する
          • 再起動するだけに留める
  • マクロで標準文法を拡張できる
    • オレオレ標準文法は?
      • マクロ自体が賛否両論
        • チームの同意ないで頑張る
        • しかしElixirはコンパイルがあるのでまだマシかも

感想

Elixir自体をはじめて知りました。 私が触ったことのある言語はJavaC#Ruby、Swift、Go、JavaScriptでそのどれとも違う性質の言語であるとの印象が強いです。 とくにプロセスという単位を基本としていることが印象的です。 プロセス間のメッセージのやり取りはGoのチャネルと似ているとのことでしたが、常に非同期処理をコーディングしている心づもりなのでしょうか。だとすればすごく実装難易度が高い言語ではないかと感じてしまいます(Elixirのことを何ひとつ調べていない状態でこの文章を書いています。多分そんな難しく考えなくてもいいような言語設計になっているのでは?)。

次に学んでみたい言語はKotlin、Scalaと考えていましたが、Elixirも選択肢に入りそうです。


フロントエンドのつくりかた - シンプルなコードを達成するためのセオリー

  • 単方向
  • MVCはゲーム機のコントローラー・PS4・モニターの関係
  • MVP
    • Humble View(ハンブルビュー)(慎ましいView)
      • ユーザーがViewとやり取り
      • ViewがPresenterとやり取り
      • PがModelとやり取り
  • 重要なのはドメインプレゼンテーションの分離
    • MVW
      • ModelViewWhatever
      • 重要なのはモデルとView
        • つまり矢印の方向を意識することが大切なこと

           データ同期の仕方

  • モーダルでユーザーが内容を変更した時にサーバーとのデータ不整合が一時的に発生している
    • モーダル閉じた時点でサーバーにデータ送信
    • サーバーからもう一度データ送信する
  • こうすることでデータの整合性が保たれる

エラーハンドリング

  • エラーハンドリングはソフトウェアの使い勝手に密接
    • ユーザーが回復できるエラー
      • 拾うべきはこっち
        • クライアントのエラー
          • メールアドレスフォーマットエラー
          • パスワード間違い
        • サーバーのエラー
          • メールアドレスやユーザーのエラー(すでに存在している)
            • 画面の上部に複数エラーをまとめて表示する
              • フロントでサーバーから帰ってきたエラーをラップする
                • これをリストにしてHTMLでループさせてエラーをまとめて表示
                  • 場合分けをしっかりするのが大切!
    • システムエラー

コンポーネント構造

感想

Vue.jsは入門書を読んでみた程度しか経験がないのですが、普段サーバー側の言語で実践しているSRP(単一責任の原則)をきちんと意識して実装すると、○○地獄になりにくいのでオススメと言う話という理解です。

またSLAP原則というものがあり、これはざっくりいうとコードの粒度をあわせておくと見通しがよくなるという原則なのですが、Viewという変更が頻繁に起こるであろう領域においてこの原則も同時に意識しておくと詳細実装がある程度品質が低くても、なにか問題が発生したときのアジリティーがいい感じになることも合わせて主張されていたように思います。

QAの時間での質問がとても多かったのですが、サーバーサイドエンジニア的にはある程度浸透している考え方(上記の設計原則など?)がフロントエンドエンジニアには浸透していなかったりするのかな?と思いました。これは私がフロントエンドエンジニアではなく、また関わりもあまりないため感じるちょっとした違和感レベルかもしれないのでなんとも言えないです。

私の今のプロジェクトではSPAを利用していないのであんまりイメージが湧いていませんが、いざSPAを始める時に再度参照したい発表内容でした。