はじめに
Python 学習のアウトプットとして、Python3 + CleanArchitectureのサンプルプログラムをコーディングしました。Injector を使って、DIP(依存関係逆転の原則)を満たすようにしています。というか今の所それだけですmm
- (※) クリーンアーキテクチャ関連の理解に関しては、以下を参考にしています
- クリーンアーキテクチャの右下の図@nrslibさん
- Clean Architecture 達人に学ぶソフトウェアの構造と設計 ...途中まで読みました...
環境&構成
- Python 3.7.4
- sample app (source code)
.
├── main.py
├── interfaces
│ ├── controller.py
│ └── console.py
├── usecase
│ └── restaurant.py
└── domain
└── message.py
処理フロー
クリーンアーキテクチャの図と、シーケンス図の色を合わせています。
-
RestaurantUseCase
は、抽象的なIORepository
に依存する -
RestaurantController
のコンストラクタで、DI定義のから、RestaurantUseCase
の実装を取得する
ポイント
- 抽象クラスの
IORepository
と、それを継承したConsole
のDIのバインド設定を定義する -
RestaurantController
のコンストラクタで、上記の設定でDIされたRestaurantUseCase
を保持する
class DIMoudule(Module):
def configure(self, binder):
binder.bind(repository.IORepository, to=console.Console)
class RestaurantController:
def __init__(self):
self.usecase = Injector([DIMoudule()]).get(
restaurant.RestaurantUseCase)
def run(self):
self.usecase.run()
-
RestaurantUseCase
のコンストラクタで、DIされたIORepository
の実装を保持する
(上記のDIMoudule
の設定だと、Console
がDIされる)
class RestaurantUseCase:
@inject
def __init__(self, c: repository.IORepository):
self.console = c
def run(self):
self.console.start)
終わりに
- 今回の実装だと、
UseCase
の抽象(=UseCaseInputPort
)が存在しない -
Controller
のコンストラクタで、Injector
から、DIバインド済みのUseCase
を取得するようになっています