Принцип замены Лисков (LSP, lsp) является понятием в Объектно-ориентированном программировании, которое указывает:
Функции, которые используют указатели или ссылки на базовые классы, должны быть в состоянии использовать объекты производных классов, не зная это.
В его сердечном LSP об интерфейсах и контрактах, а также как решить, когда расширить класс по сравнению с использованием другая стратегия, такая как состав для достижения цели.
самый эффективный способ, которым я видел, чтобы проиллюстрировать этот тезис, был в [1 122] Главный Первый OOA& D. Они представляют сценарий, где Вы - разработчик на проекте создать платформу для стратегических игр.
Они представляют класс, который представляет плату, которая похожа на это:
Все методы берут координаты X и Y в качестве параметров для определения положения мозаики в двухмерной антенной решетке Tiles
. Это позволит разработчику игр управлять единицами в плате в ходе игры.
книга продолжает изменять требования, чтобы сказать, что игровая основа должна также поддерживать 3D игровые доски для размещения игр, которые имеют полет. Так ThreeDBoard
класс представлен, который расширяется Board
.
На первый взгляд это походит на хорошее решение. Board
обеспечивает и Height
и Width
, свойства и ThreeDBoard
обеспечивают ось Z.
то, Где это ломается, - когда Вы смотрите на всех других участников, наследованных от Board
. Методы для AddUnit
, GetTile
, GetUnits
и так далее, все берут оба параметра X и Y в Board
класс, но ThreeDBoard
потребности параметр Z также.
, Таким образом, необходимо реализовать те методы снова с параметром Z. Параметр Z не имеет никакого контекста к Board
класс и унаследованные методы от Board
, класс теряет их значение. Единица кода, пытающегося использовать ThreeDBoard
класс как его базовый класс Board
, была бы очень неудачливой.
, Возможно, мы должны найти другой подход. Вместо того, чтобы расшириться Board
, ThreeDBoard
должен состоять из [1 119] объекты. Один Board
объект на единицу оси Z.
Это позволяет нам использовать хорошие объектно-ориентированные принципы как инкапсуляция и повторное использование, и doesn’t нарушают LSP.
Либо измените дизайн столбца, как это было предложено Уильямом Тотландом, либо выполните синтаксический анализ строки, чтобы получить представление даты.
Если столбец только содержит день недели, тогда вы можете сделать это:
ORDER BY FIELD(<fieldname>, 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY');
Я думаю, что, если не считать перепроектирования столбца для использования вместо него перечисления, для этого мало что нужно сделать, кроме сортировки результатов после того, как вы их получили.
Редактировать: Грязный прием - это, конечно, добавление еще одной таблицы с парами id: weekday и использование объединений или select in select для подделки перечисления.
Это выглядит беспорядочно, но все же работает и кажется более общим:
select day,
case day
when 'monday' then 1
when 'tuesday' then 2
when 'wednesday' then 3
when 'thursday' then 4
when 'friday' then 5
when 'saturday' then 6
when 'sunday' then 7
end as day_nr from test order by day_nr;
Использование if еще более универсально и запутанно:
select id, day,
if(day = 'monday',1,
if(day = 'tuesday',2,
if(day = 'wednesday',3,
if(day = 'thursday',4,
if(day = 'friday',5,
if(day = 'saturday',6,7)
)
)
)
)
) as day_nr from test order by day_nr;
Вы также можете скрыть детали преобразования имени в int в сохраненном процедура.
Другой способ - создать другую таблицу с этими днями и int для их сортировки, присоединиться к этой таблице при поиске и упорядочить по ней. Конечно, присоединение к varchar не рекомендуется.
Table DaysOfWeek
id | day
--------------------
1 | Monday
2 | Tuesday
3 | Wednesday
4 | Thursday
5 | Friday
6 | Saturday
SELECT * FROM WhateverTable LEFT JOIN DaysOFWeek в DaysOFWeek.day = WhateverTable.dayColumn ЗАКАЗАТЬ DaysOfWeek.id
(Прошу прощения, если это неверно; я недавно застрял с SQL-сервером)
Опять же, это НЕ рекомендуется, но если вы не можете изменить данные, которые у вас уже есть ... Это также будет работать, если в поле dayColumn есть нестандартные значения.
... ЗАКАЗАТЬ ПО date_format (order_date, '% w') = 0, date_format (order_date, '% w');