技術的負債の返済を経営陣に伝えるキーワードは「技術的設備の更新」

Higtyのシステムの作り方

外部コンサルでとある会社を支援中のHigty。社長からの相談です。

社長は営業出身で気合と根性で売上を伸ばしてきたたたき上げの社長です。


社長からの相談

社長「うちの社内のエンジニアが技術的負債が~とか言ってるのがよくわからん。そんなものをやる暇があったら新機能を作ってほしいんだが」

Higty「そうなんですね」

社長「新機能を作らないでその負債っていうやつを整理したほうが開発の生産性が上がると言っているんだが本当か?」

Higty「社長は今回、まじでエンジニアの言ってることを本気で理解しようとしてますか?」

社長「もちろん。エンジニアが言ってることは全く理解不能だが、分からないなりに理解しないとまずいなと」

Higty「わかりました。じゃあ開発の生産性についてまず理解しましょう」

社長「俺は頭悪いから簡単に頼むよ!」


プログラムとは?

Higty「まずはプログラムで何ができると思いますか?」

社長「よーわからん」

Higty「一言で言うと『PCを操作できる』ということです」

社長「わからんんぞ(笑)」

Higty「たとえば」

社長「ふむ」

Higty「社長のPCのハードディスクの容量が残り少ないとします」

社長「うむ。今まさに家のPCがそういう状況だ」

Higty「プログラムを書くとサイズが大きくて最終アクセス時刻が古いファイルをリストアップできます」

社長「それは便利だな」

Higty「そのために英語でプログラムを書きます。こんな感じです。」


Program.cs

using System;
using System.IO;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        // 引数でフォルダを指定。なければカレントディレクトリを使う
        string targetDir = args.Length > 0 ? args[0] : Directory.GetCurrentDirectory();

        Console.WriteLine($"探索対象フォルダ: {targetDir}");

        try
        {
            // 全ファイルを再帰的に取得
            var files = Directory.EnumerateFiles(targetDir, "*", SearchOption.AllDirectories)
                                 .Select(f =>
                                 {
                                     FileInfo fi = new FileInfo(f);
                                     return new
                                     {
                                         Path = fi.FullName,
                                         Size = fi.Length,
                                         LastAccess = fi.LastAccessTime
                                     };
                                 });

            if (!files.Any())
            {
                Console.WriteLine("ファイルが見つかりませんでした。");
                return;
            }

            // アクセス時刻が古い順、サイズが大きい順でソート
            var candidate = files.OrderBy(f => f.LastAccess)
                                 .ThenByDescending(f => f.Size)
                                 .First();

            Console.WriteLine("不要そうなファイル候補:");
            Console.WriteLine($"パス: {candidate.Path}");
            Console.WriteLine($"サイズ: {candidate.Size} バイト");
            Console.WriteLine($"最終アクセス: {candidate.LastAccess}");
        }
        catch (Exception ex)
        {
            Console.WriteLine("エラー: " + ex.Message);
        }
    }
}

社長「何書いてるかわからんがとにかくプログラムを書くとPCを操作できるんだな!」

Higty「そうです」


ライブラリとは?

Higty「これを自分で書くのは大変だと思いませんか?」

社長「まあ無理だな」

Higty「これをもっと簡単にする方法があります」

社長「ほう」

Higty「メソッドを作ったりライブラリにしたりするとめちゃくちゃ簡単になります。私がこういうのを作ると」

static void ShowUnnecessaryFile(string targetDir)
{
    try
    {
        // 全ファイルを再帰的に取得
        var files = Directory.EnumerateFiles(targetDir, "*", SearchOption.AllDirectories)
                                .Select(f =>
                                {
                                    FileInfo fi = new FileInfo(f);
                                    return new
                                    {
                                        Path = fi.FullName,
                                        Size = fi.Length,
                                        LastAccess = fi.LastAccessTime
                                    };
                                });

        if (!files.Any())
        {
            Console.WriteLine("ファイルが見つかりませんでした。");
            return;
        }

        // アクセス時刻が古い順、サイズが大きい順でソート
        var candidate = files.OrderBy(f => f.LastAccess)
                                .ThenByDescending(f => f.Size)
                                .First();

        Console.WriteLine("不要そうなファイル候補:");
        Console.WriteLine($"パス: {candidate.Path}");
        Console.WriteLine($"サイズ: {candidate.Size} バイト");
        Console.WriteLine($"最終アクセス: {candidate.LastAccess}");
    }
    catch (Exception ex)
    {
        Console.WriteLine("エラー: " + ex.Message);
    }
}

Higty「社長は以下の文字を書けばよくなります」

var targetDir = args.Length > 0 ? args[0] : Directory.GetCurrentDirectory();
ShowUnnecessaryFile(targetDir);

社長「ほう。これなら書けそうだ!」

Higty「こういう感じで難しい処理を簡単に利用できるようになってるものをライブラリといいます」

社長「なるほど。うちのエンジニアもこういうのを使ってるのか?」

Higty「はい、ほとんどのエンジニアはMicrosoftやGoogleやオープンソースの誰かが作ったライブラリを組み合わせてシステムを作ってます」

社長「そうなのか。詳しいことはわからんが、2行書けばやりたいことができるというのは大幅な生産性UPだな」

Higty「そのとおりです」


ライブラリは家電や装備やツールみたいなもの

社長「なんとなくわかったがもうちょっとわかりやすい例えはないのか?」

Higty「社長は何か趣味はありますか?」

社長「登山やキャンプはするな」

Higty「なるほど。キャンプで火おこしをするときにOD缶バーナーを使う場合と原始的な摩擦熱での火おこしを思い浮かべてください」

社長「ふむ」

Higty「自分でゼロからプログラムを書くのが原始的な火おこしです」

https://mujinto.jp/survival-fire/

社長「なるほど」

Higty「ライターや缶バーナーを使うのがライブラリを使用する方法です。使うと生産性が大幅UPです」

社長「そういえばエンジニアがフレームワークという言葉も使ってたがあれも同じ意味なのか?」



フレームワークはライブラリの集まり

Higty「フレームワークはもうちょっと広い意味合いです」

社長「広いとは?」

Higty「1泊で登山をするときには以下のようなアイテムがいりますよね?」

・テント

・シュラフ

・ヘッドランプ

・水筒

・バーナー

・バックパック


Higty「これらの1つ1つのアイテムがライブラリです」

社長「それはわかるけどうちのシステムだとどういうことになるのか?」

Higty「自社ECサイトであれば以下のようなサービスのライブラリを使ってると思います」

・Stripe(課金サービス)

・SendGrid(メール送信)

・CloudFlare(ファイルの管理)

・OpenAI(AI処理)


社長「確かにECサイトで課金処理やメール送信処理はやってるな。そこでこういうのが使われてるということか」

Higty「はい。ライブラリが使われてるということになりますね」

社長「これらを自分で作ることもできるという理解であってるのか?」

Higty「そうですね。作ることはできます。ただ自分で作るととても時間がかかりますしバグも多くなります」

社長「そうなのか?なぜ?」

Higty「有名なライブラリは数万人がエンジニアが使用してます。さらにライブラリを使用しているサービスのユーザーは数百万人いたりするのでありがちなバグは既に修正され、あまりバグはありません」

社長「なるほど」

Higty「登山行くときに木を擦って火おこしはしないですし、トレッキングポールを木から削り出して作ることはしないのと同じです」

社長「で、フレームワークとは?」

Higty「フレームワークは特定の目的に合うようなライブラリを集めたものをそう呼ぶことが多いです」

社長「例えば?」

Higty「WEBフレームワークとかだとWEB開発に必要なライブアリを集めたものになります」

社長「よくわからん」

Higty「登山フレームワークは登山のためのアイテムのセットというイメージです」

社長「なるほど」

Higty「以下のアイテムのセットを登山フレームワークいう感じです」

・テント

・シュラフ

・ヘッドランプ

・水筒

・バーナー

・バックパック


社長「WEBフレームワークだと?」

Higty「WEBだとだいたい以下のような処理が必要になります」

・ルーティング(URLをページと紐づける)

・リクエストとレスポンス

・テンプレート(画面のヘッダーやフッターの共通部分をまとめる)

・SSE(ChatGPTみたいなテキストがぬるぬる出てくる処理)


Higty「こういうWEBで使われるライブラリがまとまってるのをフレームワークという感じです」

社長「うーむ、なんとなくイメージはわかったぞ。とにかくライブラリやフレームワークを使うと生産性がUPするんだな」


技術的設備の更新で生産性がUPする

社長「で、技術的負債の返済って何なんだ?どう生産性のUPに寄与するのかが経営する立場としては知りたい」

Higty「これはもっと適切な言葉があって技術的設備の更新といった方が正しいです」

社長「ほう」

Higty「10年前の登山アイテムと今を比べてみてください」

社長「今年最新のゴアテックスのレインウェア買ったけどあれは凄いな。雪山でも寒くないし大雨でも水が全く入ってこないしその上蒸れない。信じられないよ」

Higty「他の登山ギアも10年も経つと進化するじゃないですか」

社長「それはそう。どんどん良くなるね」

Higty「ライブラリもどんどん進化するんですよ」

社長「ふむ」

Higty「新しいライブラリの生産性は以前のライブラリよりも良くなっています」

社長「登山アイテムと同じということか」

Higty「今まで10行書いてたのが1行で済むようになったりします」

社長「それは良いな」

Higty「今使ってるライブラリを定期的に更新しないと生産性が上がらないんです」

社長「なるほど」

Higty「5年前は最新の便利なライブラリだったのが陳腐化するんです」

社長「ふむ」

Higty「あとは全く新しいラ機能を提供するイブラリが登場することもあります。AIのライブラリがそうですね」

社長「そういった意味ではあの扇風機が服についてるのも似たようなものか」

Higty「そうですね」

社長「登山以外の例えは?」

Higty「ちょっと違う視点で飲食店だと」

Higty「古いかまどで料理を作っている厨房と、最新のオーブンレンジで料理を作っているお店」

Higty「1個1個食器を手洗いしてるお店と、最新鋭の食器洗浄機を導入しているお店」

Higty「紙でお客様からの注文を伝票で書いて口頭で厨房に伝えるお店」

Higty「多くのお客様に質の高い料理を速く届けるには、こういった設備の更新が必須です」

社長「古いライブラリだと生産性が伸びないと」

Higty「飲食店を経営していてオーブンレンジを入れたいとか食器の洗浄が間にあってないから食器洗浄機を買いたいとかは理解できるじゃないですか」

社長「それはそうだな」

Higty「技術的負債を解消したいというのは技術的設備の更新したいということです。そうすることでより簡単に機能を追加できるようになり、1人月で作成可能な画面数が増え、生産性がUPするということです」

社長「ふむふむ」

Higty「登山だと最新のアイテムの活用でバックパックのウエイトが軽くなって歩くペースがUPし、最新のレインウェアやアイテムで安全性も向上しますよね」

社長「そうだな」

Higty「工場の設備投資も似た感じですね。最新の機械をいれると労災のリスクが減り生産量もUPします」

社長「それはわかりやすいな」

Higty「技術的負債の解消も似た感じです。ライブラリや自社のプログラム部分を更新することで生産性がUPします」

社長「それならやったほうが良さそうだな!」


CTOや技術顧問

社長「こういう説明がうちのエンジニアにはできないんだが」

Higty「エンジニアはすし職人みたいなもので専門職以外への説明は苦手です」

社長「できないものなのか?」

Higty「技術への深い理解があって、ビジネスサイドの人、例えば営業や管理職や役員社長に適切な解像度で説明できる人は稀です」

社長「なるほど」

Higty「ですからいいCTOや技術顧問というのはなかなか見つからないです。見つけたらしっかりつなぎとめておかないともったいないです」

社長「そういうものなのだな」

Higty「いいCTO候補はあっという間にどこかから声がかかるので見つけたらしっかり捕まえておかないと後悔しますよ」

社長「わかった」

Higty「経営陣への説明以外にも適切な設備の選択やエンジニアチームの管理などいろんなことをやってくれますから」

社長「今までCTOの仕事の解像度が低かったけどだいぶ上がった気がする。ありがとう!」