Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Pythonソースコードの構造可視化とそれがもたらすもの
Search
yosu
August 28, 2020
Programming
5.6k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Pythonソースコードの構造可視化とそれがもたらすもの
yosu
August 28, 2020
Other Decks in Programming
See All in Programming
市販E-Readerを乗っ取れ 〜Embedded Swiftで電子ペーパーガジェットを制御する〜
trickart
0
200
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
280
Starting & Sustaining Code-Based E2E Testing for Non-Coding QA Teams( #jasstniigata )
teyamagu
PRO
1
490
大喜利で理解するLLM as a Judge / Understanding LLM-as-a-Judge through Ogiri
rockname
0
160
仕様駆動開発による爆速プロダクト開発 / Bakusoku Spec Driven Development
kobakei
0
120
App Intentsのビルドプロセスを支える技術
kntkymt
0
420
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
250
新卒PdEのリアル
ryu1013
1
510
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
270
Intent as Code
shoppingjaws
6
1.1k
iOSDC2026登壇資料.pdf
riofujimon
0
180
LoopHub - ローカルで動く GitHub で、AI と共同開発
jugyo
1
560
Featured
See All Featured
Six Lessons from altMBA
skipperchong
29
4.5k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Utilizing Notion as your number one productivity tool
mfonobong
4
590
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.3k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
530
Ethics towards AI in product and experience design
skipperchong
2
380
Darren the Foodie - Storyboard
khoart
PRO
4
3.9k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
560
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
470
Music & Morning Musume
bryan
48
7.4k
Odyssey Design
rkendrick25
PRO
2
810
Transcript
Pythonソースコードの 構造可視化 とそれがもたらすもの PyCon JP 2020 #pyconjp_2
自己紹介 @yosu 2 years Web App & Crawler 今月まで @
お手伝い @
本日お話すること 背景 見えてくるもの 構造 と その重要性 可視化の 必要性
背景 見えてくるもの 構造 と その重要性 可視化の 必要性 本日お話すること
背景 500ファイル以上あるPythonアプリケーションのPython2/3移行プロジェクト に参加 最初に移行するべき対象を見つけ出すため、簡易的なスクリプトで各パッケージ 間の依存関係を明らかにした。 うまく対象を選び、最初の移行は大きなトラブルもなく無事完了。 他にも、実際に可視化して見ると循環参照のような望ましくない構造や、依存が 多すぎるモジュールなど改善に生かす手がかりが得られることに気づいた。
背景 見えてくるもの 構造 と その重要性 可視化の 必要性
構造とは?
None
一つの全体を構成する 部分同士の関係性 部分はそれぞれが 役割・責務を持つ
None
屋根 窓 床 天井 階段
屋根 窓 床 階段 天井 雨を防ぐ
屋根 窓 床 階段 天井 光を通す 雨を防ぐ
屋根 窓 床 階段 天井 光を通す 雨を防ぐ 1階と2階 をつなぐ
Python アプリケーション の場合
None
None
PI = 3.1415926535
PI = 3.1415926535 def area(radius): return PI * radius **
2
PI = 3.1415926535 class Circle: def __init__(self, radius): self.radius =
radius def area(self): return PI * self.radius ** 2
import sys from figure import Circle def main(): radius =
float(sys.argv[1]) circle = Circle(radius) print(circle.area())
area() PI main() Circle figure 参照 参照 参照 所有 所有
呼出し
area() PI main() Circle figure 依存 依存 依存 依存 依存
依存
area() PI main() Circle figure 名前が 役割・責務 を表す
依存関係の 特徴
A B 依存先 がないと機能しない ❌
A B 依存先 の変化で影響を受ける
今回のスコープ
全体を捉えるために、 モジュール同士の 依存関係をみていく
jig-py ⚒
github.com/levii/jig-py
イメージ
jig-pyの由来 Java製のコードによる設計支援ツール Jig(irofさん作)に由来。 https://github.com/dddjava/jig 三層+ドメインモデルの アーキテクチャを想定し、 様々な可視化ができる。
jig-pyはまだ モジュール関係のみ 可視化
話を戻して ↩
なぜ構造に 着目するか?
ソフトウェア だから
ソフト =柔軟に変化できる ここに価値がある
None
つまりソフトウェアの優位性は、開発サイクルが短く、 アイデアを出してからプロトタイプを作り、エラーを 発見して修正するまでが短時間かつローコストでできる ことにある。 もし設計プロセスで技術者が絶対にミスを犯さないのな ら、ハードウェアもソフトウェアもコストはさほど変わ らないかもしれない。だが実際にはミスは避けられない のだから、何か特別な理由でもない限り、ソフトウェア のほうが好ましいことになる。 ソフトウェアの優位性
つまりソフトウェアの優位性は、開発サイクルが短く、 アイデアを出してからプロトタイプを作り、エラーを 発見して修正するまでが短時間かつローコストでできる ことにある。 もし設計プロセスで技術者が絶対にミスを犯さないのな ら、ハードウェアもソフトウェアもコストはさほど変わ らないかもしれない。だが実際にはミスは避けられない のだから、何か特別な理由でもない限り、ソフトウェア のほうが好ましいことになる。 ソフトウェアの優位性
構造が影響を及ぼす
None
リファクタリングとは ソフトウェアの 外部的振る舞いを保ったままで、 内部の構造を改善していく作業のこと。 リファクタリングを行なえば、以前に書いたコードの 設計が向上することになる。
わるい構造
よい構造 わるい構造
よい構造 わるい構造 リファクタリング
よい構造 リファクタリング 変更が危険で やっかい 機能追加・バグフィクス が容易 開発スピードが安定 わるい構造
よい構造 リファクタリング 変更が危険で やっかい 機能追加・バグフィクス が容易 開発スピードが安定 わるい構造
どうやって 構造を みていくか
None
None
None
そのままでは 見えにくい
背景 見えてくるもの 構造 と その重要性 可視化の 必要性
None
単純に可視化 してみると
None
None
うまく可視化する必要
Google Earth
None
None
None
Python アプリケーション を探索
None
None
None
None
None
None
None
None
None
None
を使って 探索的に可視化する
① 初期状態
ステップ1: 解析・情報収集 "common.bind" -> "common.group.application"; "common.context.builder" -> "common.context.domain"; "event.application.event_history" ->
"framework.paginator"; "event.application.repository" -> "event.domain"; "feedback.application.announcement" -> "common.exceptions"; "feedback.application.idea" -> "framework.logging"; "feedback.domain.idea" -> "event.domain"; "feedback.domain.idea" -> "notify.domain.email_builder"; "framework.paginator" -> "framework.logging"; "integration.bind" -> "event.domain.event_handler_setting"; "main" -> "framework"; "main" -> "task.routes"; "notify.application" -> "common.user.application"; "task.domain.notification" -> "common.system_setting.application"; "test_helpers.feedback" -> "common.user.domain";
ステップ2: トップレベルに集約 "common.bind" -> "common.group.application"; "common.context.builder" -> "common.context.domain"; "event.application.event_history" ->
"framework.paginator"; "event.application.repository" -> "event.domain"; "feedback.application.announcement" -> "common.exceptions"; "feedback.application.idea" -> "framework.logging"; "feedback.domain.idea" -> "event.domain"; "feedback.domain.idea" -> "notify.domain.email_builder"; "framework.paginator" -> "framework.logging"; "integration.bind" -> "event.domain.event_handler_setting"; "main" -> "framework"; "main" -> "task.routes"; "notify.application" -> "common.user.application"; "task.domain.notification" -> "common.system_setting.application"; "test_helpers.feedback" -> "common.user.domain";
ステップ2: トップレベルに集約 "common" -> "common"; "common" -> "common"; "event" ->
"framework"; "event" -> "event"; "feedback" -> "common"; "feedback" -> "framework"; "feedback" -> "event"; "feedback" -> "notify"; "framework" -> "framework"; "integration" -> "event"; "main" -> "framework"; "main" -> "task"; "notify" -> "common"; "task" -> "common"; "test_helpers" -> "common";
ステップ3: 重複の除去 "common" -> "common"; "common" -> "common"; "event" ->
"framework"; "event" -> "event"; "feedback" -> "common"; "feedback" -> "framework"; "feedback" -> "event"; "feedback" -> "notify"; "framework" -> "framework"; "integration" -> "event"; "main" -> "framework"; "main" -> "task"; "notify" -> "common"; "task" -> "common"; "test_helpers" -> "common";
"common" -> "common"; "event" -> "framework"; "event" -> "event"; "feedback"
-> "common"; "feedback" -> "framework"; "feedback" -> "event"; "feedback" -> "notify"; "framework" -> "framework"; "integration" -> "event"; "main" -> "framework"; "main" -> "task"; "notify" -> "common"; "task" -> "common"; "test_helpers" -> "common"; ステップ3: 重複の除去
ステップ4: セルフループの削除 "common" -> "common"; "event" -> "framework"; "event" ->
"event"; "feedback" -> "common"; "feedback" -> "framework"; "feedback" -> "event"; "feedback" -> "notify"; "framework" -> "framework"; "integration" -> "event"; "main" -> "framework"; "main" -> "task"; "notify" -> "common"; "task" -> "common"; "test_helpers" -> "common";
ステップ4: セルフループの削除 "event" -> "framework"; "feedback" -> "common"; "feedback" ->
"framework"; "feedback" -> "event"; "feedback" -> "notify"; "integration" -> "event"; "main" -> "framework"; "main" -> "task"; "notify" -> "common"; "task" -> "common"; "test_helpers" -> "common";
ステップ5: ビジュアライズ(初期状態準備完了)
② 探索
見たくないものを除去
見たくないものを除去
見たくないものを除去
詳しく見たいものを掘り下げる
詳しく見たいものを掘り下げる
注意
前提として 人に優しい粒度で パッケージ(階層)化 されてないと厳しい
デモ
背景 見えてくるもの 構造 と その重要性 可視化の 必要性
特徴的なパターン 依存しかしない: エントリーポイント/ルーター
特徴的なパターン 依存しかしない: エントリーポイント/ルーター 他のモジュールの 呼び分けを行う。 機能的な依存をしない ようにすると、変化の 影響を直接受けない ので怖くない。
特徴的なパターン 依存されるが他への依存が少ない(しない): アプリケーション基盤、共通部品
特徴的なパターン 依存されるが他への依存が少ない(しない): アプリケーション基盤、共通部品 変化させにくい部分。 必要とされる概念を きちんとモデリング、 一度作れば変化しなく て済むようにする。
特徴的なパターン 依存されるし、他への依存も多い: ビジネスロジック/コアドメイン
特徴的なパターン 依存されるし、他への依存も多い: ビジネスロジック/コアドメイン アプリケーションの 中核となる部分。 環境やビジネスの変 化に応じて変化して いく。
変 更 頻 度 依存されている数 多 い 少 な い
多い 少ない
変 更 頻 度 依存されている数 多 い 少 な い
多い 少ない アプリケーション基盤 エントリーポ イント ビジネス ロジック
変 更 頻 度 依存されている数 多 い 少 な い
多い 少ない アプリケーション基盤 ビジネス ロジック エントリーポ イント ここを 他と隔離しつつ きちんと保つ ことが重要
☠不吉な匂い
相互依存 / 循環参照 A B
相互依存 / 循環参照 A B
相互依存 / 循環参照 A B
相互依存 / 循環参照 A B
相互依存 / 循環参照 A B
相互依存 / 循環参照 A B
相互依存 / 循環参照 A B
相互依存 / 循環参照 A B
相互依存 / 循環参照
相互依存 / 循環参照
相互依存 / 循環参照
相互依存 / 循環参照
相互依存 / 循環参照
たいていは 責務違反
名前がない 隠れた役割を持つ
まとめ
まとめ 1. 構造とは一つの全体を構成する部分の関係・役割 2. 構造のあり方がソフトウェアの柔軟性に影響を及ぼす (リファクタリングはよい構造を作るための活動) 3. うまく可視化することで構造を捉える 4. 構造の特徴・パターンから中核となる場所を見つけ、そこを
きちんと保つことが重要