制約理論 (TOC) で早いリリース・価値創生を目指す！レビュー短縮編

本記事は HRBrain Advent Calendar 2023 の記事です。

https://qiita.com/advent-calendar/2023/hrbrain


# はじめに
私の所属する開発チームでは、リリースが遅れがち、コードレビューが溜まりがち、という課題に対して、コードレビューをより早く消化できるよう、経験則で対策を実施してきました。
今回は、制約理論 (TOC) を用いて、その妥当性や、他に打ち手が無かったかを検討してみます。


# 制約理論 (TOC) とは
**制約理論 (Theory of Constraints)** とは、エリヤフ・ゴールドラット博士が体系化した、 **生産性向上のためのマネジメント理論** です。
※Qiitaのタグでは *Table of Contents (目次)* の記事が混ざってヒットしますのでご注意を

制約理論は、 **「The Goal (邦題: ザ・ゴール)」** という、工場の閉鎖危機に立ち向かうストーリー仕立ての書籍で公開されました。
基本的な考え方は、生産工程全体の中の制約 (ボトルネック) が、最終的な生産力を決定しているので、制約に集中して改善を行うことで、全体最適化することができる、というものです。

絵と図でわかりやすい **「ザ・ゴール コミック版」** もあります。
コミック版は電子書籍で無料お試し版も配信されているので、興味が湧いた方はぜひ。

https://promo.diamond.jp/books/the-goal/


# ソフトウェアエンジニアが目指すべき「目標 (ザ・ゴール)」とは
制約理論での改善に取り組む前に、書籍の冒頭でも述べられている、「目標 (ザ・ゴール)」について考えてみます。

企業にとっての目標とは **お金を稼ぐこと** である、と書籍では明言されています。
ソフトウェア開発エンジニアは、その目標に対する中間目標をどこに置くべきでしょうか？

その1つは **ソフトウェアのリリース** ではないでしょうか。

新規機能や機能改善をリリースすれば、既存顧客の契約継続・拡張、あるいは新規顧客獲得といった、お金を生み出すプロセスに貢献できます。
つまり、ソフトウェアのリリースを通して、顧客への訴求力を高め、売上を伸ばすことができます。

マクロに考えると、 **リリースしたソフトウェアの機能を使うことで、顧客の利益を向上できるようにすること** が最終目標、とも言えそうです。

ひとまず **リリースを早くすることで、より早くお金を生み出す** ことを **目標 (ザ・ゴール)** としてみます。

Slackのリリース関連のチャンネルも :moneybag: でまとめてみました。
![slack_section_release.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3500817/e55b57c0-b96c-ee3d-39d0-2c9e256e458e.png)


# 制約理論のステップ
制約理論における、改善のステップは以下です。

1. 制約を見つける
2. 制約をどう徹底活用するかを決める
3. 他のすべてをステップ2の決定に従わせる
4. 制約の能力を高める
5. ここまでのステップで制約が解消したらステップ1に戻る

**制約 (ボトルネック)** とは、処理能力が与えられた仕事と同等以下のリソースのことです。
まずは制約を探してゆきます。


# 開発工程の制約 (ボトルネック) を探す
制約はどうやって探せばよいでしょうか？

タスク管理ツールを使っているなら、あらゆる作業をタスク化しておけば、タスクの数や滞在時間で算出できそうです。
簡易に見つけるなら、「The Goal」の書籍の事例に倣い、仕掛り作業が溜まっているところを探す、という手もありそうです。
じっくり取り組むなら、バリューストリームマップ等を活用し、現状を図式化しつつ考える、というのも良さそうです。

2023年6月〜7月頃の開発チームでは、コードレビュー待ちのプルリクエストが大量にあり、他の工程と比べて明らかに不健全な状態に見えたので、いくつかの対策を実施しました。
これは、仕掛り作業の山から制約を見つける、というパターンに一致します。
改善すべき点の見つけ方として、間違ったものではなさそうです。

参考: とある朝の様子を `7/1以前にオープンされ、7/1より後にマージされたPR` で再現
![some_day_many_pr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3500817/bf0cf8e8-67c0-e3bf-b9c2-ab833a2f836e.png)


# なぜプルリクエストが滞まっているのか？
簡単に言えば、レビューが優先されない状態にあるからでした。
レビュワーにあたる人々は、実装タスクも割り振られており、そちらを優先しがちでした。

また、特にバックエンドはメインレビュワーが一人で、実装タスクと平行ではとても消化しきれない状態でした。
そのほか、1つあたりのプルリクエストが巨大で、短時間で消化しきれない問題もありました。


# 実装とレビュー、どっちが大切なの？
最終的な目標 (ザ・ゴール) をお金を設けることとするなら、より大きな価値を生み出せるものが優先、と言えそうです。
価値の大きさに差がないなら、より早く価値を生み出せる＝早くリリースできる方が優先、でしょうか。
つまり、緊急性の高いものを除き、 **実装よりレビューを優先すべき** ではないでしょうか？


# レビュー工程の改善策を洗い出す
理論立てて考えず、経験則と思いつきにより実施した対策は、以下でした。
- 毎日固定してレビューする時間を設ける
- 小さな変更ごとにプルリクエストを発行する
- レビューを極力優先する
- レビュワーを案件ごとに分担する
- バックエンドのメインレビュワーの差し込みタスクの負荷を減らす


改めて、制約理論に基づいて対策を検討してみます。
制約を見つけた後の改善ステップは以下なので、順に考えてみます。
2. 制約をどう徹底活用するかを決める
3. 他のすべてをステップ2の決定に従わせる
4. 制約の能力を高める


## レビュー工程を徹底活用する
「制約をどう徹底活用するかを決める」のステップです。
「徹底活用する」とは、基本的には **時間の無駄をあらゆる方法で無くす** ことです。
言い換えれば、 **リードタイム (LT) を短くする** ことと捉えて良さそうです。

「The Goal」で紹介されている事例を踏まえて深掘ってみます。


### 制約を休ませない
不要に休止や先延ばしがされず、無駄なく実行されている状態にすることです。

レビューを休み無くやれ、というのは非現実的ですし本末転倒ですが、 **レビューを他より優先して実施せよ** 、という解釈に落とし込むことはできそうです。


### すぐに必要なもの以外は作らない
すぐに必要なもの以外を、制約となっている工程に流すと、ゆとり (バッファー) がなくなったり、優先順位の変更で仕掛りが溜まったりします。
それを避けるため、必要な時に必要なものだけ工程に流しましょう、という考えです。

優先度の低い実装タスクのレビュー、というのがこれに当たるでしょうか。
例え実装タスクの手が空いていたとしても、 **制約であるレビュータスクを圧迫するようなことはしない** とも捉えられます。
手が空いている人は代わりに何をやるべきか？は要検討です。

なお、関連する概念として、「ドラム・バッファー・ロープ」というものがあります。
- ドラム
  - 制約のペースに合わせて、資材投入のタイミングを知らせる
- バッファー
  - 納期を時間で保護する
- ロープ
  - 早すぎる資材投入を防ぐ
  - 生産工程全体の在庫の量を、制約に合わせて決めてしまう


### 事前の検品を行う
制約となっている機械へ部品投入する前に、欠陥部品を取り除いておく手法が挙げられていました。

レビューでも、 **静的解析ツールやAIコードレビュー** 等を活用すれば、人のレビューが必須な箇所を事前に減らせそうです。

また、コードを実装する前の、 **設計段階でレビュー** をする、というのも、手戻りを防げそうです。


### バッチサイズを小さくする
バッチサイズ (処理の単位) を小さくする、という手法です。
長くなりがちなキュータイムやウェイトタイムを減らすことができ、リードタイムが圧縮され、生産のペースが早くなる、と書籍にはあります。
ただし、セットアップ (準備) の回数は増えるので、その点は要注意です。

少ない変更で **小さくプルリクエストを発行する** ことが、これに当たります。
多すぎて通知が来すぎとか、コンテキストスイッチが発生しすぎ、コンフリクトしすぎ、といった現象には注意でしょう。


## 他のすべての決定を「レビューのLTを短くすること」に従わせる
「他のすべてをステップ2 (制約をどう徹底活用するか) の決定に従わせる」ステップです。
制約となっている工程がスムーズに進むよう、他の工程のルールを変えていきます。

前述の「ドラム・バッファー・ロープ」の概念が関連してきます。
全体最適を考えれば、手が空く工程があったとしても問題ない、すべてが休み無く働いている状態は非効率である、といった趣旨のことも書籍では述べられています。

レビューLT改善に当てはめると、 **新規のプルリクエストが発行された際に通知する** 、 **レビュー可能になったら速やかにレビューする** 、等でしょうか。

仮に、レビューすべきものがないので、休ませないために開発し続けよ、という状態だと、制約はすでに開発フェーズに移行していそうです。


## レビュー工程の処理能力を上げる
「制約の能力を高める」ステップです。
対策としては最もシンプルですね。

レビューに対しては、以下のようなものが考えられます。
- レビュワーの分担・分散
- レビューすべき観点の認識を揃え、LTを短くする
- レビューできる人が少ないなら増やす


# 制約理論で洗い出した対策と取り組んできた対策との差分
同一ではないですが、重なる対策は実施できていました。

- レビュー工程を徹底活用する
  - 制約を休ませない
    - 毎日固定してレビューする時間を設ける
  - バッチサイズを小さくする
    - 小さな変更ごとにプルリクエストを発行する
  - 事前の検品を行う
    - CIによるlintの実行 ※新規に実施した対策ではない
- 他のすべての決定を「レビュー工程のLTを短くすること」に従わせる
  - レビューを極力優先する
- レビュー工程の処理能力を上げる
  - レビュワーを案件ごとに分担する
  - バックエンドのメインレビュワーの差し込みタスクの負荷を減らす

まだまだやれることは残っていますが、妥当な対策であれば一定の効果が出ていそうなので、分析してみます。


# 取り組んできた対策の結果を分析
本当は企画〜リリースしてお金になるまでの全体を分析したいところですが、仮でデータの取りやすい、「プルリクエストのマージ数・変更行数・リードタイム」から分析してみます。

![merge_count_and_lead_time.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3500817/e0a1d851-0c81-efb2-50e3-cd75772044be.png)

変更行数を大きく減少させずに、マージされるプルリクエスト数が増加しています。
また、リードタイムは6月時点と比べると、改善傾向にあります。
7月はリードタイムが短いですが、マージ数や変更行数が少ないので、特段良い状態では無かったものと思われます。

つまり、無事、一定の効果はあったようです！
経験則で実施した対策でしたが、制約理論に基づいて体系的に説明できれば、対策を進める上での障害があった時、ステークホルダーへの説得材料としても使えそうです。


# 終わりに
制約理論や書籍「The Goal」で挙げられている、生産性向上のための考え方の一部は、「リーン開発の本質」や「DevOps Research and Assessment」等とも共通しています。
どれを使うべきとは一概に言えませんが、制約理論という考えもあるよ！ということを知っていただけたなら幸いです。

なお、制約理論では、問題解決のための「思考プロセス」も体系化されています。
思考プロセスについては、「It's Not Luck (邦題: ザ・ゴール2)」という書籍で紹介されています。
コミック版は「ザ・ゴール2」は勿論、「Necessary But Not Sufficient」を元にした「ザ・ゴール3」もあります。
これらも面白いので、ぜひ手にとってみてください。

最後に、HRBrainでは、一緒に働く仲間をエンジニアに限らず広く募集しています。
こちらもぜひご検討ください！

https://www.hrbrain.co.jp/recruit