El mejor patrón de diseño OOP para una secuencia de operaciones

7

Estoy trabajando en una aplicación, un módulo del cual realiza las siguientes operaciones financieras de forma secuencial:

Cuando un usuario solicita que se transfiera una cierta cantidad a su cuenta bancaria:

  1. comprobar si alguna transacción puede suceder ahora? (la transacción solo se puede llevar a cabo durante un período de tiempo determinado)
  2. compruebe si el usuario ha solicitado que se retire una cantidad mínima
  3. compruebe si el usuario tiene alguna cuenta predeterminada

Se debe registrar el resultado de todas las acciones anteriores.

Si todas las condiciones anteriores cumplen, la transacción se lleva a cabo. En el futuro, puede haber algunos controles adicionales.

¿Qué patrón de diseño orientado a objetos debería ser el más adecuado para el caso anterior?

    
pregunta kumar 21.04.2013 - 14:53

5 respuestas

9

Parece que lo que está buscando es una Cadena de responsabilidad . En este caso podría tener las siguientes clases:

  • TransactionValidatorBase clase base abstracta
  • TransactionTimeValidator
  • TransactionAmountValidator
  • TransactionAccountValidator

Se encadenan para aplicar sin importar cuántas reglas especifiques.

Lectura furiosa

respondido por el p.s.w.g 21.04.2013 - 16:50
2

El patrón correcto aquí realmente depende de un contexto. Antes de elegir cualquier patrón en particular para seguir, trataré de encontrar respuestas a esas preguntas:

  • ¿Se requiere crear diferentes combinaciones de (1,2,3) cheques en tiempo de ejecución?
  • ¿Necesitan las mismas variables para realizar sus acciones o son muy diferentes?
  • ¿Qué tan precisos deben ser los mensajes de error?
  • En caso de error, ¿el usuario vuelve a intentarlo desde (1) primer paso siempre?
  • ¿Cómo se maneja la concurrencia?
  • ¿Cada método agrega algo a la solicitud o simplemente valida? (decir ID de cuenta predeterminada)

Basándome en un presentimiento, los codificaría como métodos simples con parámetros de agregación para códigos de error.

public void DoTransaction(IErrorAgregator error, TransactionRequest request)
{
    if(!IsTransactionInCertainTimePeriod(request, error)) return;
    if(!IsTransactionAmountInUserBounds(request, error)) return;
    if(!UserHaveDefaultAccount(request, error)) return;
    bankingTransactor.PerformTransaction(request);
}

Podría ser una buena idea colocar DoTransaction en la interfaz "ITransactionValidationStragegy" y crear un supertipo de capa que contendrá el código de validación de la validación.

Sin embargo, en este diseño, asumo que la lógica de validación se determina en el momento de la compilación.

    
respondido por el Valera Kolupaev 07.10.2013 - 23:07
1

Si su secuencia de pasos realiza la mayoría de las tareas de validación (como parece que lo es), sin mutar las entradas, pienso realmente en el patrón de "Cadena de responsabilidad", como se explica en su respuesta por @pswg

Pero como su pregunta es un poco más genérica, también me gustaría agregar el "Procesamiento de tuberías", ya que con este paso, un paso produciría una salida que se convertiría en la entrada del siguiente paso (por lo tanto, la mutación entrada original).

Aquí hay dos artículos al respecto:
Colección de tuberías de Martin Fowler
Más discusión teórica sobre el patrón

    
respondido por el julio.g 04.12.2017 - 15:50
0

Si bien los patrones ya se mencionaron aquí, le sugeriría que piense cómo le gustaría usar el mismo en su aplicación, en función de los marcos que esté utilizando.

Por ejemplo, la validación que le gustaría hacer, lo más probable es que siga cambiando a medida que avance el tiempo (es posible que desee agregar una nueva validación en el futuro que restrinja las transacciones a 10 por día). Además, es posible que no desee realizar la validación antes de que comience su servicio de negocios o código de integración. Sería bueno si pudiera agregar las validaciones como configurables.

En caso de que estés utilizando Struts, usar interceptores puede ser una buena idea. En el caso de la primavera, la inyección de frijoles como dependencia le da más flexibilidad. Mi sugerencia no es solo observar los patrones / modismos, sino también el marco que usa para crear la aplicación y ver cómo puede adaptarse mejor a sus necesidades desde un punto de vista futurista.

    
respondido por el Arun 07.10.2013 - 13:17
-2

Según mi entendimiento, todo lo que se requiera puede ajustarse en el patrón de comando como se muestra a continuación. El diseño de la clase se puede hacer como se indica a continuación.

interface Transaction{
void performAction();
}

class Banking{

void moneyValidation(){
//Validate Here
}

void timeValidation(){
//validate Here
}
}

class TimeValidation implements Transaction{

public Banking bank;

public TimeValidation (Banking bnk){
bank=bnk;
}

void performAction(){
bnk.timeValidation();
}


class MoneyValidation Implements Transaction{

public Banking bank;

public MoneyValidation(Banking bnk;){
bank=bnk;
}

void performAction(){
bnk.moneyValidation();
}
}


class Control{

private List val_list=new ArrayList();

void storeValidation(Transaction trans){
val_list.add(trans);
trans.performAction(val_list.getFirstAndRemove());
}
}

//Same for other validation classes

Su clase de cliente contendrá el siguiente fragmento de código:

Banking bnk = new Banking();
MoneyValidation m_val = new MoneyValidation (bnk);
TimeValidation t_val = new TimeValidation (bnk);
Control ctrl = new Control();
ctrl.storeValidation(m_val);
ctrl.storeValidation(t_val);

Esto es según mi entendimiento, con el escenario que se ha dado anteriormente.

    
respondido por el alok 07.10.2013 - 12:11

Lea otras preguntas en las etiquetas