ОО Дизайн вопрос

У меня есть два типа продуктов: со скидкой (10% диск) и без скидки (0%). Каждый из них может быть либо LocalProduct, либо ExportableProduct, при этом экспортный продукт облагается налогом с продаж в размере 15%.

Как лучше смоделировать этот сценарий. Я абсолютный новичок в дизайне программного обеспечения, и у меня очень ограниченные идеи 1. Иметь 4 разных подтипа продукта 2. Использовать шаблон стратегии и иметь 4 разных стратегии.

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


person NewbieEngineer    schedule 15.02.2010    source источник
comment
Чем больше я узнаю, тем больше кажется, что шаблон/композиция стратегии по сравнению с принципом наследования/открытия-закрытия является предпочтительной стратегией по сравнению с наследованием почти во всех случаях, когда не используется подстановка типов (LSP). Но тогда я дебил.   -  person    schedule 15.02.2010
comment
Существует шаблон стратегии, поэтому вы можете легко поддерживать будущие изменения (новые типы продуктов) в своем программном обеспечении. Если вы можете вообразить использование программных плагинов для вашего дизайна, где типы продуктов являются плагинами, тогда стратегия идеальна.   -  person Fuhrmanator    schedule 18.04.2012


Ответы (8)


Классы различают наборы поведения. Итак, давайте посмотрим на ваши подразделения в этих терминах:

  • Хотя можно было бы привести аргумент, что скидка/без скидки — это вариация в поведении, тривиально свести это к одному поведению: все товары имеют скидку, но сумма скидки составляет 0% для товаров без скидки. . Это просто атрибут ваших товаров (discount_amount), а не отдельный класс.

  • Локальный/экспортируемый может иметь или не иметь отличное поведение. Если единственное различие заключается в том, разрешено ли перевозить продукт за границу или нет, то простой логический флаг должен обрабатывать это различие более чем адекватно. Если, с другой стороны, для экспортируемых продуктов требуется поведение, не поддерживаемое местными продуктами (например, запись таможенных требований и процедур), то было бы уместно либо сделать ExportableProduct подклассом LocalProduct (если поведение экспортируемого продукта является надмножеством местных поведение продукта) или создайте абстрактный класс Product с подклассами LocalProduct и ExportableProduct (если локальные продукты также имеют поведение, которое не поддерживается экспортируемыми продуктами).

person Dave Sherohman    schedule 15.02.2010

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

person crunchdog    schedule 15.02.2010

я бы сделал так:

Имейте класс под названием «Продукт», который имеет основные свойства продукта, такие как имя, описание, тип и т. д.

Базовый класс «Продукт» может иметь свойство «Ставка скидки». Это может быть 0 для без скидки и любое значение для скидки. Это поможет упростить расчет, так как всегда будет применяться одна и та же формула, только в одном случае скидка равна 0.

Тогда у вас может быть два класса «ExportableProduct» и «LocalProduct», оба они наследуются от класса «Product».

person Emad Gabriel    schedule 15.02.2010

Я бы предположил, что, возможно, товары со скидкой/без скидки вообще не должны быть типами товаров. Вместо этого есть два подтипа и свойство/поле «скидка» в родительском продукте. Каждый продукт может иметь любую скидку. Это также позволяет скидки, которые не фиксированы на уровне 10%.

person Tom Castle    schedule 15.02.2010

Я бы избегал наследования (т.е. подтипа) только для этого.

Вместо этого я бы определил перечисления для Discounted / NonDiscounted и Local / ExportableProduct. Тогда каждый класс продуктов будет просто иметь свойство для каждого из них, указывающее его тип.

Затем в отдельном классе, например: PricingCalculator, определите метод Calculate (возможно, статический), который принимает экземпляр продукта. Этот метод просто проверяет свойства перечисления и применяет требуемые процентные значения в расчетах.

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

person Ash    schedule 15.02.2010

Я бы избегал всего и имел только два свойства: discount и local

Поскольку меняется только одна вещь (цена), вы можете рассчитать ее на лету (скидка => price * .9, экспорт => price * .85 - или даже и то, и другое => экспорт и скидка => price * .9 * .85)

person Adam Kiss    schedule 15.02.2010

Наследование особенно полезно, когда больше зависит от типа.

Например, если скидка, налог и способ доставки различаются в зависимости от типа товара, то определенно пора подумать о наследовании и подклассах (где вы бы сказали, что «этот подтип товара имеет этот налог и эту скидку и эта доставка").

С другой стороны, когда только одна вещь изменяется в зависимости от типа, тогда менее очевидно, стоит ли иметь несколько типов (т. иметь значение свойства (например, с именем «discount_percentage»).

person ChrisW    schedule 15.02.2010

Когда это все поведение, которое вам нужно, просто иметь два логических значения в вашем продукте и включать их — лучшее решение. ЯГНИ.

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

person Stephan Eggermont    schedule 15.02.2010