[PYTHON] Zope.interface ist nützlich zum Üben der hexagonalen Architektur

Nachtrag: 2017-02-12

Tatsächlich hat mein Projekt diese Methode in letzter Zeit nicht verwendet. Es ist eine lose Idee, dass das Modell der Domänenschicht und die Implementierung der Infrastrukturschicht nicht unbedingt vererbt werden müssen, solange sie durch Inject verbunden sind und die erforderlichen Methoden definiert sind (Ententypisierung).

Außerdem habe ich in meinem letzten Projekt anstelle der Infrastrukturschicht die Module Port und Adapter definiert. Für den Adapter ist es so, als würde man eine Implementierung einer Schnittstelle schreiben, die auf der Domänenebene oder dem Port definiert ist. Das Konzept im Domänenmodell wird in der Domänenschicht platziert, und die Kooperationsschnittstelle mit dem externen System wird im Port platziert.

Ich werde einen weiteren Artikel schreiben, wenn ich Zeit habe.

Überblick

Wenn Hexagonal Architecture auf die domänengesteuerte Entwicklung angewendet wird, wird die Schnittstelle für Repositorys und Domänenereignisse in der Domänenschicht platziert, jedoch [zope.interface](http: //: //) Mithilfe von docs.zope.org/zope.interface/) können Sie leicht verständlichen Code schreiben, der Mehrfachvererbung vermeidet.

Domänenschicht

from abc import ABCMeta
from zope.interface import Interface


class Entity(object):
    """ Base class for Entity """
    __metaclass__ = ABCMeta


class IRepository(Interface):
    """ Interafce for Repository """


class IDomainService(Interface):
    """ Interface for Domain Service """


class Blog(Entity):
    def __init__(self, identity, title):
        self._identity = identity
        self._title = title


class IBlogRepository(IRepository):
    """ Blog repository Interface """

    def add_entity(blog):
        """ add blog """

    def get_by(identity):
        """ get blog by identity """


class IBlogProvisioningService(IDomainService):
    """ Blog provisioning service interface """

    def provision_blog(title):
        """ provision blog with title. returns Blog object """

Infrastrukturschicht

import uuid
from abc import ABCMeta
from zope.interface import implementer
from domain import Blog, IBlogRepository, IBlogProvisioningService


class MySQLRepository(object):
    """ MySQL based repository """
    __metaclass__ = ABCMeta


class MemoryRepository(object):
    """ memory based repository """
    __metaclass__ = ABCMeta


@implementer(IBlogRepository)
class BlogRepository(MySQLRepository):

    def add_entity(self, blog):
        # do some stuff
        pass

    def get_by(self, identity):
        # do some stuff
        return Blog(identity, "some stored title")


@implementer(IBlogRepository)
class BlogMemoryRepository(MemoryRepository):

    def add_entity(self, blog):
        # do some stuff
        pass

    def get_by(self, identity):
        # do some stuff
        return Blog(identity, "some stored title")


@implementer(IBlogProvisioningService)
class BlogProvisioningService(object):

    def __init__(self, repo):
        self._repo = repo

    def provision_blog(self, title):
        entity = Blog(uuid.uuid4().hex, title)
        self._repo.add_entity(entity)

Prüfung

import pytest
from zope.interface.verify import verifyClass
from domain import Blog, IBlogRepository, IBlogProvisioningService
from infra import BlogRepository, BlogMemoryRepository, BlogProvisioningService


def test_class_interface():
    assert verifyClass(IBlogRepository, BlogRepository)
    assert verifyClass(IBlogRepository, BlogMemoryRepository)
    assert verifyClass(IBlogProvisioningService, BlogProvisioningService)

Domaingesteuerte Entwicklungsserie

Recommended Posts

Zope.interface ist nützlich zum Üben der hexagonalen Architektur
Python-Dotfiles ist praktisch für die Verwaltung von Dotfiles
Watchdog ist sehr nützlich für die Dateiüberwachung
Eine Szene, in der GPU für tiefes Lernen nützlich ist?
Wofür ist Linux?