Это отлично работает до тех пор, пока... есть спрос на доллар. Как только спрос начнёт снижаться возникнет проблема - куда деть свеженапечатанное. Ну, это не считая того неприятного момента, что инфляция убивает сбережение.
Очень мало кто делает оптимизацию путём изменения схемы. Все предпочитают фокусы с инексацией, хинты и т.п.
Секционирование, кстати, можно ещё применять. Но тогда несбалансированное поле надо в первичный ключ загонять (если конечно СУБД не умеет делать партиционирование по произвольному уникальному индексу, а только по первичному ключу), а это почит всегда невозможно и всегда неудобно.
вы получаете не копию, а ссылку/указатель на объект
На самом деле в данном случае это не имеет значения :) Потому что исходный пример был ложной демонстрацией — из изменения значения какого-либо атрибута объекта не следует что сам объект стал другим.
в конкретном случае когда у вашего прямоугольника есть методы setWidth и setHeight, то наследовать от него квадрат не самая хорошая идея потому что у квадрата функция setWidth будет менять сразу ширину и высоту что кaк минимум не соотвествует её названию.
Безусловно идея не самая лучшая (скорее всего Прямоугольник и Квадрат вообще потомки общего предка Многоугольник), но речь не об «удачно-неудачно», а о «нарушает LSP/не нарушает LSP». И как по мне — при корректной реализации — не нарушает.
Я же в последней строчке проверяю его идентичность (ну или эквивалентность если оператор перегружен), а вовсе не тип.
Я, признаться, не силён в синтаксисе C# (или на чём этот код написан?). Но в других языках подобные присваивания (old = square;) порождают новый экземпляр (который дальше живёт своей жизнью). Поэтому я и пишу вам про разницу между эквивалентностью и бытием (есть ОГРОМНАЯ разница между понятиями «тот же» и «такой же»).
Принцип наименьшего удивления.
Эвона… То есть вы ожидаете что объект будет себя вести так, как хочется вам, притом что вам мало что известно о его внутренней структуре и реализации? Я всё пытаюсь намекнуть на то, что строчка assert rect.get_area() == 200
это грубое нарушение принципа инкапсуляции.
Откуда вообще убеждённость в том, что будет два разных метода для задания ширины и высоты, а не один для задания двух сторон сразу (и, при этом, виртуальный), например? Который у Квадрата будет вызывать ошибку при вызове с разными значениями в параметрах…
Такой потомок нарушает LSP точно так же, как это делает потомок-квадрат.
Ничего он не нарушает. Вы, вероятно, неверно понимаете LSP. Замените все вызовы Прямоугольник. на Квадрат. и всё будет работать ровно так же (если вы правильно сделали реализации).
Если продолжать вашу логику дальше и довести её до крайности получится что наследование вообще нельзя использовать, так как потомки могут отличаться от предков (сохраняя, при этом, полную идентичность в поведении).
Минуточку! Я правильно понимаю что в вашем понимании отличие ООП-фигуры (что квадрата, что прямоугольника, что окружности) от математического состоит в том, что у них можно изменить размер? Ну, потому что приведённый вами фрагмент кода демонстрирует несколько отличную от исходной («изменить размер так, чтобы он при этом остался тем же самым квадратом») идею, а именно «у ООП квадрата можно изменить размер и он, при этом, по прежнему останется квадратом». А если добавить перед последней строчкой что-нибудь вроде square.Color = Red;
результат последней будет такой же (true)?
Так именно в этом и проблема: нет у него двух разных понятий «длина» и «ширина», а потому их нельзя менять независимо друг от друга. А вот у прямоугольника — можно.
Это кто вам такое сказал? С чего вообще вы берёте на себя смелость утверждать что вы можете гарантировать то или иное поведение класса (при условии что вы не видите и не определяете его реализацию)? Откуда убеждённость в том что длины сторон непременно независимы?
Давайте на секунду представим что у класса «Прямоугольник» есть потомок «Прямоугольник с соотношением сторон 1:2» (или вроде того). Вы будете утверждать что класс Прямоугольник никак не может являться его предком? Если да — на каком основании?
У «математического» квадрата нельзя изменить размер так, чтобы они при этом остался тем же самым квадратом. У «ООП-квадрата» — можно.
И у ООП-квадрата нельзя. Как?
А обсуждаемый пост тут для кого был написан? У прямоугольника можно менять длину и ширину независимо, у квадрата — нет. Это и есть разное поведение.
И у квадрата можно. Просто у него нет понятий «длина» и «ширина», а есть понятие «длина стороны» (причём можно сделать реализации, в которых это будет дополнительное свойство, в том числе вычислимое). Но вы можете изменить длину любой его стороны. В чём проблема-то?
Никогда не понимал откуда эти проблемы с квадратом и прямоугольником…
Базовый постулат: каждый квадрат является прямоугольником (но не каждый прямоугольник — квадратом). Следовательно у класса Квадрат (который является потомком класса Прямоугольник) должен быть переопределён метод контроля длин сторон и сеттеры для них. Никто же не удивляется что нельзя создать прямоугольник с нулевой или отрицательной длинами сторон? Так же и квадрат — он должен контролировать единообразность длин. А уж что делать при расхождении (генерировать исключение или приводить вторую сторону в соответствии с задаваемой) — вопрос договорённостей (и, в известной степени, деталей реализации интерфейсов класса Прямоугольник).
В данном случае, разумеется, речь про явление. Оно не полностью тождественно моде (как не полностью тождественно религии, философскому учению и т.п.), но весьма на неё похоже (в первую очередь именно отсутствием чёткой логической мотивации выбора).
Называть их можно как угодно. Тогда это называли сетевыми и иерархическими БД.
Но было это не только в эпоху ленточек, но уже и во вполне себе «дисковые времена».
Я вообще не против нового, но оно обязано доказывать свою ценность.
Ну, строго говоря, документо-ориентированные БД — это совсем не новое (и появились они ДО реляционных, которые, в свою очередь, как раз и решали многие проблемы предшественников) :)
Постулат получился настолько с одной стороны простым, а с другой — многослойным, что совершенно неважно о каком именно канале идёт речь! Потому и гениально.
Это отлично работает до тех пор, пока... есть спрос на доллар. Как только спрос начнёт снижаться возникнет проблема - куда деть свеженапечатанное.
Ну, это не считая того неприятного момента, что инфляция убивает сбережение.
Очень мало кто делает оптимизацию путём изменения схемы. Все предпочитают фокусы с инексацией, хинты и т.п.
Секционирование, кстати, можно ещё применять. Но тогда несбалансированное поле надо в первичный ключ загонять (если конечно СУБД не умеет делать партиционирование по произвольному уникальному индексу, а только по первичному ключу), а это почит всегда невозможно и всегда неудобно.
На дворе январь 2022-го. Почём сейчас газ в Литве?
Пишу из октября 2021. Тут Украина покупает у Белоруссии 900МВт чтобы заткнуть дыры в энергобалансе.
P.S. А газ торгуется по 1200, а доходил до 2000 за 1 тыс.куб.м.
Тот случай, когда читаешь и думаешь: "Это должен был написать я!" :)
В скобочках — выдумка экскурсовода. Его попробовали (подозревая что оно, таки, испортилось, «но вдруг нет?») когда оно вернулось назад на Мадейру.
Кстати ситуация с ромбом отлично демонстрирует ущербность концепции множественного наследования.
На самом деле в данном случае это не имеет значения :) Потому что исходный пример был ложной демонстрацией — из изменения значения какого-либо атрибута объекта не следует что сам объект стал другим.
Безусловно идея не самая лучшая (скорее всего Прямоугольник и Квадрат вообще потомки общего предка Многоугольник), но речь не об «удачно-неудачно», а о «нарушает LSP/не нарушает LSP». И как по мне — при корректной реализации — не нарушает.
Я, признаться, не силён в синтаксисе C# (или на чём этот код написан?). Но в других языках подобные присваивания (old = square;) порождают новый экземпляр (который дальше живёт своей жизнью). Поэтому я и пишу вам про разницу между эквивалентностью и бытием (есть ОГРОМНАЯ разница между понятиями «тот же» и «такой же»).
Эвона… То есть вы ожидаете что объект будет себя вести так, как хочется вам, притом что вам мало что известно о его внутренней структуре и реализации? Я всё пытаюсь намекнуть на то, что строчка
assert rect.get_area() == 200
это грубое нарушение принципа инкапсуляции.
Откуда вообще убеждённость в том, что будет два разных метода для задания ширины и высоты, а не один для задания двух сторон сразу (и, при этом, виртуальный), например? Который у Квадрата будет вызывать ошибку при вызове с разными значениями в параметрах…
Ничего он не нарушает. Вы, вероятно, неверно понимаете LSP. Замените все вызовы Прямоугольник. на Квадрат. и всё будет работать ровно так же (если вы правильно сделали реализации).
Если продолжать вашу логику дальше и довести её до крайности получится что наследование вообще нельзя использовать, так как потомки могут отличаться от предков (сохраняя, при этом, полную идентичность в поведении).
Минуточку! Я правильно понимаю что в вашем понимании отличие ООП-фигуры (что квадрата, что прямоугольника, что окружности) от математического состоит в том, что у них можно изменить размер? Ну, потому что приведённый вами фрагмент кода демонстрирует несколько отличную от исходной («изменить размер так, чтобы он при этом остался тем же самым квадратом») идею, а именно «у ООП квадрата можно изменить размер и он, при этом, по прежнему останется квадратом». А если добавить перед последней строчкой что-нибудь вроде
square.Color = Red;
результат последней будет такой же (true)?
Это кто вам такое сказал? С чего вообще вы берёте на себя смелость утверждать что вы можете гарантировать то или иное поведение класса (при условии что вы не видите и не определяете его реализацию)? Откуда убеждённость в том что длины сторон непременно независимы?
Давайте на секунду представим что у класса «Прямоугольник» есть потомок «Прямоугольник с соотношением сторон 1:2» (или вроде того). Вы будете утверждать что класс Прямоугольник никак не может являться его предком? Если да — на каком основании?
И у ООП-квадрата нельзя. Как?
И у квадрата можно. Просто у него нет понятий «длина» и «ширина», а есть понятие «длина стороны» (причём можно сделать реализации, в которых это будет дополнительное свойство, в том числе вычислимое). Но вы можете изменить длину любой его стороны. В чём проблема-то?
А можно попросить раскрыть понимание квадрата для программиста?
Как конкретно он их нарушит? С точки зрения поведения экземпляры класса Квадрат будут совершенно аналогичны экземплярам класса Прямоугольник.
Базовый постулат: каждый квадрат является прямоугольником (но не каждый прямоугольник — квадратом). Следовательно у класса Квадрат (который является потомком класса Прямоугольник) должен быть переопределён метод контроля длин сторон и сеттеры для них. Никто же не удивляется что нельзя создать прямоугольник с нулевой или отрицательной длинами сторон? Так же и квадрат — он должен контролировать единообразность длин. А уж что делать при расхождении (генерировать исключение или приводить вторую сторону в соответствии с задаваемой) — вопрос договорённостей (и, в известной степени, деталей реализации интерфейсов класса Прямоугольник).
Нисколько не споря с тезисом (весьма нелепо спорить с тем, в чём сам убеждён) хочу лишь заметить что вы недооцениваете роль моды в ИТ.
Но было это не только в эпоху ленточек, но уже и во вполне себе «дисковые времена».
Ну, строго говоря, документо-ориентированные БД — это совсем не новое (и появились они ДО реляционных, которые, в свою очередь, как раз и решали многие проблемы предшественников) :)