Upgrade to Pro — share decks privately, control downloads, hide ads and more …

C#コードの結合を可視化する Roslyn解析による設計改善と リファクタリング判断

Avatar for dora56 dora56
September 19, 2026

C#コードの結合を可視化する Roslyn解析による設計改善と リファクタリング判断

結合は単に減らせば良いのではなく、強さ・距離・変動性のバランスが重要です。
本セッションではRustのcargo-couplingから着想を得たdotnet-couplingを題材に、namespaceやproject境界、interfaceやなどC#のプロジェクト構造をどのように数値化し、設計改善の判断材料にするかを具体例をお話しします。
https://github.com/dora56/dotnet-coupling

Avatar for dora56

dora56

September 19, 2026

More Decks by dora56

Other Decks in Technology

Transcript

  1. TOOL dotnet-coupling C#の結合を、根拠までたどれる形で可視化するCLI SCAN PRIORITIZE 強度・距離・変動性 RoslynとGit履歴から依存を観測 issue / hotspots

    リファクタリング候補を絞り込む INVESTIGATE SHARE & GATE impact / trace 変更の波及と呼び出し元をたどる JSON・SARIF・AI・CI レビューと品質ゲートへ接続する SOURCE / DOCS github.com/dora56/ dotnet-coupling dotnet tool install --global dotnet-coupling 06
  2. COUPLING BALANCE 強度と距離の4つの組み合わせ 強度 \ 距離 近い 遠い 低い 局所的複雑性

    疎結合 高い 高凝集 大域的複雑性 近くに置くなら強い関係 遠くに置くなら弱い関係 弱い関係を近くに集めると、局所的複雑性が増える 出典:Vlad Khononov『ソフトウェア設計の結合バランス』p.181 表10.3をもとに作成 08
  3. COUPLING BALANCE 距離が変える2つのコスト ↑ コスト CHANGE COST 変更のコスト 遠くなるほど変更の調整コスト は増える。

    近いほどビルド・テスト・デプ ロイを共有する。 DISTANCE 組織、所有者、実行時の依存も距 離に影響する。 ライフサイクル結合 距離 → 文脈 メンバー プロジェク ト パッケージ 名前空間 /ライブラ リ サービス システム 出典:Vlad Khononov『ソフトウェア設計の結合バランス』p.152 図8.4をもとに作図 10
  4. COUPLING BALANCE 変動性はGit履歴から近似する LOW MEDIUM 0–2回 3–10回 HIGH 11回以上 OBSERVATION

    変更回数は、変更理由や 将来の変化そのものではな い 既定の観測期間:6か月 11
  5. COUPLING BALANCE 書籍の均衡度とツールのscore 01 02 03 書籍 強度と距離の差を、 低い変動性が補う ツール

    構文から得た 段階値を独自式で計算 同じ言葉を使っても、 数値モデルは別 12
  6. ROSLYN ANALYSIS 内部結合のBalance Score STRENGTH DISTANCE VOLATILITY Contract 0.25 Model

    0.50 Functional 0.75 Intrusive 1.00 Same namespace 0.25 Different namespace 0.50 Project 0.75 External 1.00 Low 0.00 Medium 0.50 High 1.00 alignment × volatilityImpact → Balance Score(0.00〜1.00) 13
  7. ROSLYN ANALYSIS Balance Scoreの読み方 BALANCED NEEDS REFACTORING Contract 0.25 ×

    Different project 0.75 Low volatility 0.00 Functional 0.75 × Different project 0.75 × High volatility 1.00 alignment = 1 - |0.25 - (1 - 0.75)| = 1.00 volatilityImpact = 1 - (0.00 × 0.25) = 1.00 score = 1.00 × 1.00 = 1.00 alignment = 1 - |0.75 - (1 - 0.75)| = 0.50 volatilityImpact = 1 - (1.00 × 0.75) = 0.25 score = 0.50 × 0.25 = 0.125 → 0.13 Score 1.00 Score 0.13 強い依存は近くに、遠い依存は契約越しに Scoreは結合単位の参考値。Gradeはissue densityで別に判定する 14
  8. ROSLYN ANALYSIS Roslyn解析の流れ 01 02 03 04 COLLECT RESOLVE ENRICH

    REPORT 構文木から 型と利用箇所 → 参照先と 依存を分類 → Git履歴と ドメイン設定 → score・issue・ ソース位置 観測 → 解釈 → 判断材料 13
  9. ROSLYN ANALYSIS semantic mode:workspaceからsymbolへ 01 02 03 04 05 INPUT

    REGISTER LOAD RESOLVE OBSERVE .csproj .sln / .slnx → MSBuild Locator → MSBuild Workspace → Project / Document SemanticModel → symbol identity 依存として記録 GetSymbolInfo / GetTypeInfo / GetOperation 15
  10. ROSLYN ANALYSIS semantic mode:増える観測と残る境界 RESOLVED CONSERVATIVE BOUNDARY IDENTITY alias /

    global using / partial / generic CALLS extension・連鎖・条件付き呼び出し field / property / inferred local source typeが不明な dynamic parameter BOUNDARIES project / assembly / NuGet package workspaceを 読み込めない環境 INDIRECT typeof / nameof / Activator / service locator 具体型を追えるdynamic 具体型を示さない Type変数 依存を捏造しない preview / opt-in dotnet-coupling --mode semantic ./MyApp.sln 16
  11. ROSLYN ANALYSIS レポートを根拠まで読む Grade C Avg Score 0.75 DETECTED INTERPRET

    別namespaceの具象型を 直接生成している Gradeと平均scoreは 別の計算 分類:GlobalComplexity issue種別とソース位置へ戻る 内部結合 1本 Medium 1件 数値だけで結論を出さず、検出根拠を読む 18
  12. DESIGN DECISION ドメインコンテキストによる補正 OBSERVED CONTEXT CALIBRATE Git履歴 observedChurn 変更回数の事実 subdomain

    expectedVolatility technicalRole effective coupling score・severity・Grade へ反映 → → 実際に見つけた依存グラフは保持し、解釈だけを補正する 19
  13. DESIGN DECISION ドメインコンテキストによる補正(tomlによる設定) [[domain.subdomains]] name = "CoreRules" category = "core"

    paths = ["src/DotnetCoupling.Core/Domain/**"] expected_volatility = "high" [[domain.subdomains]] name = "CoreContracts" category = "supporting" paths = ["src/DotnetCoupling.Core/Contracts/**"] expected_volatility = "medium"
  14. OSS EVALUATION OSS例:CommandLine Parserを読む 対象:commandlineparser / commandline Phase 3 OSS

    syntax / semantic compare SYNTAX SEMANTIC PREVIEW Grade C 502 internal couplings High 1 / Medium 30 Grade C 2,005 internal couplings High 1 / Medium 30 診断 6件 観測する結合は増えたが、Gradeとissue件数は変わらなかった 20
  15. OSS EVALUATION OSS例:レポートから分かること 観測範囲 結果の安定性 環境の診断 semanticはsymbol解決で 結合候補を増やす Gradeとissue件数は このOSS例では不変

    対象の.NET Framework 開発パック不足を6件報告 モードを比較するときは、結合数の増加とworkspace診断を一緒に読む 21
  16. CLOSING リファクタリングの方向性を検証する 1 絞る 2 依存の候補と ソース位置 → 確かめる 共有知識と

    変更理由 3 → 比べる テストと 同条件の再解析 数値は結論ではなく、レビューを始める場所 28
  17. BACKUP 補足:書籍の式とツールの式 書籍:B = max(|S - D|, 10 - V)

    + 1 ツール:alignment = 1 - |s - (1 - d)| score = alignment × (1 - v × s) 両者は別の数値モデル 30
  18. BACKUP 補足:候補と影響範囲を絞る dotnet-coupling --hotspots 5 ./src dotnet-coupling --impact Order --depth

    2 ./src dotnet-coupling --trace Repository.Save \ --mode semantic ./MyApp.sln 32