Лучший шаблон проектирования ООП для последовательности операций


11

Я работаю над приложением, модуль которого последовательно выполняет следующие финансовые операции:

Когда пользователь запрашивает перевод определенной суммы на свой банковский счет:

  1. проверить, может ли какая-либо транзакция произойти сейчас? (транзакция может быть осуществлена ​​только в течение определенного периода времени)
  2. проверьте, запросил ли пользователь минимальную сумму для снятия
  3. проверьте, есть ли у пользователя учетная запись по умолчанию

Результат всех вышеперечисленных действий должен быть зарегистрирован.

Если все вышеперечисленное условие удовлетворяет, сделка выполняется. В будущем могут быть некоторые дополнительные проверки.

Какой объектно-ориентированный шаблон проектирования лучше всего подходит для вышеуказанного случая?


3
Никогда не ищите шаблон дизайна для решения проблемы. Используйте шаблоны проектирования, чтобы сообщить правильное решение. programmers.stackexchange.com/questions/70877/… Следуйте принципам SOLID, и вы не ошибетесь.
НДР

2
Я не согласен. У шаблонов есть имена, которые облегчают общение, и их также следует использовать для обмена решениями. Но я не согласен с «Никогда не ищите шаблон дизайна для решения проблемы». Они не только решают конкретные проблемы, но и сталкиваются с различными силами и ограничениями. Посмотрите на «Прокси» и «Декоратор». Они похожи, но решают разные проблемы. Поэтому, на мой взгляд, прежде чем вы решите проблему самостоятельно, вы должны хотя бы взглянуть на общеизвестные шаблоны проектирования, чтобы извлечь выгоду из обоих, стандартного подхода к решению проблемы и простого способа ее решения.
Джонни Ди

10
Вот хорошая характеристика того, что такое шаблон: «Они [шаблоны] обеспечивают рабочие, конкретные и адаптируемые решения проблем, которые неоднократно возникают в определенных ситуациях при разработке программного обеспечения, от организационного до программного контекста». [POSA5, стр. 30] Таким образом, с этой точки зрения, совершенно ясно, что поиск шаблона в качестве адаптируемого решения является легитимным подходом.
Джонни Ди

3
Вы запрашиваете объектно-ориентированную конструкцию для описания простого старого процедурного программирования?
Mouviciel

4
Следуйте принципу KISS. До сих пор ваша проблема может быть решена с помощью 3 «если» операторов в одном методе. Не пытайтесь использовать шаблон дизайна только ради того, чтобы быть крутым. Каждый раз, когда вы пишете дополнительный урок, всегда думайте: мне это действительно нужно?
Eiver

Ответы:


13

Похоже, что вы ищете, это цепь ответственности . В этом случае вы можете иметь следующие классы:

  • TransactionValidatorBase абстрактный базовый класс
  • TransactionTimeValidator
  • TransactionAmountValidator
  • TransactionAccountValidator

Они объединены в цепочку, чтобы применить любое количество правил, которые вы укажете.

Furter Reading


11
Насколько я понимаю, «Цепочка ответственности» - это скорее фильтр - то есть мы идем по цепочке, пока не найдем кого-то, способного справиться с ответственностью, тогда это «звено» справится с ответственностью и уйдет. Одним из недостатков COR на практике является то, что трудно заставить его возвращать значение, которое, как вам кажется, может понадобиться для этого.
Эми Бланкеншип

Я думаю, что у вас может быть одноуровневая цепочка R. Я не думаю, что сложно вернуть значение из цепочки с небольшим отрывом. Каждый уровень должен будет сообщать о присоединении к определенному примитивному интерфейсу и должен будет принимать входные данные снизу, если такой входной сигнал соответствует примитивному интерфейсу. Когда требуется богатство интерфейса между двумя уровнями цепочки, которые более тесно связаны, для поддержки этого абстракция может быть Poly-morphed.
Andyz Smith

3

Если ваша последовательность шагов выполняет в основном обязанности проверки (как вам кажется), не изменяя входные данные, я действительно подумаю о шаблоне «Цепочка ответственности», как объяснил в своем ответе @pswg

Но поскольку ваш вопрос немного более общий, я хотел бы также добавить «конвейерную обработку», поскольку с этим шагом шаг будет производить выходные данные, которые станут входными данными для следующего шага (таким образом, изменяя исходный ввод) ,

Вот две статьи об этом:
Сборник конвейеров Мартина Фаулера
Более теоретическое обсуждение паттерна


2

Правильный шаблон здесь действительно зависит от контекста. Прежде чем выбрать какой-то конкретный шаблон, я постараюсь найти ответы на эти вопросы:

  • Требуется ли создавать различные комбинации (1,2,3) проверок во время выполнения?
  • Нужны ли им одни и те же переменные для выполнения своих действий или они сильно различаются?
  • Насколько точными должны быть сообщения об ошибках?
  • В случае сбоя пользователь всегда повторяет действие с (1) шага?
  • Как обрабатывается параллелизм?
  • Каждый метод добавляет что-то к запросу или просто проверяет? (скажем, по умолчанию идентификатор действия?)

Основываясь на интуиции, я бы написал их как простые методы с агрегирующим параметром для кодов ошибок.

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

Возможно, было бы неплохо поместить DoTransaction в интерфейс «ITransactionValidationStragegy» и создать супертип слоя, который будет содержать шаблонный код проверки.

Однако в этом проекте я предполагаю, что логика проверки определяется во время компиляции.


0

Хотя шаблоны уже упоминались здесь, я бы посоветовал вам подумать о том, как бы вы хотели использовать то же самое в своем приложении, основываясь на используемых вами платформах.

Например, валидация, которую вы хотели бы сделать, скорее всего, будет меняться с течением времени (возможно, вы захотите добавить новую валидацию в будущем, которая ограничивает транзакции до 10 в день). Кроме того, вы, возможно, не захотите выполнять проверку до того, как начнет действовать ваш фактический бизнес-сервис или код интеграции. Было бы хорошо, если бы вы могли добавлять проверки как настраиваемые.

В случае, если вы используете Struts, использование перехватчиков может быть хорошей идеей. В случае весны инъекция бобов как зависимость дает вам больше гибкости. Я предлагаю не только взглянуть на шаблоны / идиомы, но также взглянуть на среду, которую вы используете для создания приложения, и увидеть, насколько лучше вы можете соответствовать вашим требованиям с футуристической точки зрения.


-2

Насколько я понимаю, все, что требуется, может быть встроено в шаблон команды, как показано ниже. Дизайн класса может быть сделан согласно ниже.

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

Ваш класс Client будет содержать следующий фрагмент кода:

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

Это, как я понимаю, со сценарием, который был приведен выше.


Это плохо, потому что, когда проверка денег не удалась, проверка времени бесполезна, но это будет сделано в любом случае
Ewoks
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.