$30 off During Our Annual Pro Sale. View Details »

技術的負債の怨霊と除霊方法 / ghosts-of-technical-debt

技術的負債の怨霊と除霊方法 / ghosts-of-technical-debt

このイベントの登壇資料です
『ミノ駆動さんと語るエンジニア怪談〜技術的負債の呪いにどう立ち向かうのかLT〜』
https://forkwell.connpass.com/event/291332/

MinoDriven

August 24, 2023
Tweet

More Decks by MinoDriven

Other Decks in Programming

Transcript

  1. 技術的負債の怨霊と
    除霊方法
    2023年8月24日
    株式会社スタメン
    ミノ駆動

    View Slide

  2. こんばんは
    霊能力者ミノ駆動です

    View Slide

  3. ミノ駆動
    エンゲージメント向上サービスを手掛ける
    株式会社スタメンで働いています
    アプリケーションアーキテクトとして
    以下設計全般に取り組んでおります
    ● 技術的負債の解消
    ● アーキテクチャの再設計
    ● 拡張性向上設計
    ● エンジニアへの設計サポート(助言、提案など)
    @MinoDriven

    View Slide

  4. 著作紹介
    『良いコード/悪いコードで学ぶ設計入門』
    技術的負債を作り込まない
    変更容易性の高い設計を学ぶ
    初級〜中級向け入門書
    新卒エンジニアに最適です
    輪読会も多数開催されております
    発売14ヶ月で10刷重版
    発行部数 3万部 超え
    3万部記念で
    帯が付きました

    View Slide

  5. ITエンジニア本大賞2023 大賞受賞

    View Slide

  6. 登壇及び受賞多数
    ● Developers Summit 2021 Summer ベストスピーカー賞3位
    ● Developers Summit 2023 話題賞1位
    ● Developers Summit 2023 ベストスピーカー賞3位
    ● Developers Summit 2023 ベストスピーカー賞5位
    ● 昨年だけでも16回以上の講演依頼
    ● 今年は毎月講演やインタビュー etc...

    View Slide

  7. おしながき
    - 恐怖1 既存クラスに…
    - 恐怖2 使えそうなロジックに…
    - 恐怖3 リファクタリングに挑むものの…
    - 技術的負債の本質的な問題とは何か

    View Slide

  8. 【注意】
    技術的負債は霊のシワザであって
    人は悪くありません
    貶める意図はないのであしからず

    View Slide

  9. 恐怖1
    既存クラスに…

    View Slide

  10. Aさん:既存の◯◯Managerクラスに新機能のロジック書いておきました。
    ぼく:ち、ちょっと。新機能なのにクラス追加しないんですか!?
    Bさん:え…クラス追加ですか? クラスって追加していいもんなんですか?
    Cさん:新しくクラスって要る? 動くもの書けてるんだからそれでいいじゃ
    ん。
    Dさん:クラス分けると一気に読み流せなくなるから俺はやらない(ドヤ顔

    View Slide

  11. おわかりいただけただろうか

    View Slide

  12. クラス追加拒絶霊

    View Slide

  13. クラス追加拒絶霊
    - クラス追加を拒んだり、恐れたりする霊。
    - 霊の性格はさまざま。以下は各性格。
    - 既存クラスへのロジック追加を何とも思わない。
    - クラスを追加することに、何かよく分からない不安感や罪悪感を覚える。
    - 追加すること自体が悪だと考えているケースもある。
    - あまりにも先鋭化するとメソッド追加や変数追加すら拒むケースもある。

    View Slide

  14. カプセル化 とは
    - データとそのデータに強く関与するロジックをひとまとめにして秘匿し、外
    部には正しい操作手段(メソッド)のみを公開すること。
    - なぜひとまとめにするのか:低凝集に陥り関連ロジックの追跡が困難にな
    る、つまり影響範囲の調査工数が増大する。
    - なぜ秘匿し正しい操作手段のみ公開するのか:秘匿せず露出したままだと、
    不正な変更や意図しない変更を加えられ、バグになる可能性がある。
    - カプセル化の発想なき実装は、こうした弊害を作り込んでいることと同じ。
    - クラスはカプセル化の手段のひとつ。

    View Slide

  15. クラス追加拒絶霊は神クラスを生み出す
    - 神クラスの正体はカプセル化が崩壊した世界。
    - クラスは、自身のメンバ(インスタンス変数、メソッド)を知っているし触
    れる。
    - 神クラスは自身のスコープが巨大すぎるために、自身のメンバがグローバル
    な性質を帯びる、つまりグローバル変数、グローバルメソッドめいてくる。
    - 秘匿されておらずありとあらゆる要素にアクセス可能な構造。カプセル化し
    ない場合の弊害がさまざまな箇所で発生しやすい構造。

    View Slide

  16. - カプセル化の意義も含め、メンバーの設計スキル向上が肝要。
    - 設計スキル向上には実際に手を動かして訓練する必要がある(本の読み合わ
    せだけでは困難)。
    - プロダクションコードを用い、例えば★ミノ駆動本★記載の手法でコードを
    整理してみる、といった勉強会がオススメ。
    - 基本的にカプセル化を軸に除霊を試みる。
    クラス追加拒絶霊を除霊するには

    View Slide

  17. 「カプセル化」で通じなければ「セキュア設計」
    - カプセル化せずフルアクセス、フルコントロール可能な構造はWebサービス
    で全くセキュリティ対策せず、重要情報を誰でも触れて変更できるのと同じ
    こと。
    - 自社のプロダクションコードをGitHubのパブリックリポジトリに置いておき
    ますか?
    - 家の玄関や窓を全開にして外出できますか?
    - カプセル化で秘匿し正しい操作手段(メソッド)のみ公開するのは、玄関を
    施錠し、ドアホンで来客者を確認することと同じ。招かれざる客(不正操
    作)を排除する。
    - クラス=家に例えても良い。クラス作成はセキュアな家をひとつひとつ建築し
    ていくことに似ている。

    View Slide

  18. - t_wadaさん「品質とトレードオフになっているのは学習コストなのではない
    か」
    - 厄介なのは成長する気のない人。まことに残念ながら一定数存在する。この
    場合せっかく学習コストをかけても徒労に終わる。除霊不能だが、封じるこ
    とはできる(後述)。
    それでも除霊できない場合もある

    View Slide

  19. 恐怖2
    使えそうなロジックに…

    View Slide

  20. Aさん:この追加仕様、どうやって実装する?
    Bさん:どれどれ。あー、それは(既存の)この◯◯メソッド内でフラグ生やし
    て分岐で切り替えるだけでいけるっしょ。
    Cさん:あと、流用できそうなメソッド見つけたよ。仕様通りに動くように呼び
    出してパパっと実装終わらせようぜ。

    View Slide

  21. おわかりいただけただろうか

    View Slide

  22. 流用霊

    View Slide

  23. 流用霊
    - ありあわせのロジックの流用や改造で動くものを作る霊。
    - 既存ロジックにフラグと条件分岐を埋め込むことを非常に好む。
    - 「流用する」「応用する」「再利用する」という言葉を好んで話す。
    - 使えそうなロジックをgrepする能力に異常に長けている。
    - grep能力がさらに先鋭化すると、ネット上で使えそうなサンプルコードを見
    つけ、サンプルのコピペと継ぎ接ぎで動くものを作ってしまう「コピペ霊」
    に変化するケースも。

    View Slide

  24. 通常割引価格
    割引率5% 夏季割引価格
    わたくしと同じ5%割引ですわ〜
    おDRY原則に基づいて
    再利用しますわ〜

    View Slide

  25. 通常割引価格
    割引率3% 夏季割引価格
    3%割引に
    仕様変更しますわ〜
    きゃあああああ!!!!!
    5%割引の仕様を満たせなく
    なりましたわよ!?!??
    - 割引率が多目的に使われてしまっており
    一方の仕様変更が別目的の仕様に影響を及ぼしてしまう
    - DRY原則とはコードの重複を許さないのではなく
    意図や目的の重複を許さない原則
    - 典型的な単一責任原則違反

    View Slide

  26. 通常割引価格
    割引率5%
    夏季割引価格
    割引率5%
    - 同じように見えるロジックでも
    目的の異なるものを共通化してはならない
    - こうすることで
    目的の異なるもの同士の仕様変更が影響しなくなる
    - 各クラスは多目的にならないよう
    単一の目的を達成する手段として設計する
    - 単一責任原則とは単一目的原則

    View Slide

  27. 再利用性は基本的に共通基盤開発のみ
    共通基盤
    (フレームワーク)
    固有
    アプリA
    固有
    アプリB
    固有
    アプリC
    再利用性を追いかけて
    いいのは共通基盤のみ
    ● DRY原則に則ると固有アプリのロジックは
    基本的に目的特化型
    ● 再利用可能なものはほぼ皆無
    ● 共通化可能なのは目的が同じロジックのみ

    View Slide

  28. 流用霊を除霊するには
    - 「流用しよう」「応用させてみよう」「再利用しよう」「共通化しよう」こ
    の手の声が聞こえたら要注意。流用霊の声である可能性が高い。
    - DRY原則の意義である「意図や目的の重複を許さない」に照らし合わせ、対
    象ロジックの意図や目的を確認すること。
    - 既存ロジックを意図や目的の違うものに流用、応用しないこと。
    - 意図や目的の違うロジック同士を共通化しないこと。
    - 開発対象がアプリケーションならば、基本的に再利用性を追いかけてはなら
    ない。
    - 開発対象がフレームワークならば、再利用性を追いかけて良い。

    View Slide

  29. 恐怖3
    リファクタリングに挑むものの…

    View Slide

  30. Aさん:デザインパターンとか、書籍『リファクタリング』に書いてある方法で
    リファクタしてみたんだけど……
    Bさん:どうした?
    Aさん:なんか逆に余計に複雑になっちゃった感じでさ。やった意味があったの
    か疑問で。
    Bさん:偉い人が書いた本かもしれないけど、実務に使えないことはよくあるか
    らね。うちらの開発には合わないんだよ。
    Aさん:そっか、そうだよね。やめた方がいいかも。

    View Slide

  31. おわかりいただけただろうか

    View Slide

  32. 挫折霊

    View Slide

  33. 挫折霊
    - 設計やリファクタリングに興味を持ち始め、取り組んではみたものの、上手
    くいかず挫折してしまう霊。
    - または「どうせ上手くいかない」「うちらには合わない」と囁き、挫折させ
    てしまう霊。

    View Slide

  34. - 設計やリファクタリングのゴールを設定できていないことが原因。
    - 技術的負債は変更容易性と深い関係がある。
    - 変更容易性とはソフトウェア品質特性のひとつで、バグを埋め込まず、どれ
    だけ素早く正確に変更できるかを示す度合い。
    - 技術的負債とは変更容易性が低い状態を指す。
    - つまり、変更容易性が高い構造がリファクタリングのゴール。

    View Slide

  35. 変更容易性
    このギャップが
    技術的負債
    変更容易性の高い構造を知らないと
    負債もゴールも認知不能
    これが挫折霊の正体

    View Slide

  36. 挫折霊を除霊するには
    - 変更容易性の高い構造を設計できるスキルが必要。
    - この設計スキルが手薄なまま書籍『リファクタリング』に記載のテクニック
    を表面的に真似てもあまり上手くいかない。
    - 凝集度、結合度、複雑度の他、SOLID原則やドメイン駆動設計など、さまざ
    まな設計知見を深めることでリファクタリングの精度が向上していく。
    - 特に、次に紹介する方法の除霊効果が高くオススメ。

    View Slide

  37. 手段に対応する目的が
    たったひとつになるよう設計する

    View Slide

  38. 【目的】
    髪を
    乾かしたい
    【目的】
    目的地に
    早く移動したい
    【手段】
    【手段】
    手段たるシステムは目的のためにあり、作り出される
    目的はひとつだけ

    View Slide

  39. 【目的】
    食べ物を
    温めたい
    【手段】
    【目的】
    濡れた猫を
    乾かしたい
    食べ物を温める目的で作らたものであって
    猫を乾かすために作られたものではない

    View Slide

  40. しかしソフトウェアの世界では
    こうしたカオスを容易に作り出せてしまう

    View Slide

  41. 【目的】
    商品を売買したい

    View Slide

  42. 【大目的】
    商品を売買したい
    【中目的】
    商品審査
    したい
    【中目的】
    在庫管理
    したい
    【中目的】
    注文
    したい
    【中目的】
    配送
    したい
    大目的は中目的から構成される

    View Slide

  43. 在庫管理 配送
    注文
    商品審査
    ECサイト
    商品モデル
    多目的に対応するよう作れられた商品モデルは巨大
    化複雑化し品質上様々な弊害をもたらす

    View Slide

  44. 商品
    原材料
    構成部品
    匂い

    審査品目
    品目分類
    審査所見
    審査結果
    サイズ
    重量
    抽出
    在庫品
    発注金額
    在庫量
    安全在庫量
    配送品
    サイズ
    重量
    注文品
    取扱開始日
    売値
    在庫量
    取扱開始日
    売値
    在庫量
    抽出
    抽出
    品目分類
    審査所見
    審査結果
    抽出
    発注金額
    在庫量
    安全在庫量
    原価
    予約開始日
    製造メーカー
    賞味期限
    目的ごとにそれぞれ必要な解決要素を抽出

    View Slide

  45. 在庫管理 配送
    注文
    商品審査
    ECサイト
    審査品目
    品目分類
    審査所見
    審査結果
    在庫品
    発注金額
    在庫量
    安全在庫量
    注文品
    取扱開始日
    売値
    在庫量
    配送品
    サイズ
    重量
    各目的に1:1で対応する特化モデルになる

    View Slide

  46. 【目的】
    商品審査したい
    【手段】
    商品モデル
    【目的】
    在庫管理したい
    【目的】
    注文したい
    【目的】
    配送したい

    View Slide

  47. 【目的】
    商品審査したい
    【目的】
    在庫管理したい
    【目的】
    注文したい
    【目的】
    配送したい
    【手段】
    審査品目
    【手段】
    在庫品
    【手段】
    注文品
    【手段】
    配送品
    手段に対応する目的はそれぞれたったひとつ
    リファクタリングもこの考えをベースにゴール設定する

    View Slide

  48. 技術的負債の怨霊
    つまり本質的な問題とは何か

    View Slide

  49. 怨霊の正体は学習コスト
    - 負債が積み上がることがマズいのではなく、解消されない、解消する環境を
    作り出せないことが問題。
    - t_wada御大が仰るように、設計に関する学習コストが原因の根本にあると考
    える。
    - ゆえに、負債解消には学習コストを軸に開発戦略を組み立てる必要がある。
    - コアドメインなど、クリティカルな品質が求められる箇所には、単純な話、
    設計の学習コストが低い人、つまり積極的に設計を学ぶ人をアサインする。
    - 学習コストが高い人、つまり消極的な人は、クリティカルな品質が求められ
    るスコープとは別の箇所にアサインする。また、多少品質の悪いコードが書
    かれても重要スコープに影響が生じないよう、アーキテクチャレベルで分離
    設計することも有効な手段。

    View Slide

  50. ご清聴ありがとうございました

    View Slide