2010-01-05 3 views
4

В настоящее время я работаю над проектом, где у меня есть объект BankAccount для какого-либо другого объекта.Образец программирования/архитектурный вопрос

Каждый банковский счет в качестве ссылки на юридическое лицо банка, номер счета и, возможно, IBAN.

Теперь, поскольку IBAN может быть проверен, как я могу убедиться, что, когда IBAN установлен для учетной записи, действительно. Какой будет чистый архитектурный подход? В настоящее время у меня есть доменный уровень без каких-либо ссылок на любой другой уровень, и мне нравится этот чистый подход (я был вдохновлен Eric Evans DDD). К счастью, проверка IBAN может выполняться без доступа к какой-либо внешней системе, так и в этом случае я мог бы что-то вроде

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

Но теперь я думал, что подход, который я хотел бы использовать, если проверка IBAN требует проверки сервера SQL, например, или внешнюю dll. Как бы это реализовать. Я бы создал объект значения IBAN, который передается службе, которая решает, является ли IBAN действительным или нет, и после этого установите его в объект BankAccount? Или я могу создать завод, которому разрешено запускать IBAN и выполнять проверку раньше?

Благодарим за помощь!

+2

Я думаю, что вы ответили на свой вопрос в конце. Образец СПЕЦИФИКАЦИИ в Evans Domain Driven Design появляется на ум. – David

ответ

5

Я бы использовал некоторую форму инверсии управления.

Чтобы быть конкретным, у меня был бы интерфейс под названием IIBANValidator. Различные способы проверки IBAN должны реализовывать этот интерфейс. Например:

interface IBANValidator { 
    Boolean Validate(string iban); 
} 

class SqlBanValidator : IBANValidator { 

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

} 

Тогда, я бы метод в моем классе BankAccount, который принят объект, который реализует IIBANValidator и номер IBAN и структурированный как (не оптимизированы на любом участке):

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

    return result; 
} 

В этот момент ваш класс BankAccount не должен иметь зависимости от ваших валидаторов, вы можете поменять их по своему усмотрению, и в конечном итоге это очень чисто.

Окончательный код будет выглядеть примерно так:

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

Очевидно во время выполнения вы можете пройти любой экземпляр валидатор вы хотели.

+0

У меня была бы проверка нулевого значения на валидаторе в случае, если его нет. – cjk

+0

@ck: Я абсолютно согласен. – NotMe

1

Вы могли бы реализовать Спецификация, которая использует Dependency Injection для Repository. Тем не менее, вы теряете некоторую сплоченность.

Более подробную информацию можно найти here.

0

Куда поместить логику проверки, зависит от информации, необходимой для выполнения этой проверки. Проверка должна выполняться в типе, который имеет достаточно информации для этого. С другой стороны, необходимо также учитывать сложность логики проверки. Например, если у вас есть данные электронной почты, прикрепленные только к типу Person, он может быть проверен «на месте» в типе лица, потому что проверка не является сложной (при условии, что проверяется только формат электронной почты), и Person является единственным потребителем. Если, с другой стороны, у вас есть данные сделки (характеризующиеся данными о товарах и данными о ценах), потребляемые магазинами и гаражами (продающими ваши старые вещи) с логикой проверки, что товары должны принадлежать инициатору сделки, имеет смысл поставить проверку внутри типа сделки ,

2

Вместо того, чтобы номер IBAN являлся простой строкой, что, если это был фактический класс? Вы можете реализовать проверку в конструкторе (если проверка не имеет внешних зависимостей), или вы можете использовать фабрику для предоставления экземпляров IBAN (если вам нужна внешняя проверка). Важно то, что если у вас есть экземпляр IBAN, вы знаете, что это действительный номер IBAN.

Должно ли BankAccount иметь изменяемый номер IBAN? Я не очень хорошо разбираюсь в банковском деле, но это звучит как страшная идея.

0

Вы можете просто использовать делегат для проверки, вам не нужно передавать весь интерфейс, который когда-либо захочет установить его, должен иметь валидатор.

public delegate bool Validation(IBAN iban); 
void SetIBAN(IBAN iban, Validation isValid){ 
    if(!isValid(iban)) throw new ArgumentException(); 
...} 
0

Я бы сделать его аспект ориентированных и уменьшить сцепление.

[IBANVlidator(Message = "your error message. can also come from culture based resouce file.")] 
    public string IBAN 
    { 
     get 
     { 
      return _iban; 
     } 
     set 
     { 
      this.validate(); 
      _iban = value; 
     } 
    } 

this.validate() вызывается из базового класса вашего BankAccount который перебирает через все свойства, имеющие атрибут проверки. Атрибуты валидации - это пользовательские атрибуты, полученные из класса ValidationAttribute, который может настраивать свойства класса.

Ответственность IBAN за валидацию присваивается атрибуту валидации IBANValidator., конечно, эта конструкция может быть улучшена, что выходит за рамки этого ответа.

Смежные вопросы