Inject wird für DDD in Python empfohlen

Überblick

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.

Anwendungsbeispiel

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

Inject wird für DDD in Python empfohlen
Techniken zum Sortieren in Python
Über "für _ in range ():" von Python
Überprüfen Sie Python auf Speicherlecks
Suchen Sie mit Python nach externen Befehlen
Unterschied zwischen == und ist in Python
Verwenden Sie Stoff wie in Python (Stoff3)
Python ist UnicodeEncodeError im CodeBox-Docker
Python für Anweisung ~ Was ist iterierbar ~
Empfohlenes Container-Image für Python-Anwendungen
In Python gibt es keinen Schalter
Wofür ist der Python-Unterstrich (_)?
Führen Sie unittest in Python aus (für Anfänger)
Python in ist auch ein Operator
Anmerkung von nfc.ContactlessFrontend () von nfcpy von Python
Tipps zum Umgang mit Binärdateien in Python
Warum Python für maschinelles Lernen ausgewählt wird
Zusammenfassung verschiedener for-Anweisungen in Python
Geben Sie Anmerkungen für Python2 in Stub-Dateien ein!
Vorlage zum Schreiben von Batch-Skripten in Python
Was ist "Mahjong" in der Python-Bibliothek? ??
Hash in Perl ist ein Wörterbuch in Python
Verarbeiten Sie mehrere Listen mit for in Python
MongoDB mit Python zum ersten Mal
Holen Sie sich ein Zeichen für Conoha mit Python
Beispiel für den Umgang mit EML-Dateien in Python
AtCoder Spickzettel in Python (für mich)
Ich habe mit Python nach einer Primzahl gesucht
Hinweise zur Verwendung von Python (Pydev) mit Eclipse
Tipps zum Erstellen kleiner Werkzeuge mit Python
Verwenden Sie pathlib in Maya (Python2.7), um sich auf das kommende Python3.7 vorzubereiten
Verwendung ist und == in Python
[Beispiel für eine Python-Verbesserung] Was ist die empfohlene Lernseite für Python-Anfänger?
2016-10-30 sonst für Python3> für:
Vorlage zum Erstellen von Befehlszeilenanwendungen in Python
Quadtree in Python --2
Python in der Optimierung
Python [für mich]
CURL in Python
CERTIFICATE_VERIFY_FAILED in Python 3.6, dem offiziellen Installationsprogramm für macOS
Metaprogrammierung mit Python
++ und-können nicht zum Inkrementieren / Dekrementieren in Python verwendet werden
Python 3.3 mit Anaconda
Geokodierung in Python
SendKeys in Python
Python ist einfach
Python Pandas ist nicht für die Stapelverarbeitung geeignet
Metaanalyse in Python
Unittest in Python
Tipps für diejenigen, die verwirrt sind, wie man is und == in Python verwendet
Was ist im Docker Python-Image pfeifend?
Bachstelze ist das beste CMS für Python! (Vielleicht)
Epoche in Python
Zwietracht in Python
Fügen Sie ein Zitat ">" für die Beantwortung von E-Mails in Python3 hinzu
Deutsch in Python
DCI in Python