diff --git a/design_patterns/hexagonal/adapters.py b/design_patterns/hexagonal/adapters.py new file mode 100644 index 0000000..727f8b6 --- /dev/null +++ b/design_patterns/hexagonal/adapters.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- + +""" +Ports module +""" + +# standard +from __future__ import annotations +import sqlite3 + +# first-party +from ports import UserRepository + + +class Sqlite3UserRepository(UserRepository): + """ + Adaptador que se implementa como un repositorio de usuarios + + """ + database_name = None + connection = None + table_name = 'users' + + def __init__(self, database_name): + self.connection = sqlite3.connect(database_name) + + def get_cursor(self): + return self.connection.cursor() + + def all(self): + """Get all users""" + cursor = self.get_cursor() + cursor.execute(f'SELECT * FROM {self.table_name}') + registros = cursor.fetchall() + cursor.close() + return registros + + def create(self, user): + """Create a user""" + cursor = self.get_cursor() + cursor.execute(f'INSERT INTO {self.table_name} (name) VALUES (?)', (user.name,)) + self.connection.commit() + cursor.close() + + def delete(self, user): + """Delete a user""" + cursor = self.get_cursor() + cursor.execute(f'DELETE FROM {self.table_name} WHERE id = ?', (user.id,)) + self.connection.commit() + cursor.close() diff --git a/design_patterns/hexagonal/main.py b/design_patterns/hexagonal/main.py new file mode 100644 index 0000000..e69de29 diff --git a/design_patterns/hexagonal/models.py b/design_patterns/hexagonal/models.py new file mode 100644 index 0000000..fa7d863 --- /dev/null +++ b/design_patterns/hexagonal/models.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- + +""" +docstring +""" + +# standard +from __future__ import annotations +from typing import TYPE_CHECKING +from dataclasses import dataclass + +# framework + +# third-party + +# first-party + +# typing +if TYPE_CHECKING: # pragma: no cover + pass + + +@dataclass +class User: + """Modelo de datos que describe a un usuario""" + id: str = None + name: str = None diff --git a/design_patterns/hexagonal/ports.py b/design_patterns/hexagonal/ports.py new file mode 100644 index 0000000..039758f --- /dev/null +++ b/design_patterns/hexagonal/ports.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- + +""" +Módulo de puertos +""" + +# standard +from __future__ import annotations +from abc import ABCMeta, abstractmethod + + +class UserRepository(metaclass=ABCMeta): + """ + Puerto para repositorios de usuarios. + Un puerto es una interfaz que define un conjunto de operaciones que un adaptador debe implementar. + (Port = Interface) + """ + + @abstractmethod + def all(self): + """Función para obtener todos los usuarios""" + + @abstractmethod + def create(self, user): + """Función para crear un usuario""" + + @abstractmethod + def delete(self, user): + """Función para eliminar un usuario""" diff --git a/design_patterns/hexagonal/services.py b/design_patterns/hexagonal/services.py new file mode 100644 index 0000000..870b0ab --- /dev/null +++ b/design_patterns/hexagonal/services.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- + +""" +Ports module +""" + +# standard +from __future__ import annotations + + +class UserService: + """User service""" + + def __init__(self, repository): + self.repository = repository + + def list(self): + """Get all users""" + return self.repository.all() + + def create(self, user): + """Create a user""" + self.repository.create(user) + + def delete(self, user): + """Delete a user""" + self.repository.delete(user)