Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programming pattern / architectural question

I am currently working on a project where I have a BankAccount entity for some other entity.

Each bank account as a reference to a bank entity, an account number and optionally an IBAN.

Now since an IBAN can be validated, how can I ensure that when the IBAN is set for an account is valid. What would be a clean architectural approach? I currently have a domain layer without any reference to any other layer and I like this clean approach (I was inspired by Eric Evans DDD). Fortunately the IBAN validation can be performed without accessing any outside system so in this case I could have something like

puclic class BankAccount
{
  public string Iban
  {
     set { // validation logic here }
  }
}

But now I was thinking what approach I would use if the IBAN validation requires an SQL server check for example, or an external dll. How would I implement that. Would I create an IBAN value object which is passed to a service, that decides whether the IBAN is valid or not and after that set it to the BankAccount entity? Or would I create a factory which is allowed to instanstiate IBANs and performs validation before?

Thanks for your help!

like image 264
Chris Avatar asked Feb 27 '23 20:02

Chris


2 Answers

I would use some form of Inversion Of Control.

To be specific, I would have an interface called IIBANValidator. The various means of validating the IBAN should implement that interface. For example:

interface IBANValidator {
    Boolean Validate(string iban);
}

class SqlBanValidator : IBANValidator {

    public bool Validate(string iban) {
        // make the sql call to validate..
        throw new NotImplementedException();
    }

}

Then, I would have a method in my BankAccount class which accepted an object that implements IIBANValidator and the IBAN number and was structured like (not optimized by any stretch):

Boolean SetIBAN(IIBANValidator validator, String iban) {
  Boolean result = false;
  if (validator.Validate(iban)) {
    Iban = iban;
    result = true;
  }

  return result;
}

At this point your BankAccount class would not have to have a dependency on your validators, you could swap them out at will, and ultimately it's very clean.

The final code would look something like:

BankAccount account = new BankAccount();
account.SetIBAN(new SqlBanValidator(), "my iban code");

Obviously at runtime you could pass any validator instance you wanted.

like image 183
NotMe Avatar answered Mar 20 '23 15:03

NotMe


Rather than the IBAN number being a simple string, what if it was an actual class? You could implement validation in the constructor (if validation has no external dependencies), or you could use a factory to provide IBAN instances (if you need external validation). The important thing is that, if you have an IBAN instance, you know that it's a valid IBAN number.

Should BankAccount actually have a mutable IBAN number? I'm not terribly familiar with banking, but that sounds like a scary idea.

like image 31
Daniel Yankowsky Avatar answered Mar 20 '23 14:03

Daniel Yankowsky