<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>依存関係注入  |  Python-memo｜自動化・AI・Web開発の実験室</title>
	<atom:link href="https://python.cbagames.jp/tag/%E4%BE%9D%E5%AD%98%E9%96%A2%E4%BF%82%E6%B3%A8%E5%85%A5/feed/" rel="self" type="application/rss+xml" />
	<link>https://python.cbagames.jp</link>
	<description>Pythonで、できるをふやそう。</description>
	<lastBuildDate>Wed, 24 Dec 2025 08:22:03 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>

<image>
	<url>https://python.cbagames.jp/wp-content/uploads/2025/06/cropped-497d491d54402de785c9e043bfa0620a-32x32.png</url>
	<title>依存関係注入  |  Python-memo｜自動化・AI・Web開発の実験室</title>
	<link>https://python.cbagames.jp</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Pythonの依存関係注入（DI）をやさしく解説｜テストしやすい設計への第一歩</title>
		<link>https://python.cbagames.jp/2025/12/24/python-di-dependency-injection/</link>
					<comments>https://python.cbagames.jp/2025/12/24/python-di-dependency-injection/#respond</comments>
		
		<dc:creator><![CDATA[asukapy]]></dc:creator>
		<pubDate>Wed, 24 Dec 2025 08:20:34 +0000</pubDate>
				<category><![CDATA[クラス設計・OOP入門]]></category>
		<category><![CDATA[DI]]></category>
		<category><![CDATA[DIP]]></category>
		<category><![CDATA[FastAPI]]></category>
		<category><![CDATA[IoC]]></category>
		<category><![CDATA[ユニットテスト]]></category>
		<category><![CDATA[依存関係注入]]></category>
		<category><![CDATA[設計]]></category>
		<guid isPermaLink="false">https://python.cbagames.jp/?p=712</guid>

					<description><![CDATA[Pythonでコードを書いていると、「あとから直しづらいな…」「テストを書くのがしんどいな…」と感じたことはありませんか？ その原因の多くは、クラス同士が強く結びつきすぎている設計にあります。 この状態をそのままにしてい [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Pythonでコードを書いていると、「あとから直しづらいな…」「テストを書くのがしんどいな…」と感じたことはありませんか？</p>



<p>その原因の多くは、<strong>クラス同士が強く結びつきすぎている設計</strong>にあります。 この状態をそのままにしていると、ちょっとした変更でも思わぬ場所が壊れたり、テストのたびに外部APIやデータベースに振り回されたりしてしまいます。</p>



<p>そこで登場するのが、<strong>依存関係注入（DI：Dependency Injection）</strong>という考え方です。 DIは「難しい上級者向けテクニック」に見えがちですが、実は<strong>コードをやさしく、長生きさせるための設計の工夫</strong>なんです。</p>



<p>この記事では、Python初心者〜中級者の方を想定して、</p>



<ul class="wp-block-list">
<li>なぜDIが必要になるのか</li>



<li>DI・IoC・DIPの関係はどうなっているのか</li>



<li>PythonではどうやってDIを実装するのか</li>



<li>テストがなぜ一気に書きやすくなるのか</li>
</ul>



<p>といったポイントを、できるだけ噛み砕いて解説していきます。</p>



<p>FastAPIで <code>Depends()</code> を見かけたことがある方や、 「モックって何のためにあるの？」とモヤっとしている方にも、きっとヒントになるはずです。</p>



<p>コードを<strong>ガチガチに固める設計</strong>から、 <strong>必要に応じて入れ替えられる柔らかい設計</strong>へ。 その第一歩として、DIの世界を一緒にのぞいてみましょう ✨</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-2"><label class="toc-title" for="toc-checkbox-2">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">1. なぜDIが必要なのか？密結合が生む3つの問題</a><ol><li><a href="#toc2" tabindex="0">問題① クラス同士が強く結びついてしまう（密結合）</a></li><li><a href="#toc3" tabindex="0">問題② テストがとにかく書きづらい</a></li><li><a href="#toc4" tabindex="0">問題③ 将来の変更コストがどんどん膨らむ</a></li></ol></li><li><a href="#toc5" tabindex="0">2. DI・IoC・DIPの関係を整理しよう</a><ol><li><a href="#toc6" tabindex="0">DIは「実装テクニック」</a></li><li><a href="#toc7" tabindex="0">IoCは「考え方・設計の方向性」</a></li><li><a href="#toc8" tabindex="0">DIPは「守るべき設計原則」</a></li><li><a href="#toc9" tabindex="0">3つの関係を一言でまとめると</a></li><li><a href="#toc10" tabindex="0">設計思想を深く理解したい人へ</a></li></ol></li><li><a href="#toc11" tabindex="0">3. PythonでDIを実装する基本パターン</a><ol><li><a href="#toc12" tabindex="0">手順① 依存先を「抽象」で表現する</a></li><li><a href="#toc13" tabindex="0">手順② 具体的な実装クラスを用意する</a></li><li><a href="#toc14" tabindex="0">手順③ コンストラクタ注入（いちばんおすすめ）</a></li><li><a href="#toc15" tabindex="0">メソッド注入という選択肢</a></li><li><a href="#toc16" tabindex="0">「DIっぽく書く」だけでも効果はある</a></li></ol></li><li><a href="#toc17" tabindex="0">4. リファクタリング視点で見るDI導入の効果</a><ol><li><a href="#toc18" tabindex="0">「変更したいのに、触るのが怖い」コードの正体</a></li><li><a href="#toc19" tabindex="0">DIは「安全に切り出すための足場」</a></li><li><a href="#toc20" tabindex="0">DIは「あとから効いてくる」設計投資</a></li><li><a href="#toc21" tabindex="0">既存コードを改善したい人へ</a></li></ol></li><li><a href="#toc22" tabindex="0">5. テストとDIの相性が最強な理由</a><ol><li><a href="#toc23" tabindex="0">DIがないと、テストはなぜつらいのか</a></li><li><a href="#toc24" tabindex="0">DIがあると「差し替え」が自然にできる</a></li><li><a href="#toc25" tabindex="0">「呼ばれたかどうか」だけを検証できる安心感</a></li><li><a href="#toc26" tabindex="0">DIとテストはセットで考えると強い</a></li><li><a href="#toc27" tabindex="0">テスト駆動の視点で理解したい人へ</a></li></ol></li><li><a href="#toc28" tabindex="0">6. DIフレームワークはいつ使うべきか</a><ol><li><a href="#toc29" tabindex="0">手動DIで十分なケース</a></li><li><a href="#toc30" tabindex="0">DIフレームワークが欲しくなる瞬間</a></li><li><a href="#toc31" tabindex="0">代表的なDIフレームワーク</a><ol><li><a href="#toc32" tabindex="0">dependency-injector</a></li><li><a href="#toc33" tabindex="0">injector</a></li></ol></li><li><a href="#toc34" tabindex="0">FastAPIのDepends()はDIの入門に最適</a></li><li><a href="#toc35" tabindex="0">最初の判断基準はこれでOK</a></li></ol></li><li><a href="#toc36" tabindex="0">まとめ</a><ol><li><a href="#toc37" tabindex="0">あわせて読みたい</a></li><li><a href="#toc38" tabindex="0">参考文献</a></li></ol></li><li><a href="#toc39" tabindex="0">よくある質問（Q&amp;A）</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">1. なぜDIが必要なのか？密結合が生む3つの問題</span></h2>



<p>まずは、DI（依存関係注入）が<strong>なぜ必要とされるのか</strong>から見ていきましょう。 多くの場合、問題は「動いてはいるけど、あとがつらいコード」から始まります。</p>



<p>Pythonでクラス設計をするとき、次のような書き方をしてしまうことはよくあります。</p>



<pre class="wp-block-code"><code>
class UserService:
    def __init__(self):
        self.mailer = GmailSender()

    def notify(self, user):
        self.mailer.send(user.email)
</code></pre>



<p>一見するとシンプルで、何も問題がなさそうに見えますよね。 でもこの設計、じわじわと効いてくる<strong>落とし穴</strong>がいくつもあります。</p>



<h3 class="wp-block-heading"><span id="toc2">問題① クラス同士が強く結びついてしまう（密結合）</span></h3>



<p>この <code>UserService</code> は、<code>GmailSender</code> という<strong>具体的な実装</strong>に直接依存しています。 これはつまり、</p>



<ul class="wp-block-list">
<li>メール送信方法を変更したい</li>



<li>別の送信サービスを使いたい</li>
</ul>



<p>といった要望が出たときに、<strong>UserService自体を修正しなければならない</strong>ということです。</p>



<p>クラス同士が「溶接」されたような状態になり、 一部分を変えたいだけなのに、周囲まで影響が広がってしまいます。</p>



<h3 class="wp-block-heading"><span id="toc3">問題② テストがとにかく書きづらい</span></h3>



<p>さらに厄介なのがテストです。</p>



<p>このままでは、テスト時にも本物の <code>GmailSender</code> が使われてしまいます。 すると、</p>



<ul class="wp-block-list">
<li>テスト実行で実際にメールが飛ぶ</li>



<li>外部サービスの状態にテスト結果が左右される</li>



<li>テストが遅く、不安定になる</li>
</ul>



<p>といった問題が起きがちです。</p>



<p>「本当はメール送信なんてしたくない。呼ばれたかどうかだけ確認したい」 そんな当たり前のテストが、書けなくなってしまうんですね。</p>



<h3 class="wp-block-heading"><span id="toc4">問題③ 将来の変更コストがどんどん膨らむ</span></h3>



<p>最初は小さなクラスでも、機能追加や仕様変更を重ねるうちに、</p>



<ul class="wp-block-list">
<li>あちこちに同じ修正が必要</li>



<li>どこを直せばいいのかわからない</li>



<li>触るのが怖くて変更を避ける</li>
</ul>



<p>という状態に陥りがちです。</p>



<p>このような「変更に弱いコード」の正体は、 <strong>依存関係がコードの中に埋め込まれてしまっていること</strong>にあります。</p>



<p>DIは、この依存関係を<strong>外に出す</strong>ことで、</p>



<ul class="wp-block-list">
<li>クラス同士の結びつきを弱め</li>



<li>テストしやすくし</li>



<li>変更に強い設計にする</li>
</ul>



<p>ための考え方です。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://python.cbagames.jp/wp-content/uploads/2025/06/9d9697ea94c9608a27d0bde31599ba86-150x150.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p>次のセクションでは、 <strong>DI・IoC・DIP</strong> という、よく一緒に語られる言葉の関係を整理しながら、 DIの正体をもう少しクリアにしていきます。</p>
</div></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>


<p><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2494518121553371"
     crossorigin="anonymous"></script><br />
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-2494518121553371"
     data-ad-slot="2936039508"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>



<h2 class="wp-block-heading"><span id="toc5">2. DI・IoC・DIPの関係を整理しよう</span></h2>



<p>DIの話を調べていると、ほぼ確実に一緒に出てくる言葉があります。</p>



<ul class="wp-block-list">
<li>IoC（Inversion of Control：制御の反転）</li>



<li>DIP（Dependency Inversion Principle：依存関係逆転の原則）</li>
</ul>



<p>どれも似た文脈で使われるので混乱しがちですが、 それぞれの<strong>役割と立ち位置</strong>を整理すると、DIの理解が一気に楽になります。</p>



<h3 class="wp-block-heading"><span id="toc6">DIは「実装テクニック」</span></h3>



<p>まず、<strong>DI（依存関係注入）</strong>はとてもシンプルです。</p>



<p><strong>「必要なものを、自分で作らず、外から渡してもらう」</strong><br>これがDIの本質です。</p>



<p>先ほどの例で言えば、</p>



<ul class="wp-block-list">
<li>GmailSenderをクラス内部でnewしない</li>



<li>外から渡されたメール送信オブジェクトを使う</li>
</ul>



<p>という形に変えることがDIです。</p>



<p>DIは<strong>コードとして実装できる具体的な手法</strong>であり、 Pythonではコンストラクタ引数や関数引数で自然に表現できます。</p>



<h3 class="wp-block-heading"><span id="toc7">IoCは「考え方・設計の方向性」</span></h3>



<p>次に <strong>IoC（制御の反転）</strong> です。</p>



<p>これは少し抽象的で、</p>



<p><strong>「何を使うか」「どう作るか」という主導権を、 クラス自身から外部に移す考え方</strong></p>



<p>を指します。</p>



<p>DIは、<strong>IoCを実現する代表的な手段</strong>のひとつです。</p>



<p>つまり、</p>



<ul class="wp-block-list">
<li>IoC：設計思想</li>



<li>DI：それをコードで実現する方法</li>
</ul>



<p>という関係になります。</p>



<h3 class="wp-block-heading"><span id="toc8">DIPは「守るべき設計原則」</span></h3>



<p>最後に <strong>DIP（依存関係逆転の原則）</strong> です。</p>



<p>DIPでは、次の2点が重要になります。</p>



<ul class="wp-block-list">
<li>上位モジュールは下位モジュールに依存してはいけない</li>



<li>どちらも「抽象」に依存すべきである</li>
</ul>



<p>ここで言う「抽象」とは、Pythonであれば</p>



<ul class="wp-block-list">
<li>抽象クラス（abc）</li>



<li>プロトコル（typing.Protocol）</li>
</ul>



<p>などを指します。</p>



<p>DIを使って依存関係を外から注入し、 その依存先を「抽象」にしておくことで、 <strong>DIPを自然に満たす設計</strong>になります。</p>



<h3 class="wp-block-heading"><span id="toc9">3つの関係を一言でまとめると</span></h3>



<ul class="wp-block-list">
<li><strong>IoC</strong>：設計の考え方</li>



<li><strong>DIP</strong>：守るべき原則</li>



<li><strong>DI</strong>：それを実装するための手段</li>
</ul>



<p>この関係が見えてくると、 「DIを使うかどうか」で悩むよりも、</p>



<p><strong>「変更しやすく、テストしやすい構造になっているか？」</strong></p>



<p>を基準に設計を考えられるようになります。</p>



<h3 class="wp-block-heading"><span id="toc10">設計思想を深く理解したい人へ</span></h3>



<p>ここまで読んで、</p>



<ul class="wp-block-list">
<li>なぜ「抽象」に依存するのか</li>



<li>依存の向きをどう設計すべきか</li>
</ul>



<p>をもっと体系的に理解したくなった方には、次の一冊がとても相性がいいです。</p>



<p><strong>Clean Architecture　達人に学ぶソフトウェアの構造と設計</strong><br>✅ <a rel="noopener" target="_blank" href="https://amzn.to/3MSB26T">Amazonでチェックする</a> ｜ ✅ <a rel="noopener" target="_blank" href="https://a.r10.to/hkO11N">楽天でチェックする</a></p>



<p>DIやDIPが「テクニック」ではなく、 <strong>ソフトウェアを長く保つための考え方</strong>だと実感できる一冊です。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://python.cbagames.jp/wp-content/uploads/2025/06/9d9697ea94c9608a27d0bde31599ba86-150x150.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p>次のセクションでは、 いよいよ<strong>PythonでDIをどう書くのか</strong>を、 シンプルなコード例で見ていきます。</p>
</div></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>


<p><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2494518121553371"
     crossorigin="anonymous"></script><br />
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-2494518121553371"
     data-ad-slot="2936039508"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>



<h2 class="wp-block-heading"><span id="toc11">3. PythonでDIを実装する基本パターン</span></h2>



<p>ここからは、Pythonで<strong>依存関係注入（DI）をどう書くのか</strong>を見ていきます。 難しい仕組みは不要で、まずは<strong>素のPython</strong>で理解するのがいちばんです。</p>



<h3 class="wp-block-heading"><span id="toc12">手順① 依存先を「抽象」で表現する</span></h3>



<p>DIの第一歩は、<strong>具体的なクラスではなく、役割（インターフェース）に依存する</strong>ことです。</p>



<p>Pythonでは <code>abc</code> モジュールを使って、抽象クラスを定義できます。</p>



<pre class="wp-block-code"><code>
from abc import ABC, abstractmethod

class MailSender(ABC):
    @abstractmethod
    def send(self, email: str) -&gt; None:
        pass
</code></pre>



<p>ここでは、</p>



<ul class="wp-block-list">
<li>「メールを送る」という役割だけを定義</li>



<li>どのサービスを使うかは決めない</li>
</ul>



<p>という状態を作っています。</p>



<h3 class="wp-block-heading"><span id="toc13">手順② 具体的な実装クラスを用意する</span></h3>



<p>次に、この抽象を実装するクラスを作ります。</p>



<pre class="wp-block-code"><code>
class GmailSender(MailSender):
    def send(self, email: str) -&gt; None:
        print(f"Gmailで {email} にメールを送信しました")
</code></pre>



<p>将来、別のサービスに切り替えたくなった場合でも、</p>



<ul class="wp-block-list">
<li>YahooSender</li>



<li>MockMailSender（テスト用）</li>
</ul>



<p>などを追加するだけで対応できます。</p>



<h3 class="wp-block-heading"><span id="toc14">手順③ コンストラクタ注入（いちばんおすすめ）</span></h3>



<p>ここで、依存関係を<strong>外から渡す</strong>ようにします。</p>



<pre class="wp-block-code"><code>
class UserService:
    def __init__(self, mail_sender: MailSender):
        self.mail_sender = mail_sender

    def notify(self, email: str) -&gt; None:
        self.mail_sender.send(email)
</code></pre>



<p>ポイントは、</p>



<ul class="wp-block-list">
<li><code>GmailSender</code> を直接生成していない</li>



<li><code>MailSender</code> という抽象に依存している</li>
</ul>



<p>という点です。</p>



<p>実際に使うときは、外側で組み立てます。</p>



<pre class="wp-block-code"><code>
mail_sender = GmailSender()
service = UserService(mail_sender)

service.notify("user@example.com")
</code></pre>



<p>これが<strong>コンストラクタ注入</strong>です。 オブジェクト生成時に必要な依存がすべて揃うので、 <strong>安全で読みやすい</strong>のが大きなメリットです。</p>



<h3 class="wp-block-heading"><span id="toc15">メソッド注入という選択肢</span></h3>



<p>場合によっては、依存関係をメソッド引数で渡すこともあります。</p>



<pre class="wp-block-code"><code>
class UserService:
    def notify(self, email: str, mail_sender: MailSender) -&gt; None:
        mail_sender.send(email)
</code></pre>



<p>この方法は、</p>



<ul class="wp-block-list">
<li>その処理でしか使わない依存</li>



<li>一時的な振る舞いの切り替え</li>
</ul>



<p>に向いています。</p>



<p>ただし、クラス全体で使う依存は <strong>コンストラクタ注入の方が意図が明確</strong>なので、基本はこちらを選びましょう。</p>



<h3 class="wp-block-heading"><span id="toc16">「DIっぽく書く」だけでも効果はある</span></h3>



<p>最初から抽象クラスを用意しなくても、</p>



<ul class="wp-block-list">
<li>外からオブジェクトを渡す</li>



<li>内部でnewしない</li>
</ul>



<p>これだけでも、設計はかなり改善されます。</p>



<p>DIは「完璧にやること」よりも、 <strong>依存を外に出す意識</strong>を持つことが何より大切です。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://python.cbagames.jp/wp-content/uploads/2025/06/9d9697ea94c9608a27d0bde31599ba86-150x150.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p>次のセクションでは、 このDIが<strong>リファクタリングの現場でどう役立つのか</strong>を、 実務視点で見ていきます。</p>
</div></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>


<p><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2494518121553371"
     crossorigin="anonymous"></script><br />
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-2494518121553371"
     data-ad-slot="2936039508"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>



<h2 class="wp-block-heading"><span id="toc17">4. リファクタリング視点で見るDI導入の効果</span></h2>



<p>DIは「最初からきれいに設計できる人のためのもの」と思われがちですが、 実際の現場では<strong>リファクタリングの途中で導入されるケース</strong>の方が圧倒的に多いです。</p>



<p>ここでは、DIがあることで<strong>何がどう楽になるのか</strong>を、 リファクタリングの視点から見ていきましょう。</p>



<h3 class="wp-block-heading"><span id="toc18">「変更したいのに、触るのが怖い」コードの正体</span></h3>



<p>長く使われているコードほど、こんな状態になりがちです。</p>



<ul class="wp-block-list">
<li>クラスの中で依存オブジェクトを直接生成している</li>



<li>同じような処理があちこちに散らばっている</li>



<li>テストがなく、動作確認は手動のみ</li>
</ul>



<p>この状態で仕様変更が入ると、</p>



<ul class="wp-block-list">
<li>どこを直せばいいかわからない</li>



<li>直したつもりが別の場所で壊れる</li>
</ul>



<p>という<strong>負のループ</strong>に陥ります。</p>



<h3 class="wp-block-heading"><span id="toc19">DIは「安全に切り出すための足場」</span></h3>



<p>DIを導入すると、依存関係が外に見える形になります。</p>



<p>すると、</p>



<ul class="wp-block-list">
<li>このクラスは何に依存しているのか</li>



<li>どこまでが責務なのか</li>
</ul>



<p>が明確になり、 <strong>安心してクラスを分割・整理できる</strong>ようになります。</p>



<p>いきなり完璧な設計を目指す必要はありません。</p>



<ul class="wp-block-list">
<li>まずは new している部分を外に出す</li>



<li>引数で受け取れる形にする</li>
</ul>



<p>これだけでも、コードは一段階「柔らかく」なります。</p>



<h3 class="wp-block-heading"><span id="toc20">DIは「あとから効いてくる」設計投資</span></h3>



<p>DIの効果は、導入した瞬間よりも、</p>



<ul class="wp-block-list">
<li>仕様変更が入ったとき</li>



<li>テストを書き始めたとき</li>



<li>別の人がコードを触るとき</li>
</ul>



<p>に強く実感できます。</p>



<p>「最初は少し面倒だったけど、今は助かっている」 DIは、そんなタイプの設計です。</p>



<h3 class="wp-block-heading"><span id="toc21">既存コードを改善したい人へ</span></h3>



<p>すでに動いているコードにDIを入れたい場合、 <strong>どう直せば安全なのか</strong>で悩むことが多いと思います。</p>



<p>そんなときにとても参考になるのが、次の一冊です。</p>



<p><strong>リファクタリング（第2版）</strong><br>✅ <a rel="noopener" target="_blank" href="https://amzn.to/498HTAG">Amazonでチェックする</a> ｜ ✅ <a rel="noopener" target="_blank" href="https://a.r10.to/hg6BrZ">楽天でチェックする</a></p>



<p>DIを直接解説する本ではありませんが、</p>



<ul class="wp-block-list">
<li>変更を小さく、安全に進める考え方</li>



<li>「直していいコード」と「触る前に準備が必要なコード」の見極め</li>
</ul>



<p>が非常にわかりやすく整理されています。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://python.cbagames.jp/wp-content/uploads/2025/06/9d9697ea94c9608a27d0bde31599ba86-150x150.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p>次のセクションでは、 DIと<strong>テストがなぜ相性抜群なのか</strong>を、 具体的なテストの流れと一緒に見ていきます。</p>
</div></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>


<p><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2494518121553371"
     crossorigin="anonymous"></script><br />
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-2494518121553371"
     data-ad-slot="2936039508"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>



<h2 class="wp-block-heading"><span id="toc22">5. テストとDIの相性が最強な理由</span></h2>



<p>DIの価値がいちばんわかりやすく表れるのが、<strong>テストを書くとき</strong>です。 ここでは、「なぜDIがあるとテストが一気に楽になるのか」を具体的に見ていきましょう。</p>



<h3 class="wp-block-heading"><span id="toc23">DIがないと、テストはなぜつらいのか</span></h3>



<p>DIを使っていないコードでは、テスト中でも</p>



<ul class="wp-block-list">
<li>実際のデータベースに接続してしまう</li>



<li>外部APIを本当に呼んでしまう</li>



<li>ファイルやネットワークに依存してしまう</li>
</ul>



<p>といった問題が起きがちです。</p>



<p>すると、</p>



<ul class="wp-block-list">
<li>テストが遅い</li>



<li>環境によって結果が変わる</li>



<li>失敗した理由がわかりにくい</li>
</ul>



<p>という、あまりうれしくない状況になります。</p>



<h3 class="wp-block-heading"><span id="toc24">DIがあると「差し替え」が自然にできる</span></h3>



<p>DIを使っていれば、テスト時に<strong>本物の依存先を使う必要がありません</strong>。</p>



<p>たとえば、先ほどの <code>MailSender</code> を、 テスト用のクラスに差し替えることができます。</p>



<pre class="wp-block-code"><code>
class FakeMailSender(MailSender):
    def __init__(self):
        self.called = False

    def send(self, email: str) -&gt; None:
        self.called = True
</code></pre>



<p>これをテスト対象に注入すると、</p>



<pre class="wp-block-code"><code>
def test_notify_calls_send():
    fake_sender = FakeMailSender()
    service = UserService(fake_sender)

    service.notify("test@example.com")

    assert fake_sender.called
</code></pre>



<p>外部環境に一切依存しない、 <strong>高速で再現性のあるテスト</strong>が書けるようになります。</p>



<h3 class="wp-block-heading"><span id="toc25">「呼ばれたかどうか」だけを検証できる安心感</span></h3>



<p>テストで本当に確認したいのは、</p>



<ul class="wp-block-list">
<li>メールが送信されたか</li>



<li>DBに保存されたか</li>
</ul>



<p>ではなく、</p>



<p><strong>「その責務を持つ処理が、正しく呼ばれたか」</strong></p>



<p>であることがほとんどです。</p>



<p>DIを使えば、 テスト対象のクラスは<strong>自分の仕事だけ</strong>に集中できます。</p>



<h3 class="wp-block-heading"><span id="toc26">DIとテストはセットで考えると強い</span></h3>



<p>DIだけを導入しても、テストを書かなければ恩恵は半分です。 逆に、テストを書こうとすると、DIのありがたみをすぐに実感します。</p>



<p>この2つは、お互いを支え合う関係なんですね。</p>



<h3 class="wp-block-heading"><span id="toc27">テスト駆動の視点で理解したい人へ</span></h3>



<p>「そもそも、なぜテストしやすい設計が大事なのか」 「設計とテストはどうつながっているのか」</p>



<p>を体系的に理解したい方には、次の一冊がとても参考になります。</p>



<p><strong>テスト駆動開発</strong><br>✅ <a rel="noopener" target="_blank" href="https://amzn.to/4qgYnNO">Amazonでチェックする</a> ｜ ✅ <a rel="noopener" target="_blank" href="https://a.r10.to/hFgqHZ">楽天でチェックする</a></p>



<p>DIを「テクニック」ではなく、 <strong>設計と品質を守るための考え方</strong>として理解できるようになります。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://python.cbagames.jp/wp-content/uploads/2025/06/9d9697ea94c9608a27d0bde31599ba86-150x150.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p>次のセクションでは、 DIフレームワークやFastAPIの <code>Depends()</code> を <strong>いつ・どこで使うべきか</strong>を整理していきます。</p>
</div></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>


<p><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2494518121553371"
     crossorigin="anonymous"></script><br />
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-2494518121553371"
     data-ad-slot="2936039508"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>



<h2 class="wp-block-heading"><span id="toc28">6. DIフレームワークはいつ使うべきか</span></h2>



<p>ここまでで、素のPythonだけでもDIは十分に実装できることが分かりました。 では、<strong>DIフレームワークはいつ必要になるのでしょうか？</strong></p>



<p>結論から言うと、 <strong>「依存関係の組み立てがつらくなったとき」</strong>が導入のタイミングです。</p>



<h3 class="wp-block-heading"><span id="toc29">手動DIで十分なケース</span></h3>



<p>次のような場合は、フレームワークを使わなくても問題ありません。</p>



<ul class="wp-block-list">
<li>依存関係の数が少ない</li>



<li>オブジェクト生成の流れが単純</li>



<li>小規模なスクリプトやツール</li>
</ul>



<p>むしろ、最初からDIフレームワークを入れてしまうと、</p>



<ul class="wp-block-list">
<li>設定が多くて理解しづらい</li>



<li>コードの追跡が難しくなる</li>
</ul>



<p>といった<strong>逆効果</strong>になることもあります。</p>



<h3 class="wp-block-heading"><span id="toc30">DIフレームワークが欲しくなる瞬間</span></h3>



<p>一方で、次のようなサインが出てきたら要注意です。</p>



<ul class="wp-block-list">
<li>オブジェクト生成コードがあちこちに散らばっている</li>



<li>依存関係の入れ替えが頻繁に起こる</li>



<li>初期化順序を間違えてバグが出る</li>
</ul>



<p>この段階になると、</p>



<p><strong>「何をどこで生成しているのか分からない」</strong></p>



<p>という状態になりがちです。</p>



<p>DIフレームワークは、 この<strong>組み立ての複雑さ</strong>を一箇所に集約するための道具です。</p>



<h3 class="wp-block-heading"><span id="toc31">代表的なDIフレームワーク</span></h3>



<h4 class="wp-block-heading"><span id="toc32">dependency-injector</span></h4>



<ul class="wp-block-list">
<li>高速で柔軟</li>



<li>コンテナで依存関係を明示的に定義</li>



<li>大規模アプリ向き</li>
</ul>



<p>依存関係が増えても、 「設計図」として一覧できるのが大きな強みです。</p>



<h4 class="wp-block-heading"><span id="toc33">injector</span></h4>



<ul class="wp-block-list">
<li>アノテーション中心のシンプルな記述</li>



<li>Guice風の書き味</li>
</ul>



<p>Java経験者には馴染みやすいですが、 Pythonでは好みが分かれることもあります。</p>



<h3 class="wp-block-heading"><span id="toc34">FastAPIのDepends()はDIの入門に最適</span></h3>



<p>FastAPIを使っている方なら、 <code>Depends()</code> をすでに見たことがあるかもしれません。</p>



<p>これは、<strong>フレームワーク組み込みのDI機構</strong>です。</p>



<ul class="wp-block-list">
<li>依存関係を関数として定義できる</li>



<li>テスト時に簡単に差し替え可能</li>



<li>非同期処理とも相性が良い</li>
</ul>



<p>「DIをちゃんと使うのは初めて」という方でも、 FastAPIなら自然にDIの考え方に触れられます。</p>



<h3 class="wp-block-heading"><span id="toc35">最初の判断基準はこれでOK</span></h3>



<ul class="wp-block-list">
<li>まずは手動DIで書いてみる</li>



<li>つらくなったらフレームワークを検討する</li>
</ul>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://python.cbagames.jp/wp-content/uploads/2025/06/9d9697ea94c9608a27d0bde31599ba86-150x150.jpg" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p>DIフレームワークは<strong>魔法の道具</strong>ではありません。 あくまで、複雑さが増えたときに助けてくれる<strong>整理係</strong>です。</p>
</div></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>


<p><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2494518121553371"
     crossorigin="anonymous"></script><br />
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-2494518121553371"
     data-ad-slot="2936039508"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>



<h2 class="wp-block-heading"><span id="toc36">まとめ</span></h2>



<p>今回は、Pythonにおける<strong>依存関係注入（DI）</strong>について、 「なぜ必要なのか」という背景から、実装方法、テストやリファクタリングとの関係までを順番に見てきました。</p>



<ul class="wp-block-list">
<li>DIはコードを複雑にするためのものではない</li>



<li>変更しやすく、テストしやすい状態を保つための工夫</li>



<li>IoCやDIPとセットで考えると理解しやすい</li>
</ul>



<p>という点が、この記事の大きなポイントです。</p>



<p>私自身も、最初は「DIって回りくどいな」と感じていました。 でも、仕様変更やテスト対応が増えるにつれて、</p>



<p><strong>「DIが入っているコードは、触るのが怖くない」</strong></p>



<p>と実感するようになりました。</p>



<p>すべてのコードにDIが必要なわけではありません。 ただ、少しでも</p>



<ul class="wp-block-list">
<li>テストが書きづらい</li>



<li>変更のたびに修正箇所が増える</li>
</ul>



<p>と感じているなら、 DIはとても頼れる選択肢になります。</p>



<p>まずは小さなクラスひとつから、 <strong>「newしない設計」</strong>を意識してみてください。 それだけでも、コードの見通しはかなり変わりますよ 😊</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><span id="toc37">あわせて読みたい</span></h3>



<ul class="wp-block-list">
<li><a target="_blank" href="https://python.cbagames.jp/2025/06/13/python-pytest-beginner-guide/">Pythonでテストコードを書く方法｜初心者向けpytest入門ガイド</a></li>



<li><a target="_blank" href="https://python.cbagames.jp/2025/06/13/python-class-basic/">初心者でもすぐわかる！Pythonのクラス入門ガイド</a></li>



<li><a target="_blank" href="https://python.cbagames.jp/2025/06/23/refactoring-for-beginners/">【リファクタリングとは？】初心者向けにコード改善の基本をやさしく解説</a></li>



<li><a target="_blank" href="https://python.cbagames.jp/2025/09/19/clean-code-rules/">読みやすく変更しやすい「綺麗なコード」の書き方</a></li>



<li><a target="_blank" href="https://python.cbagames.jp/2025/06/09/fastapi-basic-usage-guide/">【初心者向け】FastAPIの基本の使い方をやさしく解説</a></li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><span id="toc38">参考文献</span></h3>



<ul class="wp-block-list">
<li><a rel="noopener" target="_blank" href="https://www.datacamp.com/tutorial/python-dependency-injection" class="broken_link">DataCamp｜Python Dependency Injection Tutorial</a></li>



<li><a rel="noopener" target="_blank" href="https://arjancodes.com/blog/python-dependency-injection-best-practices/">ArjanCodes｜Python Dependency Injection Best Practices</a></li>



<li><a rel="noopener" target="_blank" href="https://python-dependency-injector.ets-labs.org/introduction/di_in_python.html">dependency-injector公式ドキュメント｜Dependency Injection in Python</a></li>



<li><a rel="noopener" target="_blank" href="https://zenn.dev/shimakaze_soft/scraps/793a015c66343d">Zenn｜Pythonにおける依存性注入メモ</a></li>



<li><a rel="noopener" target="_blank" href="https://dev.classmethod.jp/articles/python-injector-launch01/">Classmethod Developers Blog｜Python injector入門</a></li>



<li><a rel="noopener" target="_blank" href="https://pytest-with-eric.com/introduction/python-unit-testing-best-practices/">Pytest with Eric｜Python Unit Testing Best Practices</a></li>



<li><a rel="noopener" target="_blank" href="https://stackoverflow.com/questions/33349025/how-to-do-basic-dependency-injection-in-python-for-mocking-testing-purposes">Stack Overflow｜How to do basic Dependency Injection in Python for testing</a></li>



<li><a rel="noopener" target="_blank" href="https://python-dependency-injector.ets-labs.org/">dependency-injector｜公式サイト</a></li>



<li><a rel="noopener" target="_blank" href="https://qiita.com/mkgask/items/d984f7f4d94cc39d8e3c">Qiita｜Pythonの依存性注入パターンまとめ</a></li>



<li><a rel="noopener" target="_blank" href="https://note.com/shirotabistudy/n/ncb2dd6814698">note｜Python依存性注入（DI）を初心者向けに整理</a></li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc39">よくある質問（Q&amp;A）</span></h2>



<div class="wp-block-cocoon-blocks-faq faq-wrap blank-box block-box not-nested-style cocoon-block-faq"><dl class="faq"><dt class="faq-question faq-item"><div class="faq-question-label faq-item-label">Q</div><div class="faq-question-content faq-item-content">小規模なPythonスクリプトでもDIは使うべきですか？</div></dt><dd class="faq-answer faq-item"><div class="faq-answer-label faq-item-label">A</div><div class="faq-answer-content faq-item-content">
<p>無理に使う必要はありません。 ファイル1〜2本で完結するスクリプトなら、 直接依存させた方が読みやすいことも多いです。</p>



<p>ただし、「あとから機能追加するかも」「テストを書く予定がある」なら、 DIを意識しておくと将来が楽になります。</p>
</div></dd></dl></div>



<div class="wp-block-cocoon-blocks-faq faq-wrap blank-box block-box not-nested-style cocoon-block-faq"><dl class="faq"><dt class="faq-question faq-item"><div class="faq-question-label faq-item-label">Q</div><div class="faq-question-content faq-item-content">abcを使わずにDIっぽく書いても問題ありませんか？</div></dt><dd class="faq-answer faq-item"><div class="faq-answer-label faq-item-label">A</div><div class="faq-answer-content faq-item-content">
<p>問題ありません。 Pythonでは、</p>



<ul class="wp-block-list">
<li>ダックタイピング</li>



<li>typing.Protocol</li>
</ul>



<p>なども立派な選択肢です。</p>



<p>大事なのは<strong>抽象に依存する意識</strong>であって、 必ずabcを使うことではありません。</p>
</div></dd></dl></div>



<div class="wp-block-cocoon-blocks-faq faq-wrap blank-box block-box not-nested-style cocoon-block-faq"><dl class="faq"><dt class="faq-question faq-item"><div class="faq-question-label faq-item-label">Q</div><div class="faq-question-content faq-item-content">FastAPIのDepends()はDIフレームワークと同じものですか？</div></dt><dd class="faq-answer faq-item"><div class="faq-answer-label faq-item-label">A</div><div class="faq-answer-content faq-item-content">
<p>役割は似ていますが、スコープは少し違います。</p>



<p>FastAPIのDepends()は、</p>



<ul class="wp-block-list">
<li>リクエスト単位の依存解決</li>



<li>Webアプリ向けに最適化</li>
</ul>



<p>されています。</p>



<p>一方、DIフレームワークはアプリ全体の依存関係を管理します。 FastAPIを使っている場合は、まずDepends()から慣れていくのがおすすめです。</p>
</div></dd></dl></div>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://python.cbagames.jp/2025/12/24/python-di-dependency-injection/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
