Python 3.9 時代の型安全な Pythonの極め方 を読み、抽象クラスを使わずともProtocolを使うことで「必要なメソッドを持っているか」をPythonicな形でうまく表現できることを知った。
一方、PythonでDDDを実践していく中で、ドメイン層にレポジトリのインターフェイスを定義し、そのインターフェイスを実装した具体的なクラスをインフラストラクチャー層に実装するということをしている。その際、ドメイン層ではABC - Abstract Base Classesを使って抽象クラスを作る方法を取っていた。 ABCだとインターフェイスとその実装クラスの間に継承関係が発生するが、Protocolを使えば継承関係を持たせる必要がなくなる。
DDDではinjectorを使いDIをしているが、ABCの時は上手く動いているが、Protocolを使ったときにinjectorがうまく動くか分からなかったので実験してみた。
- Windows 10 version 2004 (OS Build 19041.450)
- Python 3.7.7
- VSCode 1.47.3
- VSCode拡張機能
まずはPowershellを立ち上げ、普通にvenv作ってactivateする
python3 -m venv venv
venv/Scripts/Activate.ps1あとは、依存ライブラリをインストールする。
pip install -r requirements.txt
Procotolを使ったサンプルはsample_protocol.pyに書いた。
ABCを使ったサンプルはsample_abc.pyに書いた。
injectorとProcotolを組み合わせた場合、Protocolで定義したメソッドが実装されていなかったとしても、その未実装メソッドが呼び出されるまではエラーにならない。
対して、injectorとABCを組み合わせた場合、@abstractmethodでアノテーションしたものが実装されていないと、インスタンス化される時点でエラーになる。
エラーの早期発見しやすさだとABCに軍配が上がるが、Protocol側でエラーの早期発見のための手立てはなにかあるのだろうか。