Pregunta

Soy bastante nuevo en el uso de capas separadas para la lógica de negocio (Dominio) y acceso a base de datos lógica, pero en el curso del trabajo las cosas me he encontrado con un problema que creo que todavía no he encontrado una gran solución.

Aclaración Mi solución existente utiliza los Datos Mapeados para lidiar con la base de datos de interacciones directamente.Sin embargo, como he investigado esta cuestión muchas personas han sugerido que la capa de Dominio no deben comunicarse directamente con ni contienen los Datos Mapeados que realmente realizan la interacción de base de datos.Esta es la razón por la que me colocó el Repositorio de objetos entre el Dominio y los Datos necesarios a los miembros de la comunidad, pero esto no se siente muy natural o correcta.Así que la pregunta real es ¿qué capa naturalmente existe para controlar la comunicación entre el Dominio y los Datos de los miembros de la comunidad?Cualquiera de los ejemplos de cómo la estructura sería muy de agradecer.

Por ejemplo:

  • ¿Cómo puedo manejar adecuadamente la recuperación de una colección de objetos de dominio en el contexto de otro objeto de dominio?
  • ¿Cómo puedo forzar la inserción de un único dominio objeto o colección de objetos basados en una acción realizada en contra de otro objeto.El caso que estoy enfrentando en la actualidad es que cuando una Persona se une a una Campaña, entonces tengo que insertar todos los Eventos que deben ser ejecutados para esa Persona para esa Campaña.
¿Fue útil?

Solución

Gabriel, este es el llamado "igualación de impedancia problema." Hay muchas soluciones, de peso pesado como J2EE beans de entidad a Ruby ActiveRecord simplemente la codificación de un lado de la conexión.

Actualización

Bien, bien, su disco duro para ver exactamente cómo atacar este sin mucha más información, pero aquí está el enfoque básico.

Cualquiera de estos tipos de problemas arquitectónicos son impulsados por los requisitos no funcionales como el rendimiento;además, hay una corrección de la cuestión aquí, en que usted quiere asegurarse de que las actualizaciones se realizan en el orden correcto.Así, vas a tener que pensar acerca de la la carga de trabajo, es decir, el patrón de uso y aplicación en el mundo real.Con eso en mente, que, básicamente, tiene un par de problemas:en primer lugar, los tipos de base de datos en su aplicación no se asignan correctamente a la base de datos (por ejemplo, ¿qué es un VARCHAR propiedad representada como en el código?), y segundo, el modelo de dominio no puede asignar correctamente a su modelo de base de datos.

Lo que te gustaría es tener la base de datos y la dmain modelo de trabajo para que una instancia de un objeto de dominio es exactamente una fila de una tabla en el modelo de base de datos;en aplicaciones a gran escala que rara vez se puede hacer esto ya sea por el rendimiento de las restricciones o limitaciones impuestas por un pre-existente modelo de base de datos.

Ahora, si usted controlar completamente su modelo de base de datos, simplifica las cosas un poco, porque entonces usted puede hacer que su modelo de base de datos se asemejan más a los de dominio.Esto podría significar que el modelo de base de datos es algo sin normalizar, pero si es así, usted puede (dependiendo de su base de datos) que el mango con vistas, o simplemente no tener una base de datos normalizado.La normalización es una útil teórica, pero eso no significa que usted no puede descansar en un sistema real.

Si no controlar completamente su modelo de base de datos, entonces usted necesita una capa de objetos que hacen que la asignación.Tienes un montón de opciones para elegir en la aplicación que:puede crear vistas o sin normalizar las tablas en la base de datos, puede crear objetos intermedios, o se puede hacer alguna de las dos, o incluso tener varios pasos de ambos (es decir, un objeto intermedio que tiene acceso a un denormalizaed tabla.)

En ese momento, sin embargo, se encuentra con problemas con "don't repeat yourself" y "hacer la cosa más simple que posiblemente va a trabajar". Piense acerca de lo que es más probable que el cambio?El modelo de dominio?Si tienes un fuerte modelo de dominio, el que tiene menos probabilidades --- los cambios de negocio relativamente rara.La representación exacta de los datos en la base de datos?Un poco más común.O, más comúnmente, la determinación precisa de los patrones de uso (como el descubrimiento de una necesidad de manejar actualizaciones simultáneas.) Así que, cuando usted piensa acerca de eso, ¿qué se necesita hacer para hacer tan fácil como sea posible para lidiar con los cambios más comunes.

Me doy cuenta de que esto no es dándole instrucciones precisas, pero no creo que nos puede ofrecer instrucciones precisas sin saber mucho acerca de su aplicación.Pero entonces yo también como que da la impresión de que usted se está preguntando acerca de lo que la forma "correcta" de la manipulación de este, mientras que usted está trabajando con algo que más o menos hace el trabajo.Así, terminaba con la pregunta: "¿qué estás satisfecho con ahora?" y "¿Cómo te gustaría resolver?"

Otros consejos

Hay una distinción entre un modelo de dominio y la aplicación de la misma.Sólo porque su modelo muestra una relación Person ---> Campaign ---> Event no significa que usted tiene que implementar de esta manera.IOW, el modelo muestra su análisis y diseño orientado a objetos, pero de implementar que en el modelo de programación orientada a objetos que es limitada en lo bien que se puede replicar ese modelo en el código.

Considere el siguiente.

Un Person no está definido por su propiedad de una Campaign, por lo que la campaña puede ser dejado fuera de su conocimiento responsibities.Por otro lado, un Campaign se define por la Events que se producen como parte de su ejecución, por lo que es justo tener una colección de eventos dentro de una campaña.El punto que estoy haciendo es que cada clase debe tener sólo lo suficiente el comportamiento y el conocimiento para hacerlo todo.

Como para la comunicación entre el dominio y la persistencia de las capas, los consideran como dos sistemas distintos que no tienen que ver con la otra.Todos cada uno de ellos sabe que es lo que sus responsabilidades son y qué anuncios se hace.Por ejemplo, la capa de persistencia sabe cómo conservar los datos pasa a ella y a anunciar que los datos han sido guardados.Sin embargo, la capa de persistencia no necesariamente tienen que entender los objetos de dominio.Del mismo modo, la capa de dominio entiende Person, Campaign, y Event pero no sabe nada acerca de la persistencia.

La implicación de lo anterior es que la capa de dominio debe ser un todo por sí mismo y no debe ser dependiente de la capa de persistencia de datos.Sin embargo, todavía necesita ser suministrado con los datos para realizar sus responsabilidades.Los datos pueden venir de cualquiera de la interfaz de usuario o la base de datos y se pasa a través de un tercero que conoce tanto el dominio y la persistencia de las capas.

Así, en el código (pseudo-C#)...

namespace DomainLayer
{
    interface IDomainListener 
    {
        void PersonCreated(Person person);
    }

    class Person
    {
        private string name;

        public Person(string name)
        {
            this.name = name;
        }

        public string Name
        {
            get { return name; }
        }
    }

    class Domain 
    {
        private IDomainListener listener;

        public Domain(IDomainListener listener) {
            this.listener = listener;
        }

        public void CreatePerson(string name) {
            Person person = new Person(name);
            listener.PersonCreated(person);
        }
    }
}


namespace PersistenceLayer
{
    interface IPersistenceListener
    {
        void PersonDataSaved(int id, object data);
    }

    class Persistence
    {
        private IPersistenceListener listener;

        public Persistence(IPersistenceListener listener) 
        {
            this.listener = listener;
        }

        public void SaveData(object data)
        {
            int id = ...; // save data and return identifier
            listener.DataSaved(id, data);
        }
    }
}

namespace MyApplication
{
    class MyController : IDomainListener, IPersistenceListener
    {
        public void CreatePersonButton_Clicked()
        {
            Domain domain = new Domain(this);
            domain.CreatePerson(NameTextbox.Text);
        }

        public void PersonCreated(Person person)
        {
            Persistence persistence = new Persistence(this);
            persistence.SavePersonData(person.Name);
        }

        public void DataSaved(int id, object data)
        {
            // display data on UI
        }
    }   
}

Como se puede ver, los espacios de nombres que representan los diferentes niveles.El XYZListener las interfaces definen los anuncios realizados por el XYZ nivel.Cualquier otros niveles a los que están interesados en estos anuncios y responder ante ellos necesitan para implementar estas interfaces, como lo hace nuestro MyApplication nivel.

Cuando el "crear botón" haga clic en el controlador crea el Domain fachada objeto de la capa de dominio y registra a sí mismo como un agente de escucha.A continuación, llama a la CreatePerson método que crea un Person luego anuncia que haya hecho esto, pasar a la nueva instancia.El controlador responde a este anuncio en el PersonCreated aplicación donde se genera una fachada de la capa de persistencia y registra a sí mismo como el agente de escucha de nuevo.A continuación, llama a la SaveData método whichannounces DataSaved cuando se haya completado.La implementación de ese método, a continuación, muestra los datos en la interfaz de usuario.

Como se puede ver, el dominio de la capa y la capa de persistencia son cada conscientes de que sólo tmemselves y no tienen que ver con las responsabilidades de los otros.Es la lógica de la aplicación, que se manifiesta aquí como el controlador, que los cables de los dos juntos.

De regreso a su problema específico, podría haber un método FindPerson en la persistencia, que iba a anunciar PersonFound(int id).La respuesta del controlador sería la llamada a la capa de persistencia para recuperar los datos sobre la campaña y eventos, a continuación, llamar a la capa de dominio con los datos para construir el Person.

Lo siento por la respuesta larga...

Muchos sistemas emplean una capa de datos independiente para manejar la persistencia hacia y desde una base de datos. Hay varios modelos para la organización de una capa de este tipo. Algunos utilizan una especie de aplicación de fábrica como, otros emplean una correspondencia uno-a-uno con una capa de datos de clase por clase de dominio.

El modelo para la capa de datos depende a menudo de estilo y preferencias. Lo que es importante es la separación de la capa de persistencia de la capa de dominio. Creo que hay herramientas por ahí que le ayudarán a generar esta capa, pero mis conocimientos de PHP es delgada, así que no puedo nombrar a ninguno en concreto para PHP.

Me gustaría ver las capas de abstracción de datos utilizados por PHPCake y Symfony.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top