pattern español data php oop architecture datamapper

php - pattern - data mapper en español



PHP DataMapper con múltiples capas de persistencia (3)

Tuve que resolver un problema similar, pero hace muchos años en la época de PEAR DB. En ese caso particular, hubo una necesidad de replicar los datos en múltiples bases de datos.

No teníamos el problema de las diferentes bases de datos con diferentes asignaciones, por lo que era bastante más simple.

Lo que hicimos fue crear una fachada de la clase DB e invalidar la función getResult (o como se llame). Esta función analizó el SQL y, si fuera leído, lo enviaría a una sola copia de seguridad y, si fuera una escritura, lo enviaría a todos.

Esto realmente funcionó muy bien para un sitio muy utilizado.

Desde ese trasfondo, sugeriría que todas las operaciones de persistencia fuesen completamente fachadas. Una vez que haya hecho eso, los detalles de implementación son menos relevantes y se pueden cambiar en cualquier momento.

Desde esta perspectiva, cualquiera de sus ideas de implementación parece un enfoque razonable. Sin embargo, hay varias cosas en las que querrás pensar.

  • ¿Qué pasa si uno de los backends arroja un error?
  • ¿Cuál es el impacto en el rendimiento de escribir en tres servidores de bases de datos?
  • ¿Pueden las escrituras hacerse de forma asíncrona? De ser así, haga la primera pregunta de nuevo

Existe, potencialmente, otra forma de resolver este problema también. Eso es para usar procedimientos almacenados. Si tiene un servidor de base de datos principal, puede escribir un desencadenador que, en la confirmación (o menos) se conecte a la otra base de datos y sincronice los datos.

Si la actualización de datos no necesita ser inmediata, puede obtener la base de datos primaria para registrar los cambios y tener otra secuencia de comandos que regularmente "alimenta" estos datos en el otro sistema. De nuevo, la cuestión de los errores deberá ser considerada.

Espero que esto ayude.

Estoy escribiendo un sistema en PHP que tiene que escribir en tres capas de persistencia:

  • Un servicio web
  • Dos bases de datos (una mysql una mssql)

La razón de esto son los sistemas heredados y no se pueden cambiar.

Quiero utilizar el patrón DataMapper y estoy tratando de establecer la mejor manera de lograr lo que quiero. Tengo una interfaz como la siguiente:

<?php $service = $factory->getService()->create($entity); ?>

A continuación se muestra un código ideado y reducido para la brevedad:

<?php class Post extends AbstractService { protected $_mapper; public function create(Entity $post) { return $this->_mapper->create($post); } } class AbstractMapper { protected $_persistence; public function create(Entity $entity) { $data = $this->_prepareForPersistence($entity); return $this->_persistence->create($data); } } ?>

Mi pregunta es que debido a que hay tres capas de persistencia, también es probable que haya una necesidad de tres mapeadores para cada una. Me gustaría una interfaz inspirada en un patrón de diseño limpio para que esto funcione.

Veo que tiene tres opciones:

  1. Inyecte tres mapeadores en el Servicio y llame a create en cada
  2. $ _mapper es una matriz / colección e itera a través de ellos llamando a create en cada
  3. $ _mapper es en realidad un objeto contenedor que actúa como un proxy adicional y crea llamadas en cada

Algo me parece erróneo con cada una de estas soluciones y agradecería cualquier retroalimentación / diseño de patrones reconocidos que pudieran encajar con esto.


Creo que la opción n. ° 2 es la mejor en mi opinión. Yo iría con eso. Si tuviera más de 10 mapeadores que la opción 3, tendría sentido cambiar la lógica de creación al mapeador en sí, pero dado que tiene un número razonable de mapeadores, tiene más sentido inyectarlos e iterar sobre ellos. La ampliación de la funcionalidad al agregar otro asignador sería una cuestión de solo agregar 1 línea a su configuración de inyección de dependencia.


Primero, un poco de terminología: lo que usted llama tres capas, son de hecho, tres módulos, no capas. Es decir, tiene tres módulos dentro de la capa de persistencia.

Ahora, la premisa básica de este problema es la siguiente: DEBE tener tres lógicas de persistencia diferentes, correspondientes a tres fuentes de almacenamiento diferentes. Esto es algo que no puedes evitar Por lo tanto, la pregunta es acerca de cómo invocar la operación de escritura en estos módulos (suponiendo que para leer no necesite llamar a los tres, o si lo hace, esa es una pregunta separada).

De las tres opciones que ha enumerado, en mi opinión, la primera es mejor. Porque, ese es el más simple de los tres. Los otros dos, aún necesitarán llamar a tres módulos por separado, con el trabajo adicional de introducir un contenedor o algún tipo de estructura de datos. Todavía no puedes evitar llamar a tres módulos en alguna parte.

Si trabaja con la primera opción, obviamente necesita trabajar con interfaces para proporcionar una abstracción uniforme para el usuario / cliente (en este caso, el servicio).

Mi punto es que: 1. Es una complejidad inherente en su problema, que no puede simplificar aún más. 2. La primera opción es mejor, porque las otras dos hacen que las cosas sean más complejas, no simples.