コードを書いていると後から改善点に気づく

1時に寝て7時に起きた。起きてからドラクエタクトをだらだらやってて10時前に起き上がってそれからオフィスへ行って活動してた。

リファクタリングのリファクタリング

昨日書いたマージリクエストの変更点についてドキュメントの更新だけしようと作業していたら、その後、一緒に修正した方がよい追加の機能拡張に気付いて3時間ほど追加の実装をしていた。その後、お昼ご飯を食べているときに午前中に書いた実装を改善した方がよいところに気付いて、さらに追加で1時間ほどリファクタリングしていた。コードを書いていて、一旦はできたつもりになってその時点ではよさそうに思うのだけど、時間が経ってから考え直すと考慮漏れやもっとよい実装のアイディアを思い付いたりする。私の頭が悪いだけかもしれないが、最初からよい実装や設計を行うことは多くの人にとって難しいことだと思いたい。何度も考えて作り直したり改善したりしているうちにもっとよい方法に気付く。

多くの開発者はもっとよいアイディアを思い付いたとしても実際にリファクタリングをしようとしない。動いているコードを修正して壊れるリスクや他に優先度の高い作業があるとか、いろいろやらない理由を言う人たちもいる。私はそのやらない理由を議論している合間にリファクタリングしてしまう。というのは、誇張した比喩で実際にはもっと時間がかかることもあるけど、設計も見直す数千行レベルの変更を気軽に行う。もしそれで壊れたらどうすると聞かれてもシンプルに謝るだけ。謝ってから直す、テストを書く、再発防止のための仕組みを考える。やることはそれだけ。問題のあるコードを見て見ぬ振りをする開発者の方が普通という感覚がある。10年以上開発をやってきて思うこととして、そういう価値観を上位の開発者が壊していって模範を示すことがよい開発文化への第一歩となる。しんどいことに対して口だけでは人は動かない。個々の開発者が問題だと思ったらどんどん書き直していく、リファクタリングしていくという文化は一朝一夕ではできない。そういう開発文化を醸成していくと大きな技術的負債が溜まるといったことはなくなるのではないかと考えている。

リファクタリング一段落

1時に寝て7時に起きた。前日も21時頃までオフィスにいて、今日も午後からコードを書いていて22時ぐらいまでやってた。コードを書いていると時間がどんどんなくなる。本当は三宮.dev の勉強会があったんだけど、このリファクタリングは週末にやってしまわないとやばいという野生の勘でキャンセルした。

ストレッチ

今日の開脚幅は開始前156cmで、ストレッチ後160cmだった。だいたいいつも通り。先週から右すねの外側の筋に張りがある。先週よりちょっとよくなった気もするけれど、まだ張りが継続している。あと今週は右腰に張りがあった。今週はリファクタリングしていて座ってきる時間がいつもより長かったためだろうと推測する。どんなに忙しくてもストレッチだけは休まないようにしている。ストレッチに通い始めて2年以上経つが身体的に体調が悪いということは記憶にほぼない。日記にはその週のどこそこに張りがあるとか調子が悪いといったことを書いたりしているが、それは日常生活を送る上で支障が出るようなレベルではない。そうならないように予防している。健康を維持する上でストレッチは大きな影響を与えているため、中長期の展望から忙しくても継続するようにしている。

機能拡張とリファクタリング

今日は休日出勤して go のコードを書いていた。ある機能を作るときに内部的には汎用の api にしてしまって他のコレクションのデータ型でも再利用できるようにしたい。先週ずっと go の generics を使って mongodb 周りのコレクションとそのクライアントのリファクタリングをしていた。go の generics の理解も進んで crud なインターフェースを generics でどのように定義して実装すればいいかわかってきた。その過程で web api のアプリケーション層と mongodb のインフラ層 (データ層) の役割分担も明確になりつつある。どちらも generics を駆使して型チェックされた上でソースコードを共通化し、汎用 api としてリファクタリングしながら設計している。その集大成としてアプリケーション側で汎用的な機能を追加するときに、理想的には1つのコードを追加・変更すれば、別のデータ型でもすべて同じように動くといった機能として実装した。4つのコレクションのデータ型で同じ振る舞い (機能) を共通化する。その実装も丸1日やれば完了できるぐらいに設計の効率化ができてきた。

go はオブジェクト指向言語ではないので generics を駆使しても、java でいうところの抽象既定クラスを用いたテンプレートパターンの実装ができない。それぞれの構造体で基本的にはコピペとなる構造体のメソッドを定義しないといけない。もちろん別のヘルパーに移譲するといったことはできるけど、状態をもっていないコードの再利用はたしかに安全ではあるけれど、状態を参照できないからそのために値をコピーするといった整合性の懸念やボイラープレート的なコードを書く必要がある。これは設計におけるトレードオフになるので go の処理系の設計に不満があるわけではない。但し、generics でできることにはまだ機能不足がある。とくに直和型の扱い。できないのかな?とググると proposal の issue がみつかるので今後の機能拡張に期待したい。

正直マネージャーが開発に工数使っていて何やってるんだとみられているかもしれない。1-2週間集中してリファクタリングしてみて、いまのアプリケーションの設計の勘所が以前よりも理解が進んだ。コードレビューだけではわからないフィードバックがある。結合テストもいくつか追加したので今後の開発で役に立つはず。これで私の (リファクタリング) 開発は終了しようと思う。

今日作ったマージリクエストの diff が次になる。

51 files +1314 -648

diff の行数だけ数えると今週だけで1万行近くは変更したと思う。

mongodb のトランザクションの考え方

1時に寝て8時に起きた。3時頃に気分悪くて起きて少し吐いてそれからまた寝た。丸1日機能拡張とリファクタリングのために go のコードを書いていた。

mongodb のトランザクション管理

2つの web api から同じコレクションの異なるフィールドを更新したい。mongodb で厳密なトランザクションを管理するようなアプリケーションではないけど、なるべく整合性を維持できるように努めることはやっておきたい。mongodb でトランザクションに近いことを実現する方法として次の記事が参考になった。

この記事では findOneAndUpdate() という api を使って、更新時に必ず変更されるフィールドを含めることで find したときのそのフィールドの値が変わっていればエラーになってくれることでトランザクション相当の機能が提供されると書いてある。必ず変更されるフィールドとして ObjectId を使えば他の更新処理を検出するのに役立つだろうとある。いま私が開発しているアプリケーションでは同じフィールドを複数の web api から更新するわけではないのでここまで厳密なトランザクション管理は必要にない。

既存の処理が Replace を使って実装されていたのを Update を使うように変更する。Replace と Update の違いはドキュメント全体を更新するのか、一部のフィールドのみを更新するのかの違いになる。具体的には go のドライバーにおいて次のメソッドの使い分けになる。

これらのメソッドを使うことで find と replace/update の操作を1回の処理でできるから効率もよいらしい。

結合テストのリファクタリング

0時に寝て7時に起きた。前日は久しぶりに飲んでいい気分で寝てた。朝コンビニ寄ったらいつもほぼ満席のイートインが閑散としているなと思いつつ、オフィスへ行って始業報告して、今日祝日だよとツッコミもらった。全然気付いていなかった。まだ新しい天皇誕生日に慣れてない。

go のテストにおける setup/teardown 関数の実装

昨日から結合テストのリファクタリングをしていてせっかくオフィスに行ったので続きをする。結合テストだとデータを作ったり削除したりをテスト単位にやりたい。例えば、ユーザーを作成してテスト実行し、終わったら作成したユーザーを削除したい。次のように setup 関数を書き、返り値として teardown の関数を返す。このときに t.Helper() を呼び出しておくと、エラーがあったときにどの呼び出し元のテストでエラーが発生したかがわかる。

func setupUsers(t *testing.T, users []mongodb.User) func() {
	t.Helper()
	user := mongodb.NewUserCollection(url, username, password)
	for _, u := range users {
		if err := user.Save(u.ID, u.Attributes); err != nil {
			t.Fatalf("failed to create a user: %s", err)
		}
	}
	return func() {
		t.Helper()
		if err := user.Truncate(); err != nil {
			t.Fatalf("failed to truncate the user collection: %s", err)
		}
	}
}

使い方は簡単で setup 関数を呼び出すと teardown 関数が返ってくるのでそれを defer で呼び出すとよい。

teardown := setupUsers(t, usersTestData)
defer teardown()

しかし、この setup 関数をサブテストと一緒に並行実行すると意図したように動かない。どうやらサブテストを並行実行すると親テストが呼ばれた後に呼び出されるという仕組みになっていて、サブテストを実行する前に teardown が呼ばれてしまうので意図した制御にならない。How to handle parent test teardown with parallel subtests in golang の回答 によると、サブテストからさらにサブテストを実行するとよいとある。この場合、親テストとサブテストは同期的に実行され、サブテストの中でさらにサブテストを並行実行するという考え方で意図した振る舞いになる。並行実行するときは次のようなコードになる。

func TestMy(t *testing.T) {
    tests := []struct{
        // test cases
    }

	teardown := setupUsers(t, usersTestData)
	defer teardown()

	t.Run("wrap for setup process", func(t *testing.T) {
		for _, tt := range tests {
			tt := tt
			t.Run(tt.name, func(t *testing.T) {
				t.Parallel()
                // do test
            })
        }
    })
}

zeromq の多言語対応がすごい

1時に寝て7時に起きた。昨晩は食べ過ぎて気分が悪かった。

エレベーター点検の間違い

朝オフィスの入っているビルへ着くと、エレベーターに張り紙があって使えないことが書いてある。問題があれば、エレベーターの保守会社へ連絡してくださいとある。その張り紙をみて、エレベーターが故障したのかな?と勘違いした。その横でオフィスの利用者が10人ほど復旧を待っていた。仕方ないから一旦、家に戻って午前中は家からお仕事することにした。これはこれで docker で開発環境を作っていると、普段使っていないマシンでもすぐに開発環境を構築できることのメリットを実感する機会となった。11時頃に再訪したら普通にエレベーターが動いていて、あれ!?と思って、そのときに初めてビルの掲示板を見に行ったら、7:30 - 8:30 の時間帯でエレベーター点検だと書いてあった。私は8時前後に出社するのでこの時間帯は厳しい。エレベーターが動いていなかったらまず点検を疑うことにするのを学んだ。

zeromq の調査

昨日から zeromq の調査をしていた。ネットワークの通信におけるプラクティスとも言える、ØMQ - The Guide というごっついガイドもあって学びが多い。少し古いバージョンなら翻訳版も ØMQガイドブック(日本語版) にある。英語が苦手な方はまずこれを読んで概要を掴むのもよいかもしれない。ちなみにこの翻訳者の方といま一緒に働いていて設計のレビューをお願いして教えていただいている。感謝。

zeromq を使うときの注意点の1つとして、バックグラウンドで i/o スレッドが動いていて zmq_send() は実際に通信しているのではなく、バックグラウンドの i/o スレッドにメッセージを渡すだけになる。そのため、i/o スレッドが実際にノード間の通信を非同期で行う。これは接続先の相手がダウンしていても送信バッファにメッセージを溜めておいて再送してくれるので都合がよい。ちなみに送信バッファのサイズは zmq_setsockopt()ZMQ_SNDHWM を指定して調整できる。ソケットが常時接続されていれば、メッセージの順序は維持されるらしいが、ソケットを接続/切断するような使い方をすると zmq_send() が呼ばれたメッセージの順序は保証されない。一般の queue をイメージしてメッセージの順序が保証されることを前提に開発すると落とし穴があるので注意しておく必要がある。そういう so や issue も登録されているのを確認した。

近況報告の雑談

約1年ぶりにやすだ先生と大阪でオフライン飲み会をした。毎年2-3月頃に近況報告して経営のアドバイスなどをいただいたりしている。今回で3回目。今年は私がいま実家のいろいろとリファクタリングなどでいっぱいっぱいなのでとくに近況報告の資料を作る余裕がなくて、普通に飲み会しながらその場での近況報告となった。昨今の web 開発の当たり前として ci/cd や k8s のことを共有しながら、大学のシステムはどうこうみたいな話しもした。やすだ先生も副業が好調らしく、東京に出張する機会も多いとご活躍されているそうだ。

今回 クラフトビアハウスモルト 梅田店 というお店に初めて行った。私のような普段着の人間でも気軽に入ってよいようなお店であることもわかった。また接待で使おうと思う。食べものはちょっと上等なおつまみがある程度なのでビールを飲むのをメインとする相手がよいだろう。飲み放題コースにしたので、食べものの選択やビールの値段を気にせず注文できたのも接待としては考えることが減ってよかったと思う。阪急グランドビルの31Fという最上階にあって、あまり広いお店ではないが、気軽に夜景をみながらクラフトビールを飲める。早めに予約したおかげだと推測するが、カウンター席の一番端だったので座席もよかった。その横におそらく VIP ルームがあって、個室かどうかよりも店内が広くないので広いスペースを使う意図で VIP ルームもよさそうにみえた。追加料金なく借りれるのかな?2人で借りるのは難しいかもしれないが、4人ほどいれば借りてみたいと思う。

気付きスキルをあげるための指導とか

1時に寝て7時に起きた。すでに疲労困憊の様相。

仕様は誰が決めるのか

たまたま定例会議である仕様について話題になった。この作業はなぜ止まっているのだっけ?と確認したら、とくに理由なく、決めの問題を誰が決めるのかでお見合いしてしまっていたような状況であることがわかった。担当の開発者は新人さんなのでスキルや経験が未熟だったりするのはよいとして、仕様を決めていくときの作業の段取りをどうやって学んでもらえばよいかについて、私が考えるよいきっかけとなった。誤解のないように書いておくと、仕様確認できずに作業が止まっていたのはマネージャーである私の責任なので担当者に非はない。

開発の仕様を決めることは難しい。要件であればお客さんに確認しなければいけないこともあるし、背景を調査したり一定の技術知識がないと決められない仕様もある。誰もが最初は上司や先輩に仕様を教えてもらいながら開発経験を積み、自分で仕様を考えたりできるようになっていく。仕様を誰かから与えられるのを待っている ==> 自分が決められる仕様は自律的に決めて作業を先に進めていくの間にある、なにか気付きを与えないといけないと実感した。

この話題でこみやさんと話してみた。

「自分が決めていいこと」の中にはこのあたりが含まれていると思う。

  • ある程度正しい判断ができること
  • 判断に自信がない場合に相談ができること
  • 判断に自信を持てること (先に進める胆力があること)

自ら枷をはめる人は結構いるとは思っていて、明示的にやっていいことを伝えてチャレンジする雰囲気を作りたいのは同意です。ということで、判断できないというのは

  • 担当範囲かどうかわからない (自分で決めてよいかわからない)
  • 対応が適当であるかわからない (自信がない)

あたりに二分されるのでは、と集約されるのかも。

後者のレベルの人に対しては相談してくれ、ブロッカーを排除するのを手伝うから、とホウレンソウを覚えてもらう感じかなあ、というのが最初のコメント。仕様を決める能力がなくても、聞きに行く能力は持っていてほしい、という感じ。困ったら騒いでほしい、というのが僕が求める最初のステップですね。

スプリントを完了させるのがミッションなので、それができないとチーム全員不合格だよ。このまま待ってていいの? 仕様はどうやったら決まるの? って伝えそうだな、僕なら。

いくつかキーワードがあるように思える。

  • 自信
  • ホウレンソウ
  • 納期の認識

「とりあえずやってみて」とか「まずは自分で考えて」が、今の若者に響かない理由。 の記事によると、いまの若い人は答えを知った後に試行錯誤したり、その後の応用で差をつける文化があるといったことが書いてある。その賛否はともかく、他のマネジメントのイベントでもいまの若い人たちは非効率なことや無駄なことをやりたがらないという話しを聞いたことがある。

まず私が教えないといけないことは、開発や設計において答えなんてないという真理だと思う。確かに経験のある開発者が行う設計は答えのようにみえるかもしれないが、設計は要件の変化によって大きく影響を受ける。いわば時間制限付き論理最適解のようなものだ。またドメイン知識の有無によっても変わってくる。設計とは、そのときに1回判断したら終わりではなく、ずっと考え続ける行為である。試行錯誤することは無駄なことではなく、よい設計を行うための最短の方法であることを教えないといけない。

自信をつけてもらうにはどうすればいいだろうか?これは成功体験を積み重ねるしかないと思うが、成功体験がない初期はどうすればよいのだろうか?パッと思いつくのは心理的安全なチームを作って、ここで失敗しても自分の過失やストレスにならないとメンバーが感じられて挑戦する雰囲気を作ることに思える。このこともそれを体現するのはリーダーの役割なので私がうまくその雰囲気を作れていないと言えるだろう。

ホウレンソウは課題管理を推奨する私にとっては得意分野なのでここでは割愛する。今回の一件もホウレンソウができていないわけではない。課題管理システム上に仕様を決めなければいけないことをコメントに書かれていてそのことに私も気付いてはいた。作業が止まっていることに気付いていなかっただけ。

最後の納期についてはどうだろうか。いまのところ、意図的に私は納期についてほぼチームに言及していない。それはメンバーの1人は十分に理解して自律的に動いてくれているので言う必要がないのもある。新人さんは納期に間に合わせるよりも適切な仕事のやり方や考え方を学んでほしいと私は考えている。納期を意識して不十分な品質の成果を出すよりも時間がかかっても一定の品質の成果を出せるように指導していきたいという私の考えから言及していないので、これも私の非であることは疑いようがない。

1つずつみていくと課題があるのはマネージャーのマネジメントにみえる。なかなか難しい。過去にタイムラインでつぶやいたことを思い出した。

コンテキストによるキャンセル処理

1時に寝て7時に起きた。昨日がっつりコードを書いていたせいか、起きてから今日は休みたいと思いながらだらだらしてた。休めないのだけど。貧乏暇なし。

echo のリクエストコンテキスト

昨日の続きで mongodb のリファクタリングをしている。mongodb はほぼすべての処理で コンテキスト を受け取れるように設計されている。メンバーが go の context の扱いを理解していないのでコンテキストを渡すようなインターフェースになっていない。私もこれまでのコードレビューでキャンセル処理は些事なのでそれよりも機能開発を優先して後回しにしていた。それで、いま機能が一通り開発完了したのでインターフェースにコンテキストを受け取るようにリファクタリングした。デフォルトのコンテキストとして echo のリクエストコンテキストを渡す。Canceling request #1815 によると、echo のリクエストコンテキストは次の状況のときにキャンセルしてくれる。

  • クライアントのコネクションがクローズされたとき
  • http2 でリクエストがキャンセルされたとき
  • ServeHTTP() が返るとき
    • サーバーがシャットダウンするタイミング?

使い方はこんなイメージ。

ctx := c.Request().Context()
store := c.Get(myStore).(Store)
store.Get(ctx, request.From, request.To)

mongodb の view 調査

4時半に寝て11時に起きた。午後から go のコードをリファクタリングしてた。平日はメンバーの issue を監視して困ってたらコメントしたり、マージリクエストをレビューしたり、管理画面の振る舞いを検証したりと、コードを書いていても途中で作業がちょくちょく中断する。休日にコードを書くとその中断がない分、いつもよりかなり捗った。リファクタリングに思いの外、時間を取られている気がしたのはそのせいもあるか。

mongodb の view 作成

実はこれまで mongodb を扱ったことがなくて今回初めて触っている。とくに難しくもないのだけど、ドキュメントを探してやりたいことを調べたり、デバッグや開発のためのツールとしてどういうものがあるかといった知見がない。ないものは仕方ないので1からドキュメントを読みながら開発というか、リファクタリングをしている。mongodb そのものの知見はなくても、様々なデータベースを操作する開発をしてきたのでやりたいことに対して実装方法はいくつか検討がつくし、その実装を支援するための機能もあるはずだと予測がつくので探すのも早い。

ある collection から複数のデータ構造のレスポンスを返すような処理がある。こういったものは view を使うとうまく整理できると知っているので調べると mongodb view が提供されていることがわかる。3.4 から追加されたらしい。いまクエリの中で aggregation pipeline を書いている処理のいくつかは、あらかじめ view を定義してクエリすることでインフラ層を堅牢にした上で実装もシンプルにできる。さらに 4.2 から on-demand materialized view が追加されていて、標準の view と比較して aggregation pipeline の計算結果をディスクに保持するのでパフォーマンス上のメリットがある。元データの更新が頻繁でなければ on-demand を使った方がよいのだろうと推測する。

またこれまで mongodb の管理画面に mongo-express を使っている。view の振る舞いを確認しようとしたところ、どうも view には対応していないようにみえる。web ベースの管理画面を他にも探してみたが、どうも他に適当なものがない。mongodb が公式に compass というデスクトップアプリケーションの gui クライアントを提供している。macos なら brew からインストールできた。

> brew install mongodb-compass

このツールは collection も view も両方扱えるし、クエリやパイプラインも実行できて機能も充実している。web ベースじゃないとインフラとして共有はできないところだけが残念なところ。それでも開発する上ではとても強力なツールにみえる。適当にデータをインポートしたり、テストで aggregation pipeline を作成してみて、それをエクスポートして view を生成するときのスキーマ定義も作ることができた。ui も洗練していて、こんな優れたデスクトップアプリケーションは久しぶりにみたと思うぐらい感心した。

右すねの外側の筋に張りがある

23時に寝て7時に起きた。旅行のときにもっていく歯磨きセットを実家に忘れてきた。髭剃りが見当たらないと思っていたのは、その歯磨きセットに入れていたからのせいだと気付いた。髭剃りを買い直してもいいかもしれない。

ストレッチ

今日の開脚幅は開始前156cmで、ストレッチ後159cmだった。2-3日前から右の足首に違和感があって歩くときにかばってしまう。トレーナーさんに相談してみたところ、右足のすねの外側の筋に張りがあることがわかった。なぜそうなってしまったのか分からないけど、それがために立つときなどの、足首に力が入る瞬間に若干の痛みや違和感を感じるらしい。足首の違和感については、すねの外側の筋か、ふくらはぎのどちらかに起因するという。さすがプロという感じで、私が曖昧に、痛いわけではないけど足首に違和感を感じると言っただけで的確にその原因となっている筋を突き止めた。その延長で調子の悪い部位を丁寧にストレッチしてもらった。毎週ストレッチしているからこういった体調管理もできる。いまやストレッチが私の健康管理の中心になっている。

車の1ヶ月点検

ストレッチが終わってからお昼ご飯を食べてディーラーさんへ1ヶ月点検に行く。すでに契約は完了していて、実際に私も車に乗っているわけだけど、自動車重量税の請求額が間違っていましたということで9,600円を返金していただく。なぜか営業さんは返金したつもりになっていて、口座への振り込み確認はしましたか?と尋ねられて、数日前の時点では入金はなかったものの、今日チェックしているわけではないのでひとまず 「分からないです。」と回答しておいた。そしたら、そもそも返金先の口座を聞いていなかったので口座を教えてくださいとなって、そんな勘違いの失敗ある?って思って、ちょっと私の中の担当者さんの信頼を落とすやり取りとなった。

実は車の取引の請求書を作り直すのは今日で2回目になる。1回目はナンバーの登録手数料の金額が間違ってました。2回目は自動車重量税の金額が間違ってました。 それはなんらかの省庁の都合で急に金額が変更されるものだろうし、そういう間違いはあるだろうと受け入れていたんだけど、返金したつもりになっていて口座すら聞いてないというのは違うだろうと思えた。担当の営業さんはよい人なんだけど、なんか仕事の詰めの甘さみたいなのが垣間みえる雰囲気がする。補足として請求書に貼り付けしている200円の収入印紙はどうなるのだろう?と思って調べてみたら 印紙税過誤納[確認申請・充当請求]手続 という手続きがあって、誤って使ってしまった収入印紙ののお金は返金されるみたい。それがなかったら2回の請求書誤りで400円の損害になる。

余裕がなさ過ぎる

1時に寝て7時に起きた。タスクが溜まり過ぎてそろそろ辛くなってきているところ。この余裕の無さはよくないことなので、自分のダメさ加減というか、大いに反省しないといけない。

隔週の雑談

顧問のはらさんと隔週の打ち合わせ。いつもは打ち合わせの議題を2-3日前には共有するようにしている。だいたい水曜日前後に議題のリファレンスをはらさんに共有して金曜日の朝に話している。しかし、今週はリファクタリングに集中し過ぎていて前日の寝る前になって議題を共有していないことに気付いた。そして朝起きてから急ぎで議題を考えて共有していた。これはとてもよくない。準備ができていないので今日の議題は主に近況の話しをしていた。

ハドルの雑談

先日から 午前中はハドルに滞在 するようにしている。今週は木曜日にチーム外から勉強会についての相談が、今日はメンバーから気分転換に雑談にやってきてくれた。おそらく私がハドルにいなかったらゼロだったコミュニケーションの機会が、1週間に1-2回でもあることに私は嬉しく思ってしまう。フルリモートワークにおける、オフラインのような気軽な雑談の機会を提供する施策の1つとして意味なくハドルに入るのは悪くない気がしている。そのときにコミュニケーションを強制させるような押し付けが発生しないよう、運用ルールを徹底することが大事に思える。いまは相手がハドルに入ってくると 1on1 のような雰囲気になってしまうのでその次の挑戦としてはハドルに入っていても話さなくてよいといった運用ルールを設ければよいのではないかと思う。例えば、午前中はとりあえずハドルに入って気分が向いたときだけ話しかけるみたいな、ゆるいコミュニケーションの場になればいいなと思う。

ハドル雑談の運用ルールのアイディア

  • ハドルに入らなくても業務上の支障は一切おきない
  • ハドルにいる人には、用事があってもなくても、話しかけてよい
  • ハドルに入っていても話さず聞いているだけでもよい
  • 業務に集中していて忙しいときは話しかけられても後回しにしてもよい (ハドルから退出した方がわかりやすいかもしれない)

go の generics 勉強会

ちょうど先週からあちこち直したり、mongodb のクライアント周りをリファクタリングしたりしている。その過程で generics を使ってコードの共通化もしたりしている。私自身 generics で意図した通りにコンパイルできなくてはまってしまった事例もあるのでそういった失敗コードも共有した。go の generics はコードに対して静的な領域しか適用されず、コード中における動的な値の型は generics とは直行した概念だというところに初学者ははまるのではないかと思う。私がはまった。参加者におそらく1度はまるからはまったときに私が話していたことを思い出してとコードの解説をしていた。

余裕があったらスライドにまとめて後で資料として再利用できるようにしたかったものの、私の作業に余裕がなさ過ぎて次のリファレンスから引用しながら解説するといった勉強会になった。ただ私が読んでよいと思った他者のスライドやブログの記事のみを紹介している。それはそれで参考にはなるので勉強会の意図としては問題なかったんじゃないかとは思う。

mongodb を触ってみる

0時に寝て7時半に起きた。今日は1日中リファクタリングしてコードを書いていた。

リファクタリング

mongodb 周りのインフラ層のリファクタリングしている。過去に mongodb を触ったことがなかったので mongodb そのものの振る舞いや仕様なども理解しながらリファクタリングしている。その第一弾として差分が1500行以上のマージリクエストを作った。私の中ではまだ 1/3 ぐらいの進捗。動くレベルになったのでコードレビューを通じてメンバーと設計の考え方を共有していく。差分は多いけど、重要なところは一部だけ。やり過ぎだなと思えるのは、設計を見直すとテストコードを書き換える必要があって、その書き換えをやっていると時間が削られる。設計の部分だけ変更して、その後の作業をメンバーに引き継いでもらうといったやり方ならもっと早くできるかもしれないけど、テストコードを書き換える過程で私もユーザーの立場になって設計の良し悪しを検証するきっかけになるのでこの作業は自分でやることにも価値があると考えている。

設計がよくないところをどうやってメンバーに指導していくかはなかなか難しい。良し悪しは複数の設計を比較することで初めて気づくことも多い。私はその引き出しが多いので比較対象がたくさんあるだけでメンバーはその引き出しが少ないから悪い設計と認識できないでいる。その比較対象を私が提示してメンバーが考える機会にしてあげたい。理屈上はこれだけなんだけど、現実のコードと納期とのバランスを取るのが難しい。

いい加減マネージャーがリファクタリングに工数を使い過ぎだろうと私自身でも思うようになってきたので週末に残りのコードを書いて区切りのよいところでひと段落つけようと思う。