Inject est recommandé pour DDD en Python

Aperçu

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).

Exemple d'utilisation

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

Inject est recommandé pour DDD en Python
Techniques de tri en Python
À propos de "for _ in range ():" de python
Rechercher les fuites de mémoire dans Python
Rechercher des commandes externes avec python
Différence entre == et est en python
Utilisez le tissu tel quel en python (fabric3)
Python est UnicodeEncodeError dans le menu fixe CodeBox
Python pour la déclaration ~ Qu'est-ce qui est itérable ~
Image de conteneur recommandée pour les applications Python
Il n'y a pas de commutateur en python
À quoi sert le trait de soulignement Python (_)?
Exécutez unittest en Python (pour les débutants)
Python in est aussi un opérateur
Note de nfc.ContactlessFrontend () de nfcpy de python
Conseils pour gérer les binaires en Python
Pourquoi Python est choisi pour l'apprentissage automatique
Résumé de diverses instructions for en Python
Tapez les annotations pour Python2 dans les fichiers stub!
Modèle pour l'écriture de scripts batch en python
Qu'est-ce que "mahjong" dans la bibliothèque Python? ??
Hash en Perl est un dictionnaire en Python
Traiter plusieurs listes avec for en Python
MongoDB avec Python pour la première fois
Obtenez un jeton pour conoha avec python
Exemple de gestion des fichiers eml en Python
Fiche de triche AtCoder en python (pour moi-même)
J'ai cherché un nombre premier avec python
Remarques sur l'utilisation de python (pydev) avec eclipse
Conseils pour créer de petits outils avec python
Utilisez pathlib dans Maya (Python2.7) en préparation du prochain Python3.7
Comment utiliser is et == en Python
[Exemple d'amélioration de Python] Quel est le site d'apprentissage recommandé pour les débutants en Python?
30/10/2016 else pour Python3> pour:
Modèle pour créer des applications de ligne de commande en Python
Quadtree en Python --2
Python en optimisation
python [pour moi]
CURL en Python
CERTIFICATE_VERIFY_FAILED dans Python 3.6, le programme d'installation officiel de macOS
Métaprogrammation avec Python
++ et-ne peuvent pas être utilisés pour incrémenter / décrémenter en python
Python 3.3 avec Anaconda
Géocodage en python
SendKeys en Python
Python est facile
Python Pandas ne convient pas au traitement par lots
Méta-analyse en Python
Unittest en Python
Conseils pour ceux qui ne savent pas comment utiliser is et == en Python
Qu'est-ce que wheezy dans l'image Docker Python?
Wagtail est le meilleur CMS pour Python! (Peut-être)
Époque en Python
Discord en Python
Ajouter un devis ">" pour répondre aux e-mails en Python3
Allemand en Python
DCI en Python