Es ist ein kleiner alter Artikel, aber InfoQs Domain Driven Design and Development Practice sagt:
Die Entwurfsabhängigkeit, dass die Domänenklasse von der DAO-Klasse (Data Access Object) und die Serviceklasse von der Domänenklasse abhängt, muss für die Implementierung durch DDD "DI" sein. "Ich mache Dinge.
Für Python ist Inject nützlich, um DI (Dependency Injection) zu erreichen.
Wenn Sie ein Beispiel mit ungefähr 100 Zeilen schreiben, sieht es so aus.
# -*- 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
Um dasselbe zu erreichen, ohne "injizieren" zu verwenden, müssen Sie "repo" als Argument von "UserService" übergeben, wodurch der Konstruktor von "UserService" mit zunehmender Anzahl von Abhängigkeiten aufgebläht wird. Sie können klar schreiben, indem Sie "injizieren" verwenden. Sie können auch den Dekorator @ injizieren.params
verwenden, um Abhängigkeiten in die Standardargumente des Konstruktors einzufügen.
Es ist eine kleine Bibliothek mit nur 300 Zeilen, aber es ist sehr praktisch.
Recommended Posts