2012-06-18 18 views
5

Duplicar posibles:
What are the benefits of Persistence Ignorance?No entiendo el punto de independencia persistencia

Después de algún tiempo y algunas preguntas tratando de averiguar el marco de la entidad, que he llegado a la conclusión de que simplemente no entiendo cuál es el punto de persistencia de los objetos ignorantes.

Lo mejor que puedo decir, la diferencia práctica entre el uso de objetos de persistencia-conscientes y los persistencia-ignorantes es que uno se acostumbra algo así como

Person p = Person.Load(id); 
p.Active = false; 
p.Save(); 

y el otro se utiliza a lo largo de las líneas de

using (var context = new MyContext()) 
{ 
    Person p = context.Persons.Single(x => x.ID == id); 
    p.Active = false; 
    context.SaveChanges(); 
} 

En el primer caso, puedo devolver p, y llamar al Save() en algún momento posterior. En este último, podría devolver p, pero tendría que ponerlo en un nuevo MyContext() para guardarlo. En el primer caso, suponiendo que Person hereda Load() y Save() de algún objeto base que realmente maneje la lógica de la base de datos, si quisiera cambiar la persistencia, simplemente implicaría cambiar ese objeto base (o incluso solo tener un IPersistent interfaz que múltiples clases base pueden implementar para acceder a múltiples tiendas). En este último, necesitaría cambiar cada instancia de MyContext si la capa de persistencia cambiara, y sería tremendamente complicado hacerlo por partes.

Mi impresión es que la persistencia-la ignorancia es algo bueno. Simplemente no puedo entender por qué. Parece que es mucho más complicado configurarlo, trabajar con él, cambiarlo al por mayor y cambiar poco a poco, sin ninguna ventaja para esa complicación. ¿Me estoy perdiendo algo importante, o todo mi entendimiento de lo que es consciente de la persistencia/ignorante es defectuoso?

+0

Además de la persistencia entidades ignorantes, también debe abstraer su ORM. Un método común de hacerlo es el [Repository pattern] (http://martinfowler.com/eaaCatalog/repository.html). – jrummell

+0

@DavidHall, no creo que sea un duplicado. Al menos, después de leer las respuestas sobre la otra pregunta, todavía no veo por qué un objeto consciente de la persistencia * abstraído * es mejor que uno persistente e ignorante. – Bobson

Respuesta

5

Persistance Ignorance es parte de Seperation of Concerns. Debería preguntarse, ¿por qué la persona debería saber cómo debería cargarse o guardarse? La persona debe lidiar con su propio pequeño dominio.

PI significa que a la persona no le importa si proviene de memoria, SQL, binario plano o cualquier otro medio de Persistencia y le permite en un punto posterior reemplazar su capa de persistencia por otra cosa. Inicialmente, podría desarrollar su aplicación para usar archivos binarios planos con los serializadores básicos para almacenar datos. Más tarde, puede actualizar a SQL por razones de rendimiento, y este cambio solo es necesario en la ubicación cuyo trabajo es manejar la persistencia, la capa/componente asociado. De lo contrario, debe revisar toda la base de códigos para cambiar pequeñas partes aquí y allá relacionadas con la persistencia.

+0

Mira, mi experiencia ha sido exactamente lo opuesto. Un objeto Persona que hereda de un tipo base que sabe acerca de la persistencia es trivial para cambiar a una nueva capa de persistencia, pero un objeto PI Person es muy difícil de alterar. Ciertamente no afirmaré que un objeto Aware sea mejor si cada objeto tiene que tener su propio conocimiento * separado de cómo acceder a sus datos, pero siempre que pueda abstraerlo en un solo lugar, no puedo ver cómo PI es mejor. – Bobson

1

Solo para hablar de su ejemplo, escribiendo Person.Load (id) usted está diciendo - cargue este objeto mirando su identificador - está creando un patrón de fábrica rígido, por el cual solo puede obtener objetos si conoce su ID, más tarde descubrirá que necesita extraer registros en función de algunos criterios de búsqueda, y agregará más métodos de fábrica, mientras que la segunda solución ya le brinda toda la libertad que necesita.

La segunda solución es perfecta para cambiar la lógica de persistencia en el tiempo de ejecución, ya que está desacoplado del modelo de objetos, podría teóricamente decidir motor wich persistencia para utilizar dentro de su código de cliente, sin codificar y tocarse la OM, y es falso decir que necesitaría cambiar cada instancia de MyContext, debe escribir su código de cliente para que reciba el contexto de una clase de fábrica o inyección de dependencia.

A modo de ejemplo, usted puede este pseudocódigo:

var person = onlineDbContext.Persons.Single(x=>x.Guid == myguid); 

offlineDbContext.Persons.Add(person) 
offlineDbContest.SaveOrUpdate(); 
+0

¿Ese pseudocódigo debería estar dentro de dos instrucciones 'using()' separadas, una para cada contexto? Además, ¿cómo puedo tener múltiples contextos que admiten el mismo objeto? – Bobson

+0

No escribí las instrucciones de uso porque no importa, ni siquiera estoy hablando de un ORM específico, acabo de mostrar que si separa los datos por la forma en que se manejan, como en la carta del cartero , obtienes más oportunidades. Cómo crear un cartero diferente es otro tema. – Spartaco

+0

Bastante justo. Sin embargo, todavía no tengo idea de cómo usar 'person' en un contexto diferente. Tener un cartero diferente no ayuda si el nuevo cartero está en una ruta diferente y nunca visita mi lugar. Esta respuesta parece ser exactamente lo que estoy buscando, solo estoy tratando de entenderlo. – Bobson