Pregunta

Tengo una clase de 'Orden de compra'. Contiene información sobre una sola orden de compra. Tengo una clase DAO para métodos de base de datos.

¿Dónde debe residir la responsabilidad de los métodos que cargarán y actualizarán la orden de compra?

Si la clase PurchaseOrder tiene métodos '.update', 'insert', 'delete' y '.load' que usan la clase DAO directamente, o si la clase PurchaseOrder ignora los métodos DAO y tiene una clase POController que gestiona estas interacciones?

El usuario solo trabajará en una única orden de compra a la vez.

¡Gracias!

¿Fue útil?

Solución

La orden de compra debe ignorar los detalles de su persistencia. Este es el punto de tener algún tipo de capa de acceso a datos, maneja la administración del objeto y el objeto en sí puede concentrarse solo en ser una orden de compra.

Esto también hace que el sistema sea más fácil de probar, ya que puede crear pedidos de compra simulados y probar la lógica de cómo el sistema los maneja sin enredarse en problemas de persistencia.

Otros consejos

Lo mantendría simple al hacer de PurchaseOrder una interfaz y poner todo el código DAO en la implementación, luego usar una fábrica.

Depende de cuánto tiempo creas que tu aplicación seguirá existiendo. La aplicación de corte de metal de mi empresa se ha desarrollado continuamente desde 1985 y se ha desarrollado a través de múltiples cambios en las arquitecturas de computadoras. En nuestro caso, casi siempre escondemos cosas detrás de una interfaz (o clase de controlador usando sus términos) porque no vamos a ser el estado de las cosas 5, 10, 15 años después.

Al usar una clase de controlador, podemos cambiar las API subyacentes sin alterar los niveles de lógica de negocios y los ajustes de IU anteriores. Estos niveles representan años de trabajo, por lo que es importante preservar su comportamiento.

Recuerde que la mayor parte de la vida útil de su proyecto estará en mantenimiento. Cualquier cosa que haga ahora para que sea más fácil cambiar el diseño más adelante, tendrá un enorme ahorro de tiempo en el camino.

La clase PurchaseOrder debe ignorar el DAO. La clase purchaseOrder debe representar los datos en sí y nada más. Use un controlador o administrador de servicios o lo que quiera para llamarlo para persistir / cargar registros de PurchaseOrder usando el DAO. Esto le da la mayor flexibilidad en su diseño. Tiene un lugar para su modelo de datos, un lugar para su lógica de negocios (el controlador) sobre cómo se almacenan / recuperan los pedidos de compra y un lugar donde realmente persiste.

Déjame guiarte a través de mi razonamiento:

Métodos de clase
Principio básico: La persistencia es un comportamiento de clase y debe ser un método de clase
Necesita una separación de preocupaciones, por lo que coloca la base de datos en una clase DAO y la utiliza de la clase para implementar los métodos. Primer problema: si necesita admitir diferentes conjuntos de DAO, debe crearlos a través de una fábrica. Segundo problema: no todos los comportamientos de persistencia están específicamente relacionados con una instancia de la clase. Por ejemplo, los métodos de lista y búsqueda: devuelven listas de clases, no clases, y no dependen de una instancia. Por lo tanto, son fundamentalmente métodos estáticos .
Tercer problema: quieres apoyar la herencia en esta clase. Como tal, los detalles de persistencia difieren de padre a hijo. Si tienes métodos estáticos, será un problema.

Así que te mueves a la

Controlador
Principio básico: Los métodos de persistencia no pertenecen a una sola clase, son más grandes y, por lo tanto, deberían estar separados
La separación de preocupaciones es necesaria nuevamente, por lo que necesita DAOs. Esta es una clase de utilidad, por lo que todos los métodos son básicamente static .
Primer problema: necesita un Factory para crear los DAO si desea admitir más de un método de persistencia.
Segundo problema: desea admitir una jerarquía de clases para que no pueda usar una clase estática. Es necesario generar los controladores a través de una fábrica.
Tercer problema: está ofreciendo una API demasiado complicada a sus desarrolladores.
Ejemplo de código de cliente:

PurchaseOrder po;
PurchaseOrderController poc;
poc = PurchaseOrderControllerFactory.Instance.Create();
po = poc.GetPurchaseOrder(42);
// do stuff
poc.SavePurchaseOrder(po);

entonces empezaría desde cero.

Comenzar desde comportamientos
Principio básico: La persistencia no es un comportamiento. Los comportamientos son más grandes que la persistencia.
En su sistema habrá un subsistema de Orden de Compra. Su usuario podrá interactuar con él solo en un nivel alto (nivel de caso de uso). Por lo tanto, los métodos implementarán casos de uso de órdenes de compra. Estos métodos utilizarán los DAO, a través de una fábrica si es necesario, para acceder a la base de datos y hacer lo que sea necesario.
En resumen, su PurchaseOrder es básicamente un DTO, una forma rápida de pasar datos. No debe tener comportamientos.
Ejemplo de código de cliente:

// It could be a factory if needed.
PurchaseOrderSystem pos = new PurchaseOrderSystem(); 

List<PurchaseOrder> transacted;
transacted = pos.TransactPurchaseOrders(john, 23);

// Show transacted purchase orders or whatever...

Definitivamente separaría la " lógica de negocios " (PurchaseOrder) desde la base de datos de interacción / acceso. Si se muda a un proveedor diferente, etc., le resultará más fácil realizar cambios en el acceso sin interferir potencialmente con la implementación empresarial, y le resultará más fácil evitar agregar comportamiento a la capa de acceso a la base de datos.

Personalmente, crearía un objeto que gestione las interacciones. No puedo defender firmemente el hecho de NO poner esta lógica en la clase PurchaseOrder en sí misma, pero crear este objeto controlador conduciría a objetos acoplados más libremente.

La cosa clave en que pensar aquí es lo que podrías querer hacer en el futuro. ¿Quizás quieres reemplazar tu base de datos con otra? Es por eso que definitivamente debe separar su código para la interacción con la base de datos de la clase que representa el pedido. Esa es una separación básica de responsabilidad, y espero que ya lo hayas hecho.

Ahora la pregunta es: ¿desea que una tercera clase (controlador) administre la interacción entre las clases de PO y DAO? Creo que eso depende de qué tan general pueda hacer la interfaz a la clase DAO. Si la interfaz DAO es lo suficientemente general como para que pueda escribir un reemplazo de complemento usando un mecanismo de almacenamiento diferente, pero sin cambiar la interfaz, dejaría que la clase PO interactúe con ella. Si no, entonces escribiría una clase de controlador.

La otra cosa en que pensar es el resto de la estructura. ¿Desde dónde se inicia el guardar / cargar? Si va a hacer muchas manipulaciones de la orden de compra (guardar, cargar, imprimir, enviar al cliente), entonces probablemente tenga sentido tener un controlador que haga todas esas cosas en lugar de integrar la funcionalidad en la clase de orden de compra. . Le brinda la ventaja de que puede agregar operaciones de PO sin tener que modificar la clase de PO.

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