Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
技術的負債の怨霊と除霊方法 / ghosts-of-technical-debt
Search
MinoDriven
August 24, 2023
Programming
11
4.2k
技術的負債の怨霊と除霊方法 / ghosts-of-technical-debt
このイベントの登壇資料です
『ミノ駆動さんと語るエンジニア怪談〜技術的負債の呪いにどう立ち向かうのかLT〜』
https://forkwell.connpass.com/event/291332/
MinoDriven
August 24, 2023
Tweet
Share
More Decks by MinoDriven
See All by MinoDriven
破壊せよ!データ破壊駆動で考えるドメインモデリング / data-destroy-driven
minodriven
18
4.4k
アーキテクチャレベルで考える開発生産性 / architecture-and-productivity
minodriven
22
11k
見えないものに着目すると上手くいく、モデリングの勘所 / invisible-driven-design
minodriven
22
6.6k
クソコード動画『カプセル化 Mk-II』 で考える 上手くカプセル化できない理由 / encapsulation2
minodriven
21
16k
分岐を低減するinterface設計と発想の転換 / interface_design_idea.pdf
minodriven
17
6.6k
目的と抽象化の関係性から分かる、システムの設計精度を高める考え方 / purpose abstraction design
minodriven
22
8.8k
『良いコード/悪いコードで学ぶ設計入門』を一歩深める読み方 / deepen good code bad code
minodriven
18
6.9k
風刺動画「一枚岩モデル」で考える、DDDの境界付けられたコンテキスト / huge model vs bc
minodriven
19
39k
不幸を再生産しないための設計に対する向き合い方
minodriven
10
9.3k
Other Decks in Programming
See All in Programming
聞き手から登壇者へ: RubyKaigi2024 LTでの初挑戦が 教えてくれた、可能性の星
mikik0
1
130
Outline View in SwiftUI
1024jp
1
330
NSOutlineView何もわからん:( 前編 / I Don't Understand About NSOutlineView :( Pt. 1
usagimaru
0
330
Enabling DevOps and Team Topologies Through Architecture: Architecting for Fast Flow
cer
PRO
0
330
2024/11/8 関西Kaggler会 2024 #3 / Kaggle Kernel で Gemma 2 × vLLM を動かす。
kohecchi
5
920
as(型アサーション)を書く前にできること
marokanatani
10
2.6k
Generative AI Use Cases JP (略称:GenU)奮闘記
hideg
1
290
Flutterを言い訳にしない!アプリの使い心地改善テクニック5選🔥
kno3a87
1
170
C++でシェーダを書く
fadis
6
4.1k
見せてあげますよ、「本物のLaravel批判」ってやつを。
77web
7
7.7k
광고 소재 심사 과정에 AI를 도입하여 광고 서비스 생산성 향상시키기
kakao
PRO
0
170
Tauriでネイティブアプリを作りたい
tsucchinoko
0
370
Featured
See All Featured
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
131
33k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
665
120k
[RailsConf 2023] Rails as a piece of cake
palkan
52
4.9k
A Tale of Four Properties
chriscoyier
156
23k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
506
140k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.2k
How GitHub (no longer) Works
holman
310
140k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
44
2.2k
Building an army of robots
kneath
302
43k
Producing Creativity
orderedlist
PRO
341
39k
Transcript
技術的負債の怨霊と 除霊方法 2023年8月24日 株式会社スタメン ミノ駆動
こんばんは 霊能力者ミノ駆動です
ミノ駆動 エンゲージメント向上サービスを手掛ける 株式会社スタメンで働いています アプリケーションアーキテクトとして 以下設計全般に取り組んでおります • 技術的負債の解消 • アーキテクチャの再設計 •
拡張性向上設計 • エンジニアへの設計サポート(助言、提案など) @MinoDriven
著作紹介 『良いコード/悪いコードで学ぶ設計入門』 技術的負債を作り込まない 変更容易性の高い設計を学ぶ 初級〜中級向け入門書 新卒エンジニアに最適です 輪読会も多数開催されております 発売14ヶ月で10刷重版 発行部数 3万部
超え 3万部記念で 帯が付きました
ITエンジニア本大賞2023 大賞受賞
登壇及び受賞多数 • Developers Summit 2021 Summer ベストスピーカー賞3位 • Developers Summit
2023 話題賞1位 • Developers Summit 2023 ベストスピーカー賞3位 • Developers Summit 2023 ベストスピーカー賞5位 • 昨年だけでも16回以上の講演依頼 • 今年は毎月講演やインタビュー etc...
おしながき - 恐怖1 既存クラスに… - 恐怖2 使えそうなロジックに… - 恐怖3 リファクタリングに挑むものの… - 技術的負債の本質的な問題とは何か
【注意】 技術的負債は霊のシワザであって 人は悪くありません 貶める意図はないのであしからず
恐怖1 既存クラスに…
Aさん:既存の◯◯Managerクラスに新機能のロジック書いておきました。 ぼく:ち、ちょっと。新機能なのにクラス追加しないんですか!? Bさん:え…クラス追加ですか? クラスって追加していいもんなんですか? Cさん:新しくクラスって要る? 動くもの書けてるんだからそれでいいじゃ ん。 Dさん:クラス分けると一気に読み流せなくなるから俺はやらない(ドヤ顔
おわかりいただけただろうか
クラス追加拒絶霊
クラス追加拒絶霊 - クラス追加を拒んだり、恐れたりする霊。 - 霊の性格はさまざま。以下は各性格。 - 既存クラスへのロジック追加を何とも思わない。 - クラスを追加することに、何かよく分からない不安感や罪悪感を覚える。 -
追加すること自体が悪だと考えているケースもある。 - あまりにも先鋭化するとメソッド追加や変数追加すら拒むケースもある。
カプセル化 とは - データとそのデータに強く関与するロジックをひとまとめにして秘匿し、外 部には正しい操作手段(メソッド)のみを公開すること。 - なぜひとまとめにするのか:低凝集に陥り関連ロジックの追跡が困難にな る、つまり影響範囲の調査工数が増大する。 - なぜ秘匿し正しい操作手段のみ公開するのか:秘匿せず露出したままだと、 不正な変更や意図しない変更を加えられ、バグになる可能性がある。
- カプセル化の発想なき実装は、こうした弊害を作り込んでいることと同じ。 - クラスはカプセル化の手段のひとつ。
クラス追加拒絶霊は神クラスを生み出す - 神クラスの正体はカプセル化が崩壊した世界。 - クラスは、自身のメンバ(インスタンス変数、メソッド)を知っているし触 れる。 - 神クラスは自身のスコープが巨大すぎるために、自身のメンバがグローバル な性質を帯びる、つまりグローバル変数、グローバルメソッドめいてくる。 -
秘匿されておらずありとあらゆる要素にアクセス可能な構造。カプセル化し ない場合の弊害がさまざまな箇所で発生しやすい構造。
- カプセル化の意義も含め、メンバーの設計スキル向上が肝要。 - 設計スキル向上には実際に手を動かして訓練する必要がある(本の読み合わ せだけでは困難)。 - プロダクションコードを用い、例えば★ミノ駆動本★記載の手法でコードを 整理してみる、といった勉強会がオススメ。 - 基本的にカプセル化を軸に除霊を試みる。
クラス追加拒絶霊を除霊するには
「カプセル化」で通じなければ「セキュア設計」 - カプセル化せずフルアクセス、フルコントロール可能な構造はWebサービス で全くセキュリティ対策せず、重要情報を誰でも触れて変更できるのと同じ こと。 - 自社のプロダクションコードをGitHubのパブリックリポジトリに置いておき ますか? - 家の玄関や窓を全開にして外出できますか?
- カプセル化で秘匿し正しい操作手段(メソッド)のみ公開するのは、玄関を 施錠し、ドアホンで来客者を確認することと同じ。招かれざる客(不正操 作)を排除する。 - クラス=家に例えても良い。クラス作成はセキュアな家をひとつひとつ建築し ていくことに似ている。
- t_wadaさん「品質とトレードオフになっているのは学習コストなのではない か」 - 厄介なのは成長する気のない人。まことに残念ながら一定数存在する。この 場合せっかく学習コストをかけても徒労に終わる。除霊不能だが、封じるこ とはできる(後述)。 それでも除霊できない場合もある
恐怖2 使えそうなロジックに…
Aさん:この追加仕様、どうやって実装する? Bさん:どれどれ。あー、それは(既存の)この◯◯メソッド内でフラグ生やし て分岐で切り替えるだけでいけるっしょ。 Cさん:あと、流用できそうなメソッド見つけたよ。仕様通りに動くように呼び 出してパパっと実装終わらせようぜ。
おわかりいただけただろうか
流用霊
流用霊 - ありあわせのロジックの流用や改造で動くものを作る霊。 - 既存ロジックにフラグと条件分岐を埋め込むことを非常に好む。 - 「流用する」「応用する」「再利用する」という言葉を好んで話す。 - 使えそうなロジックをgrepする能力に異常に長けている。 -
grep能力がさらに先鋭化すると、ネット上で使えそうなサンプルコードを見 つけ、サンプルのコピペと継ぎ接ぎで動くものを作ってしまう「コピペ霊」 に変化するケースも。
通常割引価格 割引率5% 夏季割引価格 わたくしと同じ5%割引ですわ〜 おDRY原則に基づいて 再利用しますわ〜
通常割引価格 割引率3% 夏季割引価格 3%割引に 仕様変更しますわ〜 きゃあああああ!!!!! 5%割引の仕様を満たせなく なりましたわよ!?!?? - 割引率が多目的に使われてしまっており
一方の仕様変更が別目的の仕様に影響を及ぼしてしまう - DRY原則とはコードの重複を許さないのではなく 意図や目的の重複を許さない原則 - 典型的な単一責任原則違反
通常割引価格 割引率5% 夏季割引価格 割引率5% - 同じように見えるロジックでも 目的の異なるものを共通化してはならない - こうすることで 目的の異なるもの同士の仕様変更が影響しなくなる
- 各クラスは多目的にならないよう 単一の目的を達成する手段として設計する - 単一責任原則とは単一目的原則
再利用性は基本的に共通基盤開発のみ 共通基盤 (フレームワーク) 固有 アプリA 固有 アプリB 固有 アプリC 再利用性を追いかけて
いいのは共通基盤のみ • DRY原則に則ると固有アプリのロジックは 基本的に目的特化型 • 再利用可能なものはほぼ皆無 • 共通化可能なのは目的が同じロジックのみ
流用霊を除霊するには - 「流用しよう」「応用させてみよう」「再利用しよう」「共通化しよう」こ の手の声が聞こえたら要注意。流用霊の声である可能性が高い。 - DRY原則の意義である「意図や目的の重複を許さない」に照らし合わせ、対 象ロジックの意図や目的を確認すること。 - 既存ロジックを意図や目的の違うものに流用、応用しないこと。 -
意図や目的の違うロジック同士を共通化しないこと。 - 開発対象がアプリケーションならば、基本的に再利用性を追いかけてはなら ない。 - 開発対象がフレームワークならば、再利用性を追いかけて良い。
恐怖3 リファクタリングに挑むものの…
Aさん:デザインパターンとか、書籍『リファクタリング』に書いてある方法で リファクタしてみたんだけど…… Bさん:どうした? Aさん:なんか逆に余計に複雑になっちゃった感じでさ。やった意味があったの か疑問で。 Bさん:偉い人が書いた本かもしれないけど、実務に使えないことはよくあるか らね。うちらの開発には合わないんだよ。 Aさん:そっか、そうだよね。やめた方がいいかも。
おわかりいただけただろうか
挫折霊
挫折霊 - 設計やリファクタリングに興味を持ち始め、取り組んではみたものの、上手 くいかず挫折してしまう霊。 - または「どうせ上手くいかない」「うちらには合わない」と囁き、挫折させ てしまう霊。
- 設計やリファクタリングのゴールを設定できていないことが原因。 - 技術的負債は変更容易性と深い関係がある。 - 変更容易性とはソフトウェア品質特性のひとつで、バグを埋め込まず、どれ だけ素早く正確に変更できるかを示す度合い。 - 技術的負債とは変更容易性が低い状態を指す。 -
つまり、変更容易性が高い構造がリファクタリングのゴール。
変更容易性 このギャップが 技術的負債 変更容易性の高い構造を知らないと 負債もゴールも認知不能 これが挫折霊の正体
挫折霊を除霊するには - 変更容易性の高い構造を設計できるスキルが必要。 - この設計スキルが手薄なまま書籍『リファクタリング』に記載のテクニック を表面的に真似てもあまり上手くいかない。 - 凝集度、結合度、複雑度の他、SOLID原則やドメイン駆動設計など、さまざ まな設計知見を深めることでリファクタリングの精度が向上していく。 -
特に、次に紹介する方法の除霊効果が高くオススメ。
手段に対応する目的が たったひとつになるよう設計する
【目的】 髪を 乾かしたい 【目的】 目的地に 早く移動したい 【手段】 【手段】 手段たるシステムは目的のためにあり、作り出される 目的はひとつだけ
【目的】 食べ物を 温めたい 【手段】 【目的】 濡れた猫を 乾かしたい 食べ物を温める目的で作らたものであって 猫を乾かすために作られたものではない
しかしソフトウェアの世界では こうしたカオスを容易に作り出せてしまう
【目的】 商品を売買したい
【大目的】 商品を売買したい 【中目的】 商品審査 したい 【中目的】 在庫管理 したい 【中目的】 注文
したい 【中目的】 配送 したい 大目的は中目的から構成される
在庫管理 配送 注文 商品審査 ECサイト 商品モデル 多目的に対応するよう作れられた商品モデルは巨大 化複雑化し品質上様々な弊害をもたらす
商品 原材料 構成部品 匂い 味 審査品目 品目分類 審査所見 審査結果 サイズ
重量 抽出 在庫品 発注金額 在庫量 安全在庫量 配送品 サイズ 重量 注文品 取扱開始日 売値 在庫量 取扱開始日 売値 在庫量 抽出 抽出 品目分類 審査所見 審査結果 抽出 発注金額 在庫量 安全在庫量 原価 予約開始日 製造メーカー 賞味期限 目的ごとにそれぞれ必要な解決要素を抽出
在庫管理 配送 注文 商品審査 ECサイト 審査品目 品目分類 審査所見 審査結果 在庫品
発注金額 在庫量 安全在庫量 注文品 取扱開始日 売値 在庫量 配送品 サイズ 重量 各目的に1:1で対応する特化モデルになる
【目的】 商品審査したい 【手段】 商品モデル 【目的】 在庫管理したい 【目的】 注文したい 【目的】 配送したい
【目的】 商品審査したい 【目的】 在庫管理したい 【目的】 注文したい 【目的】 配送したい 【手段】 審査品目
【手段】 在庫品 【手段】 注文品 【手段】 配送品 手段に対応する目的はそれぞれたったひとつ リファクタリングもこの考えをベースにゴール設定する
技術的負債の怨霊 つまり本質的な問題とは何か
怨霊の正体は学習コスト - 負債が積み上がることがマズいのではなく、解消されない、解消する環境を 作り出せないことが問題。 - t_wada御大が仰るように、設計に関する学習コストが原因の根本にあると考 える。 - ゆえに、負債解消には学習コストを軸に開発戦略を組み立てる必要がある。 -
コアドメインなど、クリティカルな品質が求められる箇所には、単純な話、 設計の学習コストが低い人、つまり積極的に設計を学ぶ人をアサインする。 - 学習コストが高い人、つまり消極的な人は、クリティカルな品質が求められ るスコープとは別の箇所にアサインする。また、多少品質の悪いコードが書 かれても重要スコープに影響が生じないよう、アーキテクチャレベルで分離 設計することも有効な手段。
ご清聴ありがとうございました