はじめに
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を取得するようになっています