En fait, mon projet n'a pas utilisé cette méthode ces derniers temps. C'est une idée vague que le modèle de la couche de domaine et l'implémentation de la couche d'infrastructure ne doivent pas nécessairement être hérités tant qu'ils sont liés par injection et que les méthodes nécessaires sont définies (typage canard).
Aussi, dans mon récent projet, au lieu de mettre la couche infrastructure, j'ai défini les modules de port et d'adaptateur. Pour l'adaptateur, c'est comme écrire une implémentation d'une interface définie au niveau de la couche de domaine ou du port. Le concept dans le modèle de domaine est placé dans la couche de domaine et l'interface de coopération avec le système externe est placée dans le port.
J'écrirai un autre article quand j'aurai le temps.
Lorsque Hexagonal Architecture est appliqué au développement piloté par domaine, l'interface pour les référentiels et les événements de domaine est placée dans la couche de domaine, mais [zope.interface](http: //: // En utilisant docs.zope.org/zope.interface/), vous pouvez écrire un code facile à comprendre qui évite l'héritage multiple.
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 """
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)
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)