Существуют ли известные шаблоны проектирования для реализации дисконтных моделей?
Под дисконтными моделями я имею в виду следующее:
Если клиент покупает продукт X, продукт Y и продукт Z, он получает скидку в размере 10% или 100 долларов США.
Если клиент покупает 100 единиц Продукта X, он получает скидку в размере 15% или $ 500.
Если клиент принес в прошлом году более 100 тысяч долларов, он получает фиксированную скидку 20%
Если клиент приобрел 2 единицы Продукта X, он получает 1 единицу Продукта X (или Продукта Y) бесплатно.
...
Есть ли общий шаблон, который можно применять для обработки всех вышеперечисленных сценариев? Я думаю о нескольких моделях, но не могу найти общую модель.
design
design-patterns
financial
Kanini
источник
источник
Ответы:
Если проблема заключается в том, что вам необходимо применить несколько скидок, при определенных обстоятельствах вы можете рассмотреть шаблон цепочки ответственности .
Короче говоря, вы передаете информацию, которую хотите обработать, первому процессору, и оттуда решается, передавать ли ее другим процессорам, прежде чем возвращать результат.
Таким образом, вы можете изменить структуру и последовательность процессоров, даже не меняя вызывающий код.
источник
Образцы стратегии, декоратора и состояния выделяются мне как потенциальные отправные точки. Состояние может быть особенно полезным для 2 или 3, так как 2 зависит от состояния заказа, а 3 зависит от состояния клиента в течение определенного периода времени. Стратегия и Декоратор отличаются от других, поскольку вы можете использовать стратегию для реализации нескольких алгоритмов расчета цены заказа и декоратор для добавления новых скидок к заказу.
Однако помните, что шаблоны проектирования - это просто модели. Там может быть не один шаблон, который применяется, а система шаблонов. Также рассмотрите возможность внесения изменений в описанные модели, чтобы они лучше подходили вашему решению. Лучше иметь хороший дизайн, чем создавать шаблон, который не обязательно помогает просто сказать, что у вас есть шаблон.
источник
Ну, я бы разработал модель скидок в виде пары «Предварительное условие» и «Скидка», где «Предварительное условие» - это класс с методами.
или
и скидка имеет метод
void ApplyTo(Customer c)
. Это дает вам возможность комбинировать любые предварительные условия с любым типом скидки (я думаю, что это форма "схемы моста").Если у вас есть фиксированное количество предварительных условий, то вы можете решить эту проблему путем создания определенных подтипов (шаблон стратегии). Однако, когда ваши предварительные условия могут быть очень сложными, с такими логическими утверждениями, как AND, OR и NOT, вы можете лучше реализовать некоторый интерпретатор правил для условий. Правила могут быть простой текстовой строкой, написанной на простом «предметно-ориентированном языке».
То же самое относится и к классу «Скидка»: у вас могут быть несколько подтипов для разных типов скидок, или общий подход, где правила скидок даются в текстовой форме, оцениваемой некоторым интерпретатором.
источник
Вероятно, нужен интерфейс IDiscount, поскольку все различные скидки - это одно и то же, и мы будем рассматривать их концептуально как общие скидки.
Класс "заказ этого клиента", вероятно, нуждается в коллекции скидок. Список? Hash? Связанный список? Пофиг, пока. Скидки распространяются на покупку, а не на покупателя!
Держите экземпляр экземпляра Discount отдельно от Customer, Shopping Cart, History и т. Д. Он сильно изменится, как указывал @jfrankcarr.
Вероятно, разные классы для каждой скидки, так как алгоритм и параметры для каждой скидки сильно и непредсказуемо различаются.
Я вижу много обработки событий, так как расчет скидок реагирует на изменения в корзине покупок, и наоборот.
Дизайн шаблона приложения
strategy pattern
. IDiscount - интерфейс для реализации различных алгоритмов скидок.Я вижу
factory
. Конечно, не полномасштабныйabstract factory pattern
, а отдельный класс на данный момент в анализе. Разумно, должно быть единственное место, где есть достаточно контекста, чтобы решить, какие скидки применяются и затем создать их. Один класс. Если правила применения скидок впоследствии срываются из-за вечеринки в отделе маркетинга, любая дополнительная логика Discount Construction должна объединяться в этом базовом заводском классе, я думаю.Я могу видеть
Chain of Responsibility
. Это не является взаимоисключающейfactory
идеей. Вместо того, чтобы повторять коллекцию скидок, каждая скидка вызывает следующего парня. Класс «заказ клиента» в этом случае не содержит коллекцию скидок.Я думаю, что фактор «хмммм…» в цепи ответственности состоит в том, что каждая скидка имеет ссылку на следующую. Подразумевается, что порядок имеет значение. Что не так. Кроме того, концепция, которую воплощает CoR, заключается в том, что один объект не может обработать запрос, поэтому он передается «до следующего более высокого уровня». Наша модель отличается. Единственный запрос - это рассчитать. Каждая скидка делает это. Результат или эффект могут быть нулевыми, но каждая скидка рассчитывается. Я инстинктивно склоняюсь к более высокой точности в реальном мире.
Предположения
Что меняется, что остается прежним?
Скидки очень разные. Различное количество и вид параметров для составления каждого правила.
Аргументы для соответствующих скидок изменяются при изменении корзины покупок.
Количество доступных скидок меняется
Скидки, которые этот клиент имеет право на изменения при изменении его корзины покупок.
История покупок не меняется в контексте этой покупки
Общая стоимость изменяется динамически в зависимости от количества покупок и скидок.
После первоначального применения скидка может измениться, например, при изменении количества покупки.
источник
По логике, модель со скидкой может быть чем угодно , поэтому вы не можете предполагать, что можете запрограммировать все случаи заранее. Никто, отвечая на ваш вопрос, не может быть полностью уверен, что вам действительно нужно. Однако при условии, что вы получаете обычные виды скидок, которые можно найти в реальном мире ...
Большой вопрос в том, будут ли запрограммированы скидки или вы хотите, чтобы пользователи вводили их. Как упомянуто выше, вы никогда не сможете запрограммировать их, но обычно цель состоит в том, чтобы попытаться сделать их более вводимыми, как в обычных случаях, а не программировать их все. Это в некоторой степени относится, даже если для создания всех скидок используются программисты.
Мартин Фаулер упоминает «Метод индивидуального экземпляра» в «Шаблонах анализа: многократно используемые объектные модели» как часть того, как реализовать «Правила публикации» для систем бухгалтерского учета, но правила кажутся довольно схожими с вашими. Я бы дал больше деталей, но это работа, защищенная авторским правом и
Для пользовательского интерфейса вам нужно либо придумать довольно простые варианты использования, либо создать интерпретатор и построитель запросов. Возможно оба: один для простых случаев и еще один продвинутый. Если вы действительно пишете интерпретатор, это, вероятно, довольно хороший случай для использования шаблона Интерпретатор, поскольку его относительно просто кодировать по сравнению с генератором синтаксического анализатора, и более медленное время анализа, вероятно, не будет иметь большого значения. (Если вам нравится использовать генераторы парсеров, не позволяйте мне останавливать вас).
Однако не пытайтесь делать все с помощью переводчика - в какой-то момент вы просто программируете на своем собственном непристойном языке, так что вы могли бы также использовать и настоящий. Если ваш интерпретируемый язык поддерживает функции (вероятно, он должен вызывать их - определение их сомнительно), они могут быть закодированы на реальном языке. Не идите дальше по этой дороге, чем нужно.
Независимо от того, что вы делаете, в конечном итоге кто-то захочет, чтобы скидка основывалась на том, были ли они приобретены в течение 30 рабочих дней с момента продвижения по службе, причем рабочие дни учитываются только в том случае, если в регионе не было праздников, определенных почтовым индексом магазина или клиентом. Почтовый индекс. Поэтому не пытайтесь спроектировать идеальную систему заранее - предположим, что вам иногда потребуется написать код для новых видов скидок и разработать соответствующий дизайн.
источник
Есть ли смысл спрашивать, есть ли полезный шаблон для этого? Какой тип модели требуется - структурный или поведенческий?
В идеале, если бы я написал программное обеспечение для этого, все, что нужно, это алгоритм . Простая функция, которая рассчитывает общую скидку следующим образом:
Вам не нужно ничего больше, чем это!
Чтобы уточнить: я понимаю, что будет много правил - большинство базовых таких представлений должно быть в форме базы правил (набор атрибутов данных и результирующая скидка на нее), и функция, подобная выше, будет выполнять итерацию для ее вычисления. Если правила добавляются или удаляются, вам не следует менять код - просто измените базу правил.
Шаблон понадобится только в том случае, если нам нужны разные объекты, для доступа к API друг друга или для связи, чтобы поставить задачу на место.
PS: Подумайте об этом - когда брандмауэр обрабатывает пакеты и передает или отклоняет пакеты (или изменяет его) - какой шаблон проектирования он использует? Ответ НИЧЕГО из вышеописанного!
источник