¿Mantener un modelo MVC ligeramente acoplado desde el DB?

9

Me gusta mantener mi código comprobable y he decidido seguir con la estrategia de Inyección de Dependencia para mi marco MVC actual, que definitivamente ha demostrado ser una excelente manera de garantizar un código, una capacidad de prueba y una modularidad poco ajustados.

Pero como estoy lejos de ser un maestro en los patrones de diseño, me resulta difícil encontrar una buena manera de mantener mis modelos lo menos acoplados posible de las clases de conector de base de datos.

¿Cómo se puede hacer esto?
Como no he proporcionado ningún código físico junto con esta pregunta, realmente agradecería algunos ejemplos de lógica / código o información que podrían indicarme una dirección para comprender el problema descrito anteriormente.

Industrial
fuente
Esta pregunta pertenece a la Ingeniería de Software , ya que se trata más de la estructuración y el pensamiento en torno a este tema, más que de implementarlo en el código.
Lasse V. Karlsen

Respuestas:

6

Una forma es diseñar sus modelos antes de diseñar su base de datos. Al diseñar sus modelos, la atención se centra en capturar la lógica empresarial y los significados dentro del dominio del problema. Esto debe ser capturado de una manera que tenga sentido para el negocio, incluyendo más que solo entidades y campos de datos. Algunos elementos de datos se interpretan de otros, algunos dependen de otros, etc. Además, agregaría a este modelo cualquier lógica básica que necesite, como la forma en que un objeto responde internamente cuando un determinado elemento se establece en un determinado valor.

Es muy probable que termines con algo que es 90% más idéntico a cómo terminas persistiendo los datos. Esta bien. Puede ser completamente idéntico sin estar acoplado.

Tenga en cuenta también que modelar el dominio en una niebla de verdadera ignorancia de persistencia es un poco sagrado para el diseño de software. Si puedes hacerlo, fantástico. Pero si el dominio del problema es significativo y tiene alguna complejidad, entonces es una buena idea dar un paso atrás del modelado del dominio de vez en cuando para hacer una verificación de la persistencia de los datos para asegurarse de que no haya pintado en un rincón

Solo recuerde los roles reales de los diversos componentes y mantenga esos roles separados cuando los diseñe. Para cualquier decisión de diseño, pregúntese si se viola alguno de esos roles:

  1. Base de datos: almacene los datos, mantenga la integridad de los datos, mantenga los datos en reposo.
  2. Modelos: contener la lógica empresarial, modelar el dominio del problema, mantener los datos en movimiento, responder a eventos de nivel empresarial, etc.
  3. Vistas: presente los datos a los usuarios, realice la lógica del lado del usuario (validación básica antes de realizar la validación verdadera en los modelos, etc.).
  4. Controladores: responda a los eventos de los usuarios, pase el control a los modelos, enrute las solicitudes y devuelva las respuestas.
David
fuente
Hola David. Gracias por tu extensa respuesta! Mientras mantiene un alto nivel de acoplamientos sueltos, ¿cómo conectaría los modelos con un conector de base de datos?
Industrial
1
@Industrial: hay varias formas de conectar modelos a la persistencia, pero hasta ahora el único método que he encontrado que realmente satisface mi deseo de separar las preocupaciones es tener interfaces de repositorio en el dominio que se implementan externamente por un DAL. Los métodos de repositorio aceptan y devuelven modelos de dominio, y convierten internamente entre esos y cualquier entidad de base de datos generada. (Para ser honesto, no he hecho tanto en PHP). Por lo tanto, puede usar un marco DAL para generar automáticamente todos sus DB CRUD, etc. y luego escribir sus repositorios como una interfaz entre esas cosas y sus modelos.
David
@Industrial: por ejemplo, si usa un ORM, entonces su DAL hará referencia a ese ORM (que está aislado de los modelos de dominio) y transformaría sus modelos en acceso a datos en consecuencia. O si accede directamente a la base de datos con SQL manual, lo haría en los métodos de repositorio de su DAL y traduciría los resultados de las consultas SQL en modelos de dominio antes de devolverlos.
David
@ Industrial: tenga en cuenta también que los métodos de repositorio no tienen que ser simplemente CRUDOS. Se puede incorporar mucha inteligencia en ese código. Muchos de los más complejos pueden tener una gran cantidad de código interno que transforma los datos de la base de datos. O bien, si los complejos implican muchos viajes a la base de datos, para obtener ganancias de rendimiento, puede colocar la lógica en un procedimiento almacenado y el método DAL simplemente pasa a ese procedimiento y traduce los resultados en modelos.
David
¡Hola David! Solo quería agradecerte nuevamente por esta respuesta. ¡Definitivamente uno de los mejores que he recibido en StackExchange!
Industrial
2

Quieres tener dos cosas.

  1. Sus modelos (accesores al DBAL y haciendo la mayor parte de la lógica de la aplicación).
  2. Sus "Modelos de dominio", también conocidos como Entidades de datos, representan las entidades de su sistema, como usuarios, publicaciones, productos, etc.

    class PPI_Model_User {
    
        protected $_conn = null;
    
        function __construct(array $options = array()) {
            if(isset($options['dsnData'])) {
                $this->_conn = new PPI_DataSource_PDO($options['dsnData']);
            }
        }
    
        function getAll() {
            $rows = $this->_connect->query("SELECT .....")->fetchAll();
            $users = array();
            foreach($rows as $row) {
                $users[] = new PPI_Entity_User($row);
            }
            return $users;
        }
    
    }

Código de uso

    $model = new PPI_Model_User(array('dsnData' => $dsnData));
    $users = $model->getAll();
    foreach($users as $user) {
        echo $user->getFirstName();
    }

Ahí lo tienes, así es como creas modelos de dominio (Entidades) y tienes modelos MVC que realizan la conectividad DB y la manipulación de datos.

Si se pregunta qué es PPI, busque "Marco PPI" en Google.

Buena suerte con tu búsqueda.

Saludos, Paul Dragoonis.

Paul Dragoonis
fuente
1

Recuerde, MVC surgió en smalltalk, que tiene persistencia automática para todos los objetos. Por lo tanto, el patrón MVC no prescribe ninguna solución para la separación modelo / persistencia.

Mi preferencia es proporcionar un objeto "Repositorio" que sepa cómo crear objetos Modelo a partir de la base de datos y almacenar objetos Modelo en la base de datos. Entonces el Modelo no sabe nada de persistencia. Sin embargo, alguna acción del usuario tendrá que activar un guardado, por lo que es probable que el Controlador sepa sobre el Repositorio. Usualmente uso alguna forma de Inyección de dependencia para evitar que el Controlador se acople al Repositorio.

Sean McMillan
fuente