Проектирование структуры данных на языке статической типизации - PullRequest
0 голосов
/ 20 ноября 2010

Я использую C # для написания (гипотетического) приложения - интернет-магазина.

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

  • Номер продукта(обязательно)
  • Имя (обязательно)
  • Цена (обязательно)
  • Рейтинг (необязательно)
  • Количество продано (необязательно) - это общая продажаэтого продукта

У меня есть 4 страницы, которые показывают отфильтрованный список продуктов.Страницы показывают различную информацию для каждого продукта:

  • 1-я страница: PN, Имя, Цена
  • 2-я страница: PN, Имя, Цена, Рейтинг
  • 3-я страница:PN, Имя, Цена, Количество проданных
  • 4-я страница: PN, Имя, Цена, Рейтинг, Количество проданных

Мой вопрос , как мне оформитьструктуры данных для размещения всех моих страниц с небольшим дублированием?

Подход грубой силы заключается в создании типа для каждой страницы:

IList<Product>
IList<ProductWithRating>
IList<ProductWithSoldQuantity>
IList<ProductWithRatingAndSoldQuantity>

позже 3 может происходить из Product, но из-за отсутствиямножественное наследование ProductWithRatingAndSoldQuantity не может быть получено как из продуктов Rating, так и из продуктов SoldQuantity.

В динамическом языке я бы просто добавил все необходимые поля и был бы счастлив.

Таким образом, я мог бы смоделировать динамический языковой подход, храня дополнительную информацию (рейтинг, проданные количества) в отдельных диктонарах, например:

{
    IList<Product> Products;
    IDictionary<Product, Rating> ProductRatings;
    IDictionary<Product, SoldQuantity> ProductSoldQuantities;
}
// is equivalent to
IList<ProductWithRatingAndSoldQuantities>

Создание структуры продукта, которая включает все, а затемОбойти частично инициализированный объект - это , а не решение, которое я ищу.

Есть предложения?

Ответы [ 4 ]

1 голос
/ 20 ноября 2010

Извините, недостаточно символов для ответа в комментарии.

У вас должен быть один объект домена, Product.У него могут быть ненулевое имя, ProductNumber и Price, потому что вы не можете иметь продукты, у которых нет таких вещей.

Рейтинг должен быть обнуляемым, потому что возможно иметь продукт, который не имеетрейтинг.Независимо от того, имеет ли Продукт рейтинг, он все равно всегда является Продуктом.Я оставлю «Кол-во продаж», потому что на самом деле я не буду хранить это как свойство продукта, у меня будут коллекции «Заказы» и «Линия заказов», и я буду рассчитывать количество «Проданных» из них (нормализация).Однако, в отсутствие этих других коллекций, вы можете сохранить его как поле в Product.Если бы я собирался это сделать, это было бы целочисленное свойство, не равное нулю, по умолчанию равное нулю.

Для фильтрации вам нужна только одна коллекция, которая была бы некоторой реализацией IEnumerable или IQueryable или обоих,скорее всего, вы бы выбрали что-то вроде Entity Framework и на самом деле имели бы ObjectSet, но я бы постарался не зависеть от того, какой метод хранения я использую, и работать с этими интерфейсами.

Затем вы можете запросить свойединая коллекция, чтобы определить, какие атрибуты являются нулевыми в Продуктах в модели вашего домена.Синтаксис может быть не идеальным, но Intellisense ничего не поймет, я - парень из VB в 99% случаев.

var productsWithNoSales = Context.Products.Where(p=> p.QuantitySold == 0);
var productsWithNoRating = Context.Products.Where(p=> p.Rating == nothing);
var productsWithNoSalesOrRating = Context.Products.Where(p=> p.QuantitySold == 0).Where(p=> p.Rating == nothing);

Это в значительной степени самая чистая возможная модель предметной области для того, что вам нужно.

Наследование было бы, если бы у вас были специализированные производные продукта, обладающие либо дополнительными свойствами, либо другим поведением.Например, моя собственная система имеет базовый класс Product и сущность EbayProduct и AmazonProduct, которые оба наследуются от Product и содержат только дополнительную логику и свойства, связанные с работой с этими сайтами.В классе «Мой продукт» около 20 свойств, в основном обнуляемых, так как при перечислении продуктов у нас не обязательно есть вся доступная информация.Из этих 20 я больше всего отображаю на любой странице около 15. Я, вероятно, делаю что-то похожее на то, что вы пытаетесь сделать, в том, что я отфильтровываю Продукты, которые еще не готовы перечислить, используя точный описанный метод, т.е.Коллекция моих товаров для пропущенных полей.

1 голос
/ 20 ноября 2010

Можете ли вы сохранить рейтинг и количество проданных в качестве атрибутов, а затем хранить логические значения, которые указывают, присутствуют ли они? Я думаю, что вы используете наследование, когда вы, вероятно, должны делать композицию.

1 голос
/ 20 ноября 2010

Почему Rating и SoldQuantity не могут быть просто обнуляемыми?Или всегда присутствовать, но просто не всегда отображается?

0 голосов
/ 20 ноября 2010

Вы могли бы сделать с указанием того, что вы используете?Каковы ваши "страницы" для начала?Какой у вас метод хранения данных?

Звучит так, будто вы путаетесь в отображении ваших данных с хранением данных?Нет необходимости показывать данные только потому, что они существуют.

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

Если вы используете что-то вроде Linq, вы можете просто сделать что-то вроде

var productsWithoutRating = Context.Products.Where(p => p.Rating == nothing);

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

...