一人情シス時代に学んだ「敗北条件から考えるシステム開発」

＼スニダンを開発しているSODA inc.の [Advent Calendar](https://qiita.com/advent-calendar/2023/soda-inc) 3日目の記事です!!!／

### 私はたくさん敗北してきた
　みなさんこんにちは。ひかるです。
　突然ですが、開発していると思い通りにならないことばかりですよね。タスクが思っていたより大変だったり、予定通りいかなかったり、障害や不具合を発生させてヒヤヒヤしたり……。でも、このこの程度であれば、正直敗北とは言えないですよね。なんだかんだ最後にうまくいくのであれば、それを勝利と呼んでも良さそうです。
　この記事では、敗北という言葉を**致命的、あるいは広範囲に及ぶような、ネガティブな影響を意図せず生み出してしまうこと**と定義します。システム開発の文脈で言うと、例えば障害を発生させてしまって、サービス全体に影響を与えてしまうようなことが該当するかと思います。
　当然ですが、こんな敗北は経験したくないですよね。ですが昔の私は、ぺーぺーだったこともあり、意図せずこういった失敗を繰り返してきました。そのたびに肝を冷やして、落ち込んだわけですが、それを経たおかげで学んだこともあります。今回はその学びをみなさんに共有したいと思います。

？？？「所詮……先の時代の敗北者じゃけェ…!!!」

### 一人情シス時代のこと
　時はさかのぼり、私が新卒でとある会社に入ったときのことです。私は地方の工場の情報システム部に配属されました。そこでは工場で利用されている工程管理システムの開発を行っていました。タイトル詐欺で恐縮ですが、正確には一人情シスではなく、部署には他にも開発者がいたのですが、人数が少ないこともあり、以下の開発体制が常態化していました。

* チーム開発という概念はなく、設計からテストまで一人でやり切る
* レビュワーがいないためレビューは自分でやる
* テストコードはなく、テストは自分の手作業で行う

　上記の開発体制のため、新人にとっては結構辛く、当然セルフレビューやセルフテストは穴だらけなので、いざリリースしても不具合があったり、リリースに失敗してシステム全体に影響を及ぼしたりと、大変な目に遭ってきました。あのときはみなさんご迷惑をおかけしましたm(_ _)m

　こんなことばかりだとメンタルが保ちませんので、自分なりに対策を考えてみました。

### どうしたか
　私はとりあえず、開発に取り組む初期段階で**敗北条件を定義する**ことにしました。
　どういうことかと言いますと、正直小さなバグがいくつかあるくらいでしたら問題ないのですが、前述の通り、クリティカルなバグがあると大ダメージですので、まずはそういった致命的なミスを避ける必要がありました。致命的なミスとはつまり、下記のようなものです。

 - 不具合のせいでシステム全体がストップする
 - データの不整合が発生し、機能の動作に悪影響を及ぼす
 - ユーザーがまったく求めていないような機能を作ってしまう
 などなど。

　私はひとまず、開発の初期段階で、上記のように**敗北条件**を明確にしてみました。これによって以下のメリットを得ることができました。
 
#### 重点的にテストすべき箇所を知ることができる
　テストはすべて手作業ですので、リリース前には一通り自分でテストを行うのですが、当然時間的な制約があります。その中で、上記のように敗北条件を整理しておけば、開発中やリリース直前に、適切なテストを必要な分だけ行うことができます。また、こういったテスト項目を初期段階から作っておくことで、開発中も適宜テストを行うことができます。開発の終盤にテストをやって、思わぬ大きなバグが見つかってしまうととても切ないのですが、途中からチェックポイントを設けるようにテストを行うことで、回り道をせずに済むようになります（ちょっとアジャイルっぽいですね）。
 
#### 敗北しないような設計や実装を心がけることができる
　重点的にテストすることも大切なのですが、そもそもミスりやすい設計や実装にしないことが、根本的でありながら最大の近道でもあると思います。当時の私は新人で、キレイなコードや美しい設計といったものがなんなのかさっぱりわかりませんでしたが、自分でいくつも敗北していると、どんな設計・コードがマズイかがなんとなくわかるようになってきていました。あらかじめ敗北条件を整理しておくと、それを避けるような設計や実装を想定することができます。
　また、当時の私はやりませんでしたが、先人たちの知恵を借りるというのも有効だと思います。彼らもおそらく私と同じように数多の失敗を繰り返し、そのたびに反省してきたはずなので、おそらく私が少し考えるよりもずっと良い解決方法を知っているはずです。下記のような書籍を読んだり、あるいは有名な技術記事を読んで学ぶのもいいでしょう。
 - 『[リーダブルコード](https://amzn.asia/d/a7omhiI)』
 - 『[良いコード/悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方](https://amzn.asia/d/gaiIstU)』
 - 『[Good Code, Bad Code ～持続可能な開発のためのソフトウェアエンジニア的思考](https://amzn.asia/d/7E9ooJ1)』

#### あらかじめ十分に対策をしているので、リリース前後であっても精神的に安定する
　当時の私にとってこれが最もありがたい恩恵でした。リリース前はいつもソワソワして落ち着かなかったのですが、前述のようにテストや設計段階で敗北を潰しているので、次第に私は落ち着いてリリースに臨むことができるようになりました。イチかバチかのリリースがなくなることで、他のタスクに集中できるようにもなりました。


### どうなったか

　この「敗北条件の整理」によって、私のリリースは非常に安定するようになりました。事前に特定箇所を重点的にテストしているので不具合の数も大幅に減少しました。以前のように関係者に謝ったり、リリースに失敗して肝を冷やしたりすることもなくなりました。小さな不具合があっても、ユーザーからすれば些末なものですので、機能を利用する分には問題ありませんでした。

　つまり私は敗北しなくなったのです！！

 **？？？「敗北を知りたい…」**

### この考えを現在でも利用してみる

　当然ですが、この「敗北条件からシステム開発を考える」というのはいつでも有効な考えだと思います。
　通常、新たなプロジェクトを進めるときは、どうしても甘美な勝利を想像してしまいがちです。素晴らしい機能が予定通りリリースされて、不具合もなく、ユーザーからのウケも良い……

　しかし、中には「一発KO」となるような敗北条件もあるはずです。それがどんなに素晴らしい機能やサービスであっても、例えば下記のような状態になってはまずいわけです。

* セキュリティ上の脆弱性がある
* 予定したスケジュールから大幅に遅れてしまい、ビジネス上のチャンスを逃す
* ターゲットとしているユーザーが、機能やサービスに対してまったく満足しない。むしろさらに不満を抱く

　「こんなの当たり前だよ！」と思われるかもしれませんが、開発を進めていくと、目の前の課題を解決することに意識が囚われてしまい、こういった「一発KO」系の落とし穴を忘れてしまいがちです。なので、この「敗北条件」に関してはプロジェクト開始直後にチーム内で整理し、認識を揃えておくと良いでしょう。
 　例えば、リリースの予定時期を計画するとき、まずは理想のスケジュールを立てると思うのですが、実際には色々うまくいかないことがあるので、そのスケジュールが後ろ倒しになりがちです。再現なく後ろ倒しにすることはできないはずなので、どこかで「デッドライン」を決める必要があります。つまり**これ以上スケジュールを後ろ倒しにしたらビジネス上のメリットを十分に享受できない**ポイントがあるはずなので、それをあらかじめチーム内で合意を取っておく必要があるでしょう。言い換えると、「このデッドラインにリリースが間に合わない」ことが敗北条件になるわけです。
　次にこの敗北条件を深堀りしていきます。「理想のリリース時期とデッドラインに、どれくらいの時間的な差があるのか」を考えてみます。この差が小さければ小さいほど、今回のプロジェクトはリスキーになるわけです。また、開発の終盤で「やっぱりリリースがデッドラインを超えそうです😢」と判明しても困るので、チームが普段からデッドラインを意識し、都度計画を練り直す必要があります。
　こんな感じで、敗北条件を明確にし、それを深堀りすることで、潜在的なリスクを洗い出したり、具体的な対策を立てることができるわけです。

#### 個人のタスク管理レベルでも応用できるよ！
　この考えは何もプロジェクト単位でしか利用できないというわけではありません。一人の開発者として持っているタスクを計画・管理する上でも役に立ちます。例えば下記のように、毎日自分のTODOリストを作る際、そこに敗北条件を加えてみます。

- TODO: 昼過ぎにPRを出し、夕方ころにマージする
  - 敗北条件） 明日以降にPRを出す(後続のタスクが詰まって予定が大幅に遅れるため）
- TODO: ユーザー情報を取得するAPIを実装する
  - 敗北条件） 本人以外のユーザー情報がAPIから取得できてしまう（脆弱性を生んでしまうため）

　こんな感じで、負けパターンを整理してみると、それを避けるように予定を組み直したり、設計段階で考慮し直したりするきっかけになります。「どうやるか」を考えることも重要ですが、「どうすれば敗北を回避できるか」を想定することも、堅実なシステム開発をする上で重要な考え方だと思います。

### まとめ
　敗北条件から考える、という一件ネガティブな思考方法ですが、意外と役に立ちそうではないでしょうか？ 汎用的ですし、特にデメリットもないかと思いますので、ぜひみなさんも普段の開発に取り入れていただきたいなと思います！
　以上となります！　ありがとうございました！
 
　明日はokauchiwaniさんの「QAエンジニアから「きっかけ」を作ろう」です！　お楽しみに！