🌅

ゼロイチフェーズの戦士たちに伝えたいこと

に公開

サービスの初期開発、いわゆるゼロイチフェーズをやった人たちへの苦情集です。
自戒も含め、今後そういうフェーズに関わる方の参考になったらいいなと思います。

よく言う「コードは書く回数より読む回数のほうがずっと多い」というやつです。

状況

私が直近で担当したサービスは入社時点でリリースから5年目、そこから3年半ほど保守や機能追加を担当しました。

開発チーム的にはメンバーがすでに2回か3回完全に入れ替わっており、当時を知る人はだれもいないという状況でした。たぶん私は第4代開発リーダーです。
それぞれの事跡をまとめるとこんな感じです。(微妙に2代目と3代目の境目が自信ないですが)

主な仕事 残したもの
初代 M氏 ・アーキテクチャ選定
・サービス立ち上げ
・多数の作り込まれたバグ
・仕様の存在しない機能群
・まったく無名なFWで書かれた
 フロント側コード
卑劣様
2代目🪙
・アーキテクチャの見直し
・イマイチなフロント側の書き直し
 (React乗り換え)
・書きかけで断念した
 不使用Reactコード群
3代目🦀 ・サービス黒字化に向けた方向修正
 (キャッチーな機能を後付けすること)
・初期コードとの整合性が
 若干取れてない小機能たち
4代目🍔
(わたし)
🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪
🔪歴代の管理層が後回しにした🔪
🔪無数の基盤バージョンアップ🔪
🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪
(未来の人の審判に委ねます)

私の認識としては初代〜2代目の前半ぐらいが立上げ期かなーと。
本稿では厳密な意味のゼロイチというよりは「サービスが安定稼働するまで」ぐらいの範囲を想定します。

3代目はピボットというほどではないですが世情の変化を取り入れつつ売れそうな機能追加をビジネスオーナーから(人員は削減されつつ)求められて製品のスコープを徐々に変えていったという感じ。
私は3代目の下のメンバーとして入社し、その後3代目がVPoE的な立場に昇進したことで空席になった開発リーダーの座を押し付け合いの結果引き受けた次第です。

要するに言いたいこと

  • なるべく5年後とか10年後のことを考えてください
  • 意思決定の記録とか資料とか残してください
    • さもなくば10年とか勤め続けて生き字引をやってください
  • できれば常識的な実装をしてください

ちなみに基本的なお作法は押さえてってのは省略します。
グローバル変数使うなとか適切なクラス名つけろとかエラー握りつぶすなとか。

具体的な苦情

あまりに拡張性がないガチガチのドメイン設計はやめて

初期設計としてサービス提供範囲(≒ドメイン)を明確に定めることは正しいと思います。
ただ、その範囲外のことをやるのが困難な実装をされると後の人が苦しみます。

後から範囲外部分を独立したコンポーネントとして実装できるならいいですが、たいてい既存コードの抜け穴を探して無理やり増築する形にするしかなく、ヤクザなことをしていると分かりながらスパゲッティコードを編み込む羽目になります。

特殊な判断をしたときはその経緯を記録してほしい

なぜ今まで自社でAWS使ってたのにGCP(現Google Cloud)を選んだのかとか。

なぜ当時すでにReactとかがすでにそれなりに認知されていたのにmithril.jsという無名なフロントフレームワークを選んだのかとか。
(→察するに「ワンチャン覇権とるかもだから賭けよう」とか思った?)

この謎のGoogleアナリティクスタグのオーナーは誰なのかとか。
(今月ユニバーサルアナリティクスが完全終了したおかげで消せました)

めちゃくちゃにライブラリ入れないで

バージョンアップ担当した人がウルトラ苦しんでました。

正式版じゃないやつ入れないで

「とりあえず動くからこのライブラリ使おうぜ。バージョンは0.0.1らしいけど」

:yoshi:

→セキュリティ対応の必要が発生したとき
:doushite:

同じ用途の別ライブラリを雑に増やさないで

jQueryとBootstrapを両方入れたり、複数のアイコンライブラリを使ったり。

「後で使うかも」なコードを残さないで

どうせ使わないです。
というかGitって削除済みのコードも履歴管理されるんで安心して消してください。

あとデッドコードからしか呼び出されてないライブラリとかマジで邪魔すぎるので。
脆弱性診断の対象を洗い出している時に動いてないエンドポイントが発掘されたり、絶対にたどり着けない画面が発見されたりしたのは爆笑しました。

1つの画面に何でもかんでも詰めないで

色んな要件を同時に叶えようとすると陥ってしまいがちです[1]
複雑度が高すぎてメンテ困難になる+必要ない処理やデータ取得が勝手に走り性能が悪い。

eval系使うな

苦しんだのはRubyのsendメソッド。
こいつは文字列でメソッド名を指定して実行できます。書くときは楽かもしれないですが読む方は地獄です。

これ系は任意コード実行的な危険性の話は当然のこととして、関数の呼び出し元を特定するのが非常に面倒です。
デッドコードかどうかの判断や脆弱性のある処理がどこから呼び出されるかの調査など、保守性の面でも是非使わないでください。
(それか書いた人はすべてを記録するか20年ぐらい勤め続けてください)

無言でバックログチケット却下しないで

新規要望に似たものが過去のチケットに存在するけど、謎に無言却下されてることもありました。
せめて
「やったほうがいいとは思うが今期は工数がないので」とか
「別の要望と競合するので」とか
書いてください。

「長く放置しちゃったのでとりあえず閉じます」でも無言よりはマシです。

ちょっとでもいいから仕様を残して

頻繁に変わるコードのドキュメントをどうするかは非常に難しい問題です。
それはそれとして
「画面一覧がない」だとか
「メソッドコメントの引数内容が嘘」だとか
「複数の説明を突き合わせると矛盾する」
だとかは勘弁していただきたいです。

こういう状況で後続フェーズをやる人のきもち

以下のような言葉が飛び交いながら楽しく開発していました。
あまりお行儀はよくないですが、こうでもしないと正気を保てないのです。

ゼロトラスト

新入りなどに既存コードを説明する言葉です。

<例>
しんいり「追加機能は現行記載に合わせてこんな書き方でいいですか?」
われわれ「既存コードはゼロトラストの精神で、あなたが正しいと思う書き方でぶっ壊してください」
しんいり「」

殺意駆動

これはよそでも聞く言葉ですね。
殺意に任せて大々的なリファクタリングをぶちかますと不思議と徳を積んだ気持ちになれるのでおすすめです。

<特定のコミッターのID>です

歴代のエンジニアたちも全員がヤバいわけではなく、一部が正気じゃなかったり正気じゃない人をレビュアーが止められない状況だったりしたわけです。
で、Gitのコミット履歴にはコミット者のIDが残ります。これを仮にtanakataro9とすると、、

「あー、やばいですここtanakataro9なんで多分バグってます」
(不審挙動の調査で関連処理の作成者を確認したとき)

「こっちの処理ってtanakataro9?」
「そっちはtakuyakimuraです」
「ならそんなヤバいコードじゃないはずか・・・」
(障害の原因を追っているとき)

「tanakaぁぁぁああああ!!!」
(変更が思ったとおりに動かず散々関連処理をたどった結果)

といったことになります。

人年

これはチームで僕しか言わなかったですが、既存実装が複雑すぎる画面の改修工数を概算見積りしてくれとビジネスオーナーから依頼されたので
「3人年前後ですかね」
と返しました。

まあどうせ36人月も掛けてる間に別の問題が起こるので2-3倍は工数膨らむかもですが。

おわり

とりあえず思いつく限りを書いたのでこの辺にしておきます。
他にも7年前の
// TODO: そのうち直す
が残ってたり面白い話はあります。明日っていつの明日よ!

あとは思想問題的にはフロントとバックエンドのデータ構造が密結合になってたりDRYの意味を履き違えてるとしか思えない可読性最悪GODコントローラがあったりもしましたが、この辺はまだやむ無しの範囲かなと受け入れました。

ちなみに散々ボロクソ言いましたが初代開発リーダーのM氏とはかつて別の会社で私と一緒に働いていた仲で、僕が入社してからも会社の飲み会に来てもらったこともあります[2]
知ってる間柄なのである種の内輪ノリとしてディスっております。

そしてもちろん後を継いだ我々も次の世代からディスられる覚悟でした。
こうして恨みのバトンは受け継がれていく。。。
みなさんも後世に禍根を残さないよう愛される実装をぜひお願いします[3]

脚注
  1. 私も以前別の現場でやったことがあります。
    その現場は設計フェーズが終わる頃に派遣元と派遣先が揉めて実装には関われませんでした。悪いことをしたな。。 ↩︎

  2. その際にM氏からも「好きに言ってくれ」と快諾いただいています ↩︎

  3. スケジュールとか人員の都合とかで無理なもんは無理なんですけど ↩︎

Discussion