kbigwheelのプログラミング・ソフトウェア技術系ブログ

プログラミング・ソフトウェア技術系のことを書きます

JavaScriptのAsync/Awaitにかかえていた違和感

JavaScriptのAsync/Awaitの仕様を数年前に見たときからなにか違和感を感じていたのだが、以下の記事で改めて全体を見通した時にその違和感の元に気づいた。

【初心者向け】JavaScriptの非同期処理を理解する callback、Promiseそしてasync/awaitへ - Qiita

Promiseの結果を取得するためにawaitが必要なことは直感的にわかる。 問題はasyncだ。これは単に返り値がPromiseであることを示すマーカーであり、返り値の型を明示する必要がないJavaScriptの思想とはそぐわない気がする。 これは例えばPythonのyieldとよく似ている。yieldは返り値の型をGeneratorにするが、その関数へasyncのような修飾子をつけることはない。

幸いにも疑問点に気づけば回答はネットに転がっていた。

どうやらawaitが予約後でなかったことと、parserの解析が簡単であることからasyncが用いられているようだ。 その理由に納得はしないものの、とりあえずの回答が得られたのはよかった。

正しい意思決定(判断)の価値

disclaimer

以下の文章は私個人の意見であり、特定の企業や人物を揶揄する目的のものではありません。

本文

僕はプログラミングが好きでずっとプログラミングをやっていたせいか、エンジニアで手を動かさない仕事の価値というものが長いことよくわからなかった。 8年ぐらいのエンジニア生活の中で、合理的で効果的な意思決定がなされたシーンを実感してこなかったこともその一因かもしれない1

だからいわゆるアーキテクトや上流過程というものを結構長いこと軽視していたのだけど、以前こんなことがあった。 過去のある時点でAWS上にEC2で動くアプリケーションを作ったのだけど、実はそれに相当するサービスが開発開始当時からAWSに存在した。 そちらを使えば内製するより運用費が安く、4~6人月を投資する必要がなく、保守の手間も全くかからなかったことが発覚したのだ。

言い換えればこのアプリケーションを自分たちで作ると判断した人間は数千万をドブに捨てたわけだ(AWSについての知識がなかったがために)。 だから、(もちろん考え方にもよるが)このときAWSのサービスを知っておりそれを使うという判断が出来たら数千万円を使わずに済んだことになる。

これに気づいたとき、僕はこの意思決定には数千万円分の価値があったと言えるのだろうか?とふと思った。

こんなことがあってから、僕は意思決定についての価値をもう少し考えるようになった。 現在自分が行おうとしている意思決定がどれくらいのコストを生むか(一時的コスト・継続的コスト)、それが将来的にどれくらいの利益を生むか(短期的な利益・長期的な利益)。

そうして考えながら仕事中に意思決定をしていると、この意思決定というものが思っていた以上に危険なことがわかった。もちろん会社がどの分野・どの部署・どのプロダクトに投資するのかといったことは重要な意思決定なのは自明だが、僕のような平のエンジニアでさえ、何気ない判断で会社に長期に渡って数千万、数億の損失を生む意思決定ができてしまう。

ソフトウェアエンジニアの間違った意思決定の多くの場合現金ではなく、将来のエンジニアリングコスト(人・時間)であるため計測しづらい。結果的に多くの会社でそういった損失は計測を行わず振り返りも反省もなされない2。そのため大手IT企業などでも正しい判断基準を持たずランダムウォークするようなアーキテクト・マネージャが散見され、数億や数十億以上のコストを見えずに垂れ流したりあり得たはずのサービスの可能性を潰したりしている。

そう考えると、もし意思決定を適切・慎重に正しく行えるものがいてその人物が継続的に意思決定を行えば会社はたくさんの潜在的損失を回避できることになる。 僕は従来マネージャや管理職・アーキテクトといった立場の人間を軽視していたが、上のような人物がいればその利益は計り知れない。

それこそ業務時間の90%でコードを書いて残り10%で間違った意思決定をしてしまうプレイングマネージャーよりも、業務時間の98%寝ていても残りの2%の時間で正しい意思決定をしてくれる優秀なマネージャーははるかに会社へ貢献していることになる。

だから、僕は相変わらずコーディングが好きなことは変わらないけども、最近は自分の意思決定そのものや自分以外の意思決定する人物・役職のことを見直している。 果たしてその意思決定(者)が本当に正しく、長期的に見て正解だったと言えるかどうかを。


  1. むしろ記憶に残っているのは知識の足りていない人間が間違った方向に意思決定してしまった場面ばかりだ

  2. 余談だが、そのため一部のエンジニアは意識的か無意識的かわからないが間違った意思決定のツケを払う数年後には転職していなくなってしまうようなことが常態化している。ウェブ業界では特に顕著だ

会社の開発用PCをMacBook ProからデスクトップPC(ubuntu)へ切り替えた

tl;dr

  • 会社で使うPCをMBPからデスクトップPC(ubuntu)へ切り替えた
  • dockerがよりシンプル・高速に走るlinuxが今は良い
  • 自宅もubuntuなのでショートカットキーなどを揃えたかった背景も

もう少し長い背景説明

MacBookは素晴らしい。

まずbrewの信頼性が高い。 イケてる開発ツールが多い。WIndows, Linuxでも提供しているツールも多いがSequel ProなどMacでしか提供されていない素晴らしいツールも多い。 なにより利用者が多い & LinuxWindowsのようにディストリビューション/バージョン間の差異が少ないことから多くのノウハウがウェブ上にあり、周りに使っている人間が多いためヘルプも頼みやすい。 見た目もイケてるし、ミッションコントロールワークスペース間の移動などUIも洗練されている1

なぜやめるか。

一つは自宅で使用しているubuntuとショートカットキーやUIが違うことによる操作への最適化限界がきになったからだ。 ubuntuOSXではワークスペースの移動のキーなど多くのOS標準操作方法が違う。 そのためショートカットキーを覚えることが難しく、毎回設定を参照するようなことをしていた。 また、ubuntuではCtrlが使われるケースでMacはMetaキーを使うため、ブラウザ操作などショートカットを多用するシーンにおいて間違ったキーを押すことが多かった。 OSXのUIは明らかにubuntuより優れているため自宅のデスクトップをiMacないしMac Proにすることも考えたが、コストパフォーマンス面でPC/AT互換機と比べて格段に悪くまたMac Proが年単位で放置された過去を鑑みるとアップデートサイクルをこちらで制御しにくい点も欠点となり、自宅でOSXを使うことは断念した。

となると可能なら会社で使うPCをubuntuにしたいところだったのだが、ずっと諦めていた。 というのは以下の点で会社所属のエンジニアにMacBookを渡すことは合理的であるためだ。

  1. 会議室など自席以外でプロジェクタ・大型モニタを使う時にノートブックは有用
  2. MBPなどapple製品はブランドイメージが高くエンジニア受けも比較的良い
  3. エンジニア全体でMBPに統一するとトラブルシュートや(情シスなどによる)サポートが簡単
  4. 開発チームとしてもPCをMacBookに統一すると環境差がなくなり開発しやすい

が、先日MacBookによるコンパイルの重さ・HDDへのアクセスの遅さ・メモリの足りなさに辟易としているときに気がついた。

  1. うちの会社はMac, ubuntu, windowsバラバラ
  2. 退職者の比較的高性能なデスクトップPCが余っている
  3. 会社に私用のMBA持っていっているので会議用はそれで事足りる
  4. ローカル環境での開発にDockerを利用しているため開発環境の差が吸収できている
  5. CPU使用率を見ているとdockerの特にIO部分で負荷が高いが、これはDocker for Maclinux VM内でdockerを動かしているため。linuxで直接dockerを動かすとこの負荷はかなり軽減できる(はず)

以上のような理由でむしろubuntu(linux)を使わない理由がないことに気がついた2

現在ほぼubuntuへの移行が終わった状態だが、メモリやCPUなどが相対的に強化されたこともあり非常に快適に感じている。 特にDocker周りの動作が非常に軽く、レスポンスが早くなった。

MacBook Proからubuntuに移ったデメリット

当初は特にubuntu移行のデメリットはないかと思っていた(UIが劣るのは織り込み済み). が、最近徐々に手を出し始めていたxcodeによるiOSアプリ開発ができないことは少し頭が痛い。 手元のMBAは非力で開発にまったく使えないため、この点に関しては何らかの対策を打つ必要がある。

一般的な新卒ソフトウェア系エンジニアにとってUbuntu(Linux)は第一選択肢になるか

たぶんならない。僕がubuntuを使えるのは所属している会社がスタートアップで各々の裁量が大きいこと、特にソフトウェアエンジニア内でMacBookに揃えようという方針がないこと、ubuntuの経験がそこそこあり他人を頼らなくても自力で大抵の問題は解決できることなどが背景にある。

新卒や大企業のソフトウェアエンジニアの場合、いろんな要因でapple製品に統一したかったりするメリットがある。そもそもMacBookが強い会社は新卒もMacBookを使ってくれたほうが教えやすいし教えてもらいやすい。

ただ、今後長いことソフトウェア技術の核となるdockerがmac上では遅いというのは軽視できないデメリットで、Dockerを効率的に使う視点から長期的には開発PCでもlinuxの利用が増えていく可能性はあると思う3


  1. ubuntuではウィンドウ毎にワークスペースを分けて管理することができない。ショートカットも統一された方針を持たず、キーバインドのコンフリクトがしょっちゅう発生する

  2. 新卒のときにwindows機でのweb開発に苦しみ、MBPでの快適さに感動した経験から視野が狭くなっていたのだと思う

  3. linuxはもう少しUI・UXがなんとかならないとエンジニア間ですら支持が広がらないかもしれないが

@kmizuさんのimplicitlyについての記事を読みながら思い返したこと

この記事を読んでていくつか感じたことと思い出したことをツールドフランス第15日目観戦しながら書き出します。 特にまとまってない。

記事中の黒魔術という表現についての個人的な補足

僕の勘違いでなければ、@kmizuさんは implicitly が静的に(コンパイル時に)一意に決定する、しかもそれがメタプログラミングやマクロ・リフレクションなどのコンパイル処理の外側ではなくコンパイル処理(= ファーストレベルの言語仕様1)として決まる点を指して黒魔術ではない、と行っていると思いました。

ただ、implicitlyを黒魔術的だと認識しているような人にはそこら辺の文脈・ニュアンスが伝わりづらい気がして非常に良い記事だけに少し惜しく感じました。

implicit parameterと型クラスの親子関係

おそらく、 implicit parameterという概念(もしくは、その元ネタである型クラス)

implicit parameterって型クラスから派生した概念でしたっけ?と少し引っかかりました。

implicitは特に型クラスを意識せず実装されたけれど、後々型クラスにも使えることがわかったために型クラスの表現方法としてimplicit + context boundが利用されている、とどこかで読んだような (もしかしたら説明を単純にするためにあえてこう書いているのかも)。

2019/07/26 追記

@kmizuさんにその後詳しく教えていただいたのですが、広く一般には知られていないものの紛れもなくimplicit parameterは型クラスのための機能として作られたとのこと。

詳細はこちら。

implicitlyを理解することの困難さ

元の記事は簡潔にまとまったスクロール3画面分ほどの記事なんですが、僕はここで説明されていることを完全に理解できるようになったのは真剣にScalaを触り続けて3,4年経った後だったと思います。

この記事の中ではimplicitlyに到達するまでの道のりがだいたい以下のように提示されています2

  1. implicitの使い方・作用
  2. context boundの意味
  3. implicitlyの使い方・作用

Haskellなどのバックグラウンドのない、Javaを触ったことのある程度の人間(だいたい10年前の僕)がもうちょっと補足するとこうなります。

題目 僕が理解した時期(Scala使い始めからの年数) 理解にかかる労力
implicitの使い方・作用 1~2年 めっちゃ大変
context boundの意味 3~4年 型クラスを理解していると一瞬。 理解していないと使い方・概念がさっぱりわからない
型クラスの概念 4~6年 大変。数回の挫折をはさみつつ足掛け5年かけてすごいHaskellたのしく学ぼう!独習 Scalaz — 独習 Scalazで理解した
implicitlyの使い方 1 ~ 2年 それ自体は死ぬほど理解が単純。
型クラスとしての使い方に気づいたのは型クラスを理解した後だった

上に書いていますが、僕が元の記事をだいたい理解できるようになったのは型クラスをぼんやり理解し始めた4年目以降でした。

こう書くとお前どんだけ頭悪いんだよと思われるかもしれませんが、実際のところ3つの職場で一緒にScalaを書いた同僚諸氏で確実に僕より早く・より深く上を理解していたのは10人中2,3人程度でした。 勉強への熱意や理解の早さはともかく、実際にScalaを使っている人でもかなりの人がimplicitやcontext boundなどをよくわからず使っている、またはそれらを知らなくても十分Scalaを使えていると思います。

implicit は本当にわかりにくい

改めて考えるとscalaのimplicitは本当にわかりにくいと思います。これはimplicitに多数の側面やシンプルでない仕様があるからだと思います。 以下implicitのわかりにくい点。

  1. 文字通りの暗黙的な関数パラメータという側面
    • sttpのbackendのような、メソッド呼び出しの中で本質的ではないパラメータをメソッド呼び出しへ書かないことでよりメソッドの本質に集中する機能
    • implicitで渡されるパラメータは環境・コンテキストなどのイメージ
    • 多用により可読性の低下を招くと言われていたimplicitはこの用法のイメージ
  2. 型クラスとしての活用の側面
  3. implicitという修飾子がメソッドの外側・内側両方で作用する点3
  4. implicitが探索するスコープのルール
    • 暗黙のパラメータ解決優先順位 | eed3si9nがよくまとまっていますが、継承、import、local宣言、パッケージオブジェクトなど片手に余る様々な方法でimplicitの値は渡すことができます
    • Scala熟練者が多用するにも関わらず初心者が知らない概念の一つに暗黙のスコープ (implicit scope)があります

      2) 探している implicit の型に少しでも関係のある様々なコンパニオンオブジェクトやパッケージオブジェクトから成る暗黙のスコープ (implicit scope) (具体的には、型のパッケージオブジェクト、型そのもののコンパニオンオブジェクト、もしあれば型の型コンストラクタのコンパニオン、もしあれば型の型パラメータのコンパニオン、型の親型や親トレイトのコンパニオンなど)。

結論

何が言いたいか。

1. implicit / context bound / 型クラス / implicitly わからないのは当たり前

それらがすぐにわからないからと言って、自分が頭が悪いと思ったりScalaに絶望しなくていもいいと思います。これらの概念は広範に普及しているプログラミング言語の中でもかなり難しい概念ではないかと。

2. implicit なんて全く使わなくても better java としてそこそこ使える

過去にimplicitもFutureもモナドも使わないScalaによるAPIサーバをScala初心者の人たちと一緒に書きましたが、Future・モナド・implicitを半端な理解で乱用したアプリケーションより10倍良いコードでした このように単なるbetter javaとしてscalaを使うことは全然ありだと思います4

3. implicitly が黒魔術に見えている人はimplicitly以前にimplicitそのものや型クラス、型クラスを実現するためのcontext boundというsyntax sugarという概念がわかっていない

ここで話が最初の記事に戻ってきます。 元々の記事は非常によくまとまっていて内容は正しいのだけど、最低でもScala数年触っているような人じゃないとあれ読んですぐ理解するのは難しいんじゃないかと思いました。

4. 型クラスはちゃんと理解したほうがいい

implicitはScala 3でなくなるそうですが、型クラスの概念は多少変遷しうるもののおそらく今後20年, 30年以上プログラミング技術の中で使用される可能性が高いです。 すごいHaskellから逃げずに(!?)頑張って勉強しておきましょう。それにより得られるリターンは本当に大きいと思いますし、実際大きかったです(プログラミングの表現の幅が広がった)。


  1. これ、もうちょっと適切な言い回しがある気がする

  2. 実際にimplicitlyだけを読み解くならこの全道筋を理解する必要はないけど、記事中で言及されているようなcontext boundのsyntax sugarと組み合わせた用法を理解するにはたぶんすべてを理解する必要があるでしょう

  3. 参考: implicitが内向き外向き両方の意味になってしまっている。

  4. 最もこのようなケースではJavaでいい気もするのでケースバイケース。特にScalaはリクルーティングがしづらくて・・・

ヘビーカロリーな問題の解決方法

この前、久しぶりに非常にヘビーカロリーなコードを書いた。 僕は普段コーディングをしている日はScalaの場合テスト含めて100~300行程度のコードを書いているのだけど、機能まで書いていたコードは5~10日で100コード程度しか書いていなかった。 というのも内容がhttp clientの低レベルな実装とAWS V4 signatureの実装に関するコードで問題がかなり難しかったため。 この問題、そもそも自分で解決できるかどうかギリギリレベルの難易度だったのだが、なんとか解決することはできた。

ここでは後のためにその解決方法を言語化しておく。

1. 何が問題なのかをはっきりさせる

今回の場合、根本的に何が問題なのか、何ができないのか、何をやればいいのかを調べだすのに丸2日分ぐらいの時間がかかった。 資料が少ないためでもあったが、まず問題の原因をはっきりさせることは基本であり絶対。 ここがあやふやなママ試行錯誤しても効率は上がらない。

2. 取りうる手段を列挙・検討する

取れうる手段を検討する。 今回の場合は既存のライブラリを頼ることが難しいことがある程度調べてわかった。 その結果、妥協して定期作業が必要な認証にするかそれともきちんと自分で実装するかの選択肢が出た。 最終的に後者を選んだ。

上長やチームへ説明するためにもトレードオフできる選択肢を出すことは大事。 それで自分がしようと思っていた以外の選択肢が選ばれたり新しい選択肢が出ることもままある。

3. 実装したつもりが動かない。

まず絶対に動く例を作る。例えば今回のケースではpythonのサンプルコードが会った。 まずそれを動くようにして、徐々に動かないコードと近づけていって、どこで動かなくなるかを調べた。

スクラムマスター研修受けてきた

取り急ぎまとめ。

  • 昨日・今日の2日でスクラムマスター研修を受けてきた
  • 目的はスクラムを導入しているがイマイチうまく言っていない現在のチームの改善、人にスクラムを教わることでよりよいプロセスにできるのではないかという期待
  • 基本的に自分のキャリアのためであること、会社を説得することが面倒であること、そもそも会社が出してくれそうにないこと、また取得後数ヶ月で転職するとさすがに申し訳ないこと(今のところ具体的な転職予定はないが、申し訳無さで転職の選択肢が取りづらくなることを嫌って)私費で行った
    • 税込みで計216,000円也
  • 結論から言うと非常に良かった
    • 一番良かったのはたぶん30~50回行われた参加者とガビィ、原田氏とのQ&Aで、スクラムガイドや一般的なスクラム本で語られないところ、語られても深くは掘り下げれらないところを細かく、背景を交えつつ聞けたところ
  • 参加者のやる気も非常に高かった。AWSの公式講習を受けたことがあるが(こちらも1回2~3日、20万円ぐらいかかる)、ずっと参加者のやる気は低かった
    • 実際に体を動かしたりポスターを作るなどよりアクティブなアクションが多かったのがよかった理由の1つ
  • 参加者の背景も多様で面白かった。組み込み系企業のいわゆるテックリードのように、新しい手法・技術を指導する立場にある人、会社の資格取得推奨制度をきっかけに来ている人(AWSの資格コンプリーター!)、技術コンサルをされている社長さんで、コンサル先でスクラムを指導できるように来た人など
    • 女性の参加者は全体の1/6~1/5ぐらいに見えた(6人チームに平均1人いた感じ)。比較的ソフトウェアエンジニアリングの世界より女性比率が多いように感じたが、講師が女性であるため参加しやすかったのかも
    • 年齢層も幅広く20代から40代までいた
  • たくさん勘違いや心得違いも見つかった。ごく単純な誤解から、背景を理解せず字面だけを読んだ結果真意を理解していないケースまで
  • 基本的に引きこもり・出不精なので、1日目はすごく緊張した。同じチームでやった2日目になるとだいぶお互いの人柄の理解が進んで話がしやすくなった
  • 1日目も2日目も無茶苦茶疲れた。頭いっぱいでへとへとになって自宅に返った感じ。自分は参加者の中では比較的長くスクラム(あるいはスクラムのようなもの)をしていたほうで、キーワードだけは比較的知っている方だったのにそれほど負荷が高かったので、よりスクラムに親しんでいない人はもっと大変だったかも

以下取ったメモから順不同で書き出す

  • 絵を沢山書こう
  • リファクタリングはストーリー(タスク消化)の一部。タスクと分離しない。恒常的なリファクタリングの時間をタスク見積もりに含める。恒常的にリファクタリングをする
  • 大規模チームでも編成できる。車のファームウェアのチームなどは数百人単位
  • walking skeleton
  • リモートスクラムを最初からやるのは難しい。合宿あるいはonboardingで最初しばらく一緒に仕事をすると成功しやすい
  • output ではなく outcome(機能数より具体的な成果)
  • chaos reportによると80%の機能はほとんど使われていない
  • チームがこなれてくるとスクラムマスターはお互いのタスクを交換して苦手なタスクをやらせる
    • 一時的にベロシティが下がることを許容する。しかしその後よりチームは強くなる
  • 弁当が美味い
  • スクラムマスターはポストイットが基本、jiraなどのツールを最初から使うとツールに踊らされる
  • スクラムマスターはあくまでコーチ的。開発メンバーに指示をせず、解決策も直接提示しない
  • 不要だと判断された機能はきちんと削除する
  • スクラムは経験主義をバックグラウンドとしている
    • 経験主義については個人の経験に基づいての判断ではないことに注意。ここはもうちょっと読んで理解したほうがよいかも
  • CIは重要。完成の定義をストーリーごとにクリアするにはCIで自動化しないと現実的ではない
    • 一方でCIに関するタスクをそのままPBIにしないこと
  • アーキテクチャの改善やサーバ・環境の用意、ホワイトボード・付箋・部屋・PCの用意などはスクラムで規定されていない。それらはスプリント0として扱うような方式もあるが、原田さんはあまり推奨していない。あくまでスクラム開始前に用意しておくこと。
  • 未完了は再見積もりをしてバックログに戻す(つまり未完了になったタスクのベロシティは行ってしまうと失われることになる)
  • スクラムマスターはドミナントにならないよう、必要であれば会議を意図的に欠席したりincognitoしたりする
  • 特に初心者のスクラムマスターは開発メンバーと兼任するべきではない
    • 最初のX日(1週間だっけ?)はチームを観察する、よく観察する
  • やる気のないメンバー、スクラムに反対するメンバーなどに対する手法は基本的にスクラムは規定しない
    • それらはスクラムの外側で対処するべき問題だが、やる気のないメンバーはスプリントごとのデモで自身を取り戻させることができるかもしれない
    • プロダクトオーナーが協力的でない場合は、開発メンバーはビーチに繰り出す
      • 不要な機能を作ることはむしろ害悪。削除に追加でコストがかかる
      • プロダクトオーナーがPBを持ってくる来る時に備えてビーチに繰り出し英気を養うのが開発チームの最善
    • スクラムの反対するメンバー(デイリースクラムに参加しない、など)はチームから一時的に取り除くなどの対処を取る
  • 上にも関係するが、あくまでスクラムはプロダクトマネージメントのフレームワークであり、開発で発生する問題や意思決定すべてに関する回答リスト・規定ではない
  • プロジェクトマネージメントではなくプロダクトマネージメント
  • トヨタの片山さんいわく、イテレーション(繰り返し)ではなく改善のサイクル
  • スクラムマスターとしてはチームに干渉しすぎない。自分たちで問題を発見させ、答えを聞かれたら5 whyメソッドを使って自身に考えてもらう
  • 見積もりがあんまり大変なので、最初はS, M, L, XLの4つ程度に分ける
    • それぞれSP3, 5, 8, 13に割り当てる うまくいくチームがある程度パフォーマンスを出すまで3ヶ月(原田さんのいうある程度のパフォーマンスってどのレベルのイメージだろう?)
  • 2,3ヶ月ごとに2,3名入れ替わるようなチームは安定度が足りない
  • 完成の定義はすべてのPBIに適用される汎用的なもの。acceptance criteriaはPBIごとのもの
  • Goalはステークホルダーからわかることが重要
  • CXOがスクラムに不安を感じている場合は、とりあえずミニマムで試してみることが重要
    • 一方でスクラムが成果を出すまで一定の期間が必要なので、スプリントごとのデモでステークホルダーや開発メンバー自身に手応えを掴んでもらわないと続けにくそう。
  • 優秀なスクラムマスターは日本人的シーンで場が凍っても待つ。いくらでも待つ
    • たぶんそこで待たないとメンバーは責任感を持たず、自主的に動かないからだと思う
  • 報酬制度を個々人でやるのは危険

講義中のメモ

iot企業ハードウェアチームとの連携 絵をたくさん書く

先行しているプロダクト、リファクタリングが必要。 プロダクト要求を進められない。

手分けしやすい、スケールしやすい、 なんでわけるの? PM以内の大丈夫? 大規模チーム? スケールスクラム 早めに手に入る。 要求分析 今は発注側がしんどい スクラムのメインフィールドはイノベーション イノベーションは外注できない

walking skeleton

scrum of scrum

遠隔地は最初からは難しい、一度一緒に飯を食べて、しばらく仕事をすると、リモートにしても成功しやすい。

outputではなくoutcome chaos report

機能数より成果 最初からチームで機能横断的である必要はない、レビューを繰り返すとフルスタックチームになる。

旧来のチーム、前職のようなチームではどうする? スクラム部署を小さく作り始める。デンソーの例

スクラムマスターはいつかけしかける、自分の苦手なタスクをする。

挨拶、ボールゲームで推測の難しさ、 スクラムイベント、うまい弁当、アジャイル宣言

リスクに対するテクニック、ウォーキングスケルトン 細かく作る。 シンプルなケースを作る。 80%の人を救うケースを作る、それがウォーキングスケルトン。

そもそもの問題が見えてない、マネージャーがこない?部屋がコンフリクト?

プロダクトバックログ、あまり長過ぎると管理が大変。 せいぜい100個が上限 でもの重要性

リファインメントはスプリントの10% 2週間でクソみたいなものを出すのは大事。 工数感を共有できるから。

スクラムマスターはポストイットでマスターする。

経験主義は科学分野から

POの最大の価値はプロダクトバックログ

リファクタリングをプロダクトバックログに入れろ、普段のタスクでリファクタリングしろ

機能は削除しろ。

デザイナーのためのCIを回して、積極的に参加してもらう。 チームに参加してもらう。 CIがキモ

セキュリティアーキテクチャ設計書に連絡先を書いてこちらです、にしておく

SIヤーではお客様はプロダクトオーナーではない。プロダクトオーナーは社内で建てる。 お客様はステークホルダーに過ぎない。

featureフラグでdoneにする。 デプロイは開発が任意。

プロダクトバックログには誰でも突っ込める。 優先順位を入れ替えられるのはPOだけ。

二日目

未完了は再見積もりしてバックログに戻す

デイリースクラムはマスターに報告しがちなので、マスターは隠れるなど メールが来る、登録する、日本語と英語がある、50問か30問かわからない、4択、制限時間は1時間、二回受けて2回とも落ちた人は居ない。72%で合格

ドラッカーもdone is better than doing

特に初心者のスクラムマスターは開発メンバーとも兼任するべきでない。 プロダクトバックログはvalidate 開発チームはバックログ通りに作っていることを保証するべき イテレーション、繰り返しではなく改善のサイクル、トヨタの片山さん曰く

優秀なスクラムマスターは待つ。気まずくても待つ。

スクラムマスターとしてチームに干渉し過ぎない。責任をチームに持たせるため、自ら解決させる。

    でも、そうするとスクラムマスターはやることなくない?

プロダクトオーナーが休み、病気は代理を立てる。

ビーチに行っていい?

どこまでやるんだっけ、はプロダクトオーナーと相談

3,5,8,13をSMLXLに割り当てる

high priorityかつXLは潰す。

環境構築のような機能に直結しないタスクはどうなる?

スクラムはプロジェクトマネジメントの手法ではなくプロダクトマネジメントの手法

上手く立ち上がる3/2のチームがある程度パフォーマンスが出るまで3ヶ月ぐらい。 二、三ヶ月ごとに2,3名入れ替えるのは安定度が足りない。

product ownerはend targetを決める。

今、definition of doneは完了の定義ではなく完成の定義という訳語にして曖昧さをなくした。

完成の定義は、汎用的なもの。 acceptance criteria はPBIごとのもの。

サーバの用意やインスタンスの用意はスプリント外で事前に用意する。

Goalはstake holderからわかることが重要

リファインメントはミーティングを短くする

CXOの不安を解消するため、試してみる。

試作品でもwalking skeletonを作る。 ソフトウェアでハードウェアがきちんと動いていることをテストするようにすれば、すごく高速に設計できる。 あとシミュレータをガチガチに作る。 スプリントを回すため、

何がやりたいと聞く。 報酬制度は個々人でやるのは危険

5 whyはガビーもやるテクニック

これはと思ったら、病院へ

結果整合性を使うということはDBで正規化を捨てるということだと君は理解しているか

以下、数ヶ月もんもんと考えていてなかなかアウトプットすることができなかったので自分語り交えながらとりあえず出力することにした。 読みづらいのは勘弁願いたい。

なるほど、これがDDDとしての模範解答なら僕には数ヶ月考えてもたどり着けなかったのに納得がいく

数ヶ月ほど前、アドベントカレンダーに参加したときに以下の記事を書いた。

集約の境界と整合性の維持の仕方に悩んで2ヶ月ぐらい結論を出せていない話 - kbigwheelのプログラミング・ソフトウェア技術系ブログ

そうしたところとても多くの人に反応を頂いて、自分としても一応の結論を出すことができた。

「集約の境界と整合性(略」に対して頂いたアイデアの分類と現状での僕の回答らしきもの - kbigwheelのプログラミング・ソフトウェア技術系ブログ

このとき多くの人の意見を読ませてもらい自分の結論に至って考えたのは、この結論は自分一人で考えていては絶対にたどり着けなかったということだ。

僕がどの解法を自分の結論としたかは上の記事を見てもらうとして、なぜ自分一人ではたどり着けなかったというとこの結論が正規化していないテーブル構造だからだ。

テーブル構造の正規化

テーブル構造の正規化、およびそのパターンについては他の記事・サイトに説明を譲るとして*1、 使わないほうが良い説もそこそこ聞く外部キーと比べてDBの正規化がアンチパターンだと語る話はほとんど聞いたことがない。 テーブルの正規化はRuby系のDRYにも似た概念であり、無駄なデータの重複を作らないことは更新漏れを予防したりデータ保存効率を上げたりする点でも勧められるよい設計方針だ。 RDBMSでの正規化はOOP系のプログラミング言語とのインターフェイスインピーダンスミスマッチを起こす要因として 挙げられることはあるものの、我々プログラマーRubyActiveRecordやORマッパーの機能、時には自分たちでDAO/DIOを書くことで そのミスマッチをプログラム側の努力で解消してきた。 それはそれだけDB領域の正規化を重要視してきたからである。

通常1対多のテーブル関係がある場合、多の方のカラムに1の方のIDを持たせるだけでよい。 データ保存効率がよく、また間違って多対多の関係になってしまうことも防げる。良いことづくめである。 たびたびで恐縮だが、上記リンクの回答編、最終的な結論ではDBを非正規化する解法を選択している。 なるほど、その選択肢は僕の頭には一切なかった。

なぜRDBMSを使用しているにもかかわらず非正規化しているのか

端的に言えばトランザクション境界をスパッと切るためである。 上の例で言うと組織集約とユーザー集約は別の集約(=リポジトリ)でありトランザクション境界で別れている。 DB正規化の観点からすればどのユーザーがどの組織に属しているかはユーザー側のテーブルで管理するべきだが、 オブジェクト指向、というかDDDの集約(リポジトリ)の見地からすればそれは組織集約の方で管理するべきなのだ。 1対多の関係が多対多になるリスクを負うことになるが、それでもである。

結果整合性を使うということはDBで正規化を捨てるということだと君は理解しているか

私は今までごく少数の例外(forgeign keyや論理削除・物理削除)などの問題を除けばRDBMSの基本原則を信奉していたし、 インピーダンスミスマッチを認めつつもそれはプログラム側で努力して解消するもの、または工夫により解消できるものと信じてきた。

特に正規化については重複を避けるプログラミングの原則にもマッチしているし、RDBMSを使う根本理由であるとすら思っていた。

その考えが今揺らいでいる。

慣習的に従いたいのは正規化の方針だ。しかしDDDとIDDDを読み、多くの先達の意見を聞いた今理性は正規化を捨てるときだと言っている。 実際そういった思いでDDD・IDDDのリポジトリトランザクションの章を読むと正規化を捨てるという案は全編で肯定されている。 DDDに従うならば、必要に応じて正規化を捨てるという手段は当たり前のもののようである。

しかし、思うのだ。 我々は主にウェブプログラミングへマッチさせるために外部キーを捨て、論理削除の概念を生み出した。 この上正規化を捨てるとなるともはや使っているRDBMSの機能のほうが少なくなってくる。 集約でトランザクション境界を切るとなるとJOINすることも稀になるからだ。 もはやこの用途ではRDBMSよりスキーマ強制されるNoSQLを使うほうが用途にあっている気さえする (CQRSでJOINをフル活用する必要がある場合はRDBMSが生きると言えるが、あれは邪道な気がしてどうにもまともに捉える気になれない)。

DDD本にも何度か出てくるが過去オブジェクト指向DBというものが何度も考案されては実用化できずに消えていった。 しかし、このDDDに沿ったリポジトリ実装だとどうにもこのオブジェクト指向DBというものが最適な気がしてならない。

我々は、ドメイン領域と外界とのインピーダンスミスマッチを最小にするため、ソフトウェアエンジニアリング史何度目かのオブジェクト指向データベースへの挑戦をするべきなのではないだろうか。

蛇足

今回の経験で、結果整合性を使うために集約間でトランザクション境界を切る場合は、それぞれのテーブルを別のスキーマ(MySQLなんかだと複数スキーマ間でJOINなどできてしまうが一旦それはなしと考えて)に置くとしてテーブルを設計すればいいことに気がついた。

*1:実際のところ他人に説明できるほど理解していないのである