20

I am working on an application, a module of which does the following financial operations sequentially:

When a user requests for a certain amount to be transferred into her bank account:

  1. check whether any transaction can happen now? (transaction can be carried out only during a certain time period)
  2. check whether the user has requested for a minimum amount to be withdrawn
  3. check whether the user has any default account

The result of all the above actions should be logged.

If all the above condition satisfies, the transaction is carried out. In future, there might be some additional checks.

Which object oriented design pattern should be best suitable for the above case?

9
  • 3
    Never look for a design pattern to solve a problem. Use design patterns to communicate the correct solution. programmers.stackexchange.com/questions/70877/… Follow SOLID principles and you won't go far wrong.
    – pdr
    Commented Apr 21, 2013 at 14:08
  • 2
    I disagree. Patterns have names which ease communication and they should also be used to communicate solutions. But I don't agree with "Never look for a design pattern to solve a problem". They do not only solve specific problems, but they also deal with different forces and constraints. Have a look at "Proxy" and "Decorator". They look similar but solve different problems. So in my opinion, before you solve a problem yourself you should at least have a look at well-known design patterns in order to profit from both, a standard approach to solve a problem, and an easy way to communicate it.
    – Jonny Dee
    Commented Apr 22, 2013 at 6:36
  • 10
    Here is a good characterization of what a pattern is: "They [patterns] provide working, concrete, and adaptable solutions to problems that repeatedly arise in certain situations during software development, from organizational to programming contexts." [POSA5, p. 30] So from this point of view, it is totally clear that looking for a pattern as an adaptable solution is a ligitimate approach.
    – Jonny Dee
    Commented Apr 22, 2013 at 8:25
  • 3
    Are you asking for an object oriented construction in order to describe plain old procedural programming?
    – mouviciel
    Commented Sep 23, 2013 at 14:12
  • 4
    Follow the KISS principle. So far your problem can be solved with 3 "if" statements in a single method. Do not try to use a design pattern just for the sake of being cool. Every time you write an additional class, always think: Do I really need that?
    – Eiver
    Commented Oct 7, 2013 at 11:41

5 Answers 5

18

It sounds like what you are looking for is a Chain of Responsibility. In this case you could have the following classes:

  • TransactionValidatorBase abstract base class
  • TransactionTimeValidator
  • TransactionAmountValidator
  • TransactionAccountValidator

That are chained together to apply however many rules you specify.

Furter Reading

2
  • 14
    My understanding is that Chain of Responsibility is more of a filter--i.e. we go down the chain until we find someone equipped to cope with the responsibility, then that "link" will handle the responsibility and exit. One flaw in COR in practical terms is that it's hard to make it return a value, which it seems like you might need for this. Commented May 1, 2013 at 2:38
  • I think you can have a one-level Chain of R. I don't really think t's hard to return a value from a Chain, with a little bit of abtraction. Each level will be required to communicate up adhering to a certain primitive interface, and will be required to accept input from below, given such input conforms to primitive interface. When interface richness is needed between two Chain levels that are more intimately coupled, the abtraction can be Poly-morphed to support that. Commented Oct 7, 2013 at 23:43
5

If your sequence of steps are doing mostly validation duties (as it looks you are), without mutating the inputs, I'd think indeed of the "Chain of Responsibility" pattern, as explained in his answer by @p.s.w.g

But since your question is a bit more generic, I'd like to add the "Pipeline processing" as well, since with this one, a step would produce an output that would become the input for the next step (thus mutating original input).

Here are two articles about it:
Pipeline collection by Martin Fowler
More theoretical discussion about the pattern

1

The correct pattern here is really depends on a context. Before picking any particular pattern to stick to, I will try to find out answers to those questions:

  • Is it required to create different combinations of (1,2,3) checks at run-time ?
  • Do they need the same variables to perform their actions or they are greatly different?
  • How precise the error messages should be?
  • In case of failure do user retry from (1)st step always?
  • How concurrency is handled?
  • Does each method adds something to the request or simply validates? (say Default acct id?)

Based on a gut feeling I would code them as a plain methods with aggregating parameter for error codes.

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);
}

It might be a good idea to put DoTransaction in the "ITransactionValidationStragegy" interface and create a layer super-type which will contain validation boilerplate code.

However, in this design I am assuming that validation logic is determined at compile time.

0

While the patterns are already mentioned here, i would suggest you to think about how you would like to use the same in your application, based on the frameworks you are using.

For instance, the validation you would like to do, most likely will keep changing as and when time progress (may be you want to add a new validation in future which restricts transactions to 10 a day). Also, you may not want to do the validation before your actual business service or integration code kicks in. It would be good, if you can have the validations added as configurable ones.

In case you are using Struts, using interceptors might be a good idea. In case of spring, beans injection as dependency gives you more flexibility. My suggestion is not only to look at the patterns/idioms but also look at the framework which you use to build the application and see how best you can fit in your requirement from a futuristic point of view.

-2

According to my understanding whatever is required can be fitted into the command pattern like below. Class design can be done as per below.

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

Your Client class will contain the following code snippet:

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);

This is as per my understanding, with the scenario which has been given above.

1
  • It is bad because when money validation fails, time validation is useless but it will be done anyways
    – Ewoks
    Commented Oct 28, 2015 at 20:28

Not the answer you're looking for? Browse other questions tagged or ask your own question.