C'est un article plutôt ancien, mais [Domain Driven Design and Development Practices] d'InfoQ (https://www.infoq.com/jp/articles/ddd-in-practice) déclare:
La dépendance de conception selon laquelle la classe de domaine dépend de la classe DAO (Data Access Object) et la classe de service dépend de la classe de domaine doit «DI» pour l'implémentation par DDD. «Je fais des choses.
Pour Python, Inject est utile pour réaliser DI (Dependency Injection).
Si vous écrivez un échantillon d'environ 100 lignes, il ressemblera à ceci.
# -*- coding: utf-8 -*-
import uuid
from abc import ABCMeta, abstractmethod
import inject
def config(binder):
binder.bind(UserRepository, UserMemoryRepository())
class User(object):
def __init__(self, identity, name):
self.identity = identity
self.name = name
class UserRepository(object):
u""" Base class of User Repository"""
__metaclass__ = ABCMeta
@abstractmethod
def store(self, user):
raise NotImplementedError
@abstractmethod
def find_by_identity(self, identity):
raise NotImplementedError
class UserMemoryRepository(UserRepository):
u""" User Repository on memory"""
def __init__(self):
self._users = {}
def store(self, user):
if not isinstance(user, User):
raise TypeError
self._users[user.identity] = user
def find_by_identity(self, identity):
return self._users[identity]
class UserRedisRepository(UserRepository):
u""" User Repository on Redis """
def store(self, user):
# TODO: write code here
pass
def find_by_identity(self, identity):
# TODO: write code here
pass
class UserService(object):
u""" User Service on Application Layer"""
repo = inject.attr(UserRepository)
def create_user(self, name):
user = User(uuid.uuid4(), name)
self.repo.store(user)
return user
def find_by_identity(self, identity):
return self.repo.find_by_identity(identity)
if __name__ == "__main__":
# Call once on application start
inject.configure(config)
user_service = UserService()
created_user = user_service.create_user('foo')
stored_user = user_service.find_by_identity(created_user.identity)
assert created_user == stored_user
Pour réaliser la même chose sans utiliser ʻinject, vous devez passer
repo comme argument à ʻUserService
, ce qui rend le constructeur de ʻUserService gonflé à mesure que le nombre de dépendances augmente. , ʻInject
peut être utilisé pour écrire clairement. Vous pouvez également utiliser le décorateur @ inject.params
pour injecter des dépendances dans les arguments par défaut du constructeur.
C'est une petite bibliothèque avec seulement 300 lignes, mais c'est très pratique.
Recommended Posts