Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

恐怖1 既存クラスに…

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

クラス追加拒絶霊

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

流用霊

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

挫折霊

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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