Skip to content

投稿

依存性注入は私をより良いPythonプログラマーにしてくれるか?

2025年2月16日 • 6分で読める

依存性注入は私をより良いPythonプログラマーにしてくれるか?

依存性注入は静的言語の主流ですが、Pythonで使用することに意味があるでしょうか?それは私をより良いPythonプログラマーにしてくれるでしょうか?

そして、待って、依存性注入とは何でしたっけ?

まず、質問に答えましょう:依存性注入(DI)とは何でしょうか?

依存性注入は、使用されると、オブジェクトの構築をクラスの外部に移動するパターンです。代わりに、クラスは抽象化に依存します。

C#やJavaなどの静的言語では、結合度を下げ、テストを容易にするために依存性注入が頻繁に使用されます。実際、依存関係とそれらの相互関係を維持することを唯一の目的とする依存性注入フレームワークを見つけることができます。

依存性注入は主に2つの目的を果たします:

第一に、抽象化に依存することで複雑さを軽減します。

第二に、抽象化に依存することで、テスト用のモックを含む異なる実装をクラスや関数に渡すことができます。

コードで実演してみましょう:

# Before 
class User:
    def __init__(self):
        self.database = SqlServerDatabase()

    def get_details(self, user_id: int):
        self.database.get_user_details(user_id)

# After  
class User:
    def __init__(self, database: Database):
        self.database = database

    def get_details(self, user_id: int):
        self.database.get_user_details(user_id)

これが最もシンプルな形の依存性注入です。概念は単純ですが、その力は柔軟な設計を可能にすることにあります。

Beforeの例では、UserクラスはSqlServerDatabaseクラスと密結合しています。Userクラスをテストしたい場合、新しいSqlServerDatabaseインスタンスを作成する必要があります。

Afterの例では、UserクラスはDatabase抽象化と疎結合しています。UserクラスにDatabase抽象化の異なる実装を渡すことができます。

異なるデータベース実装を切り替える方法を示す実用的な例で、この柔軟性を実演してみましょう:

date_string = "2023-10-01"  # Example date string
date_format = "%Y-%m-%d"    # Input string format
birthday = datetime.strptime(date_string, date_format) 
turn_of_the_century = datetime.strptime('2000-01-01', date_format)

database = PostgresDatabase("")

if birthday < turn_of_the_century:
    database = SqlServerDatabase("")

user = User(database=database)
user.get_details(user_id=1)

6行目(birthday < turn_of_the_century)で、依存性注入により異なる条件に基づいて実装を簡単に交換できます。この柔軟性は本番コードにとって価値がありますが、依存性注入の最も一般的な用途の一つ、特に静的言語では、テストです。

例を示します:

class UserTests(unittest.TestCase):
    def test_is_authenticated(self):
        database = MockDatabase('connection_string')
        
        is_authenticated = User(database).is_authenticated('user', 'pass')

        self.assertTrue(is_authenticated)

これはMockDatabaseクラスを使用したシンプルな例です。Pythonでは、同じ結果を得るために組み込みのMockクラスも使用できます。

興味深いことに、私が携わったPythonプロジェクトでは依存性注入は広く使用されていませんでした。静的言語のバックグラウンドから来た私には驚きでした—そして直感に反するように思えました。

しかし、この限定的な採用には理由があります。Pythonの組み込みパッチ機能は既に優れたテスト機能を提供しており、依存性注入の主な利点の一つを排除しています。依存性注入は依然として複雑さを軽減するのに役立ちますが、Pythonには同じ目標を達成する他のアプローチがあります。

Pythonで依存性注入を使用すべきではないと言っているわけではありません。むしろその逆で、すべてのツールやパターンと同様に、それらを使用する場所と時があります。そして依存性注入は、コードの品質を向上させるツールベルトの中のもう一つのツールです。

依存性注入は一般的にほとんどのPythonプロジェクトでコード品質を向上させると思います。

依存性注入をさらに探求することに興味がある場合は、2つの人気のあるPythonフレームワークをチェックすることをお勧めします:

  • Injector (github.com/python-injector/injector)
  • Dependency Injector (python-dependency-injector.ets-labs.org)

著者:Chuck Conwayはソフトウェアエンジニアリングと生成AIを専門としています。ソーシャルメディアで彼とつながりましょう:X (@chuckconway) または YouTube をご覧ください。

↑ トップに戻る

こちらもおすすめ