Как стать автором
Обновить

Чистый код: Принцип подстановки Барбары Лисков (LSP)

Уровень сложностиСредний
Время на прочтение8 мин
Количество просмотров8.1K
Всего голосов 7: ↑4 и ↓3+3
Комментарии7

Комментарии 7

Объяснено достаточно понятно, хороший пример, благодарю

а мне непонятно с самого начала. рассматривается "товар", который может иметь "категорию". или несколько. При этом у одного товара может быть несколько категорий, а одна категория может содержать разные товары. Это вроде как связь "многие ко многим", которая технически реализуется в реляционных БД через три таблицы. Автор городит свой велосипед, и начинает рассуждения о подстановках Барабары Лисков- концептуальные рассуждения в сочетании с базовой безграмотностью вызывают сомнения в том, стоит ли вообще продолжать чтение статьи. Но я прочитал дальше, и вижу, что у "продукта" в БД есть "primary_key" ID, однако класс AddDrinks при внесении классификатора определяет этот ID по "price" и "name". То есть, в коде примари-кеем работает именно пара имя-цена, но а в БД- ID- а это прямой путь к получению вских интересных эффектов, типа если я добавлю "Лук:100:спортинвентарь", а следом добавлю "Лук:100:еда", то у меня композитный лук со стрелами окажутся на полке с редиской, а мешок лука останется непрокатегоризированный и сгниет на складе, но при этом целостность БД никак не пострадает. Это плохое учебное пособие...

Т.е. вот так низя? :(((

public static int Count<T>(this IEnumerable<T> seq) {
   switch (seq) {
      case Array a:                   return a.Length;
      case ICollection<T> c:          return c.Count;
      case IReadOnlyCollection<T> c:  return c.Count;
      // Matches if seq is not null
      case IEnumerable<T> _:          return seq.Count();
      // Discard pattern when seq is null
      default:                        return 0;
   }
}

Можно, но только в рамках оптимизации. Т.е. все ветки обязаны возвращать то же самое, что вернула бы наиболее общая реализация.

Ну и, к слову, в LINQ уже так и сделано.

Заводить отдельную таблицу на каждую категорию выглядит сомнительно. Мало того что это приводит дублированию кода (методы toSQL), так ещё и усложняет добавление новых категорий.

Лучше сделать как-то так:

CREATE TABLE PRODUCT_CATEGORY(
  product_id INTEGER NOT NULL,
  category_id INTEGER NOT NULL
);

CREATE TABLE CATEGORY(
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL,
);

Искать id продукта по названию и ЦЕНЕ - это вообще что-то с чем-то. Что мешало добавить свойство id в объект Product?

и добавить как-то так:

CREATE TABLE PRODUCT_CATEGORY (
    product_id  int FOREIGN KEY REFERENCES PRODUCTS(ID) ON DELETE CASCADE,
    category_id  int FOREIGN KEY REFERENCES CATEGORY(ID) ON DELETE RESTRICT
);

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

Немного не по теме, но про чистый код: при вставке в запрос строковых данных необходимо экранировать апострофы и прочие спецсимволы.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации