LINUX.ORG.RU

Вопрос по принципу Лисков.

 ,


0

3

Возьмем классический пример, когда принцип подстановки Лисков не может быть реализован. Точней так считает большинство. Пример квадрата как подкласса прямоугольника.

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

Контракт прямоугольника (инвариант): ширина и высота положительны.

Контракт квадрата (инвариант): ширина и высота положительны; ширина и высота равны.

допустим, мы переопределяем методы квадрата setWidth и setHeight таким образом, что квадрат не реагирует на них, просто игнорирует.

Нарушили ли мы контракты? Нет. Нарушили ли мы принцип Лисков? Да, вроде, тоже нет. Тогда в чем проблема?

Ответ на: комментарий от den73

С того бы.

Тебе же выше уже все объяснили. Если твое draw имеет контракт «чтото рисовать», то переопределенные draw для того, чтобы удовлетворять принципу Лисков, должны что-то рисовать, не более. Если контракт животного для ф-и «подергать за хвост» будет «издать звук», то потомки в виде кошки, которая мяукает, собаки, которая гавкает, свиньи, которая хрюкает - удовлетворяют принципу.

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

anonymous
()
Ответ на: комментарий от AndreyKl

В прошлой удаленной теме он рассказывал, как планирует провести вечер с поллитрой водки внутри и интересным разговором на ЛОР. Да и до того говорил, что постил пьяным.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от anonymous

то переопределенные draw для того, чтобы удовлетворять принципу Лисков

Я на это уже ответил: ты заказчик, я исполнитель. Я тебе сдаю библиотеку виджетов, которая рисует чёрные экраны. Я выполнил ТЗ, каждый виджет «что-то рисует». Подписывай акт и гони деньги.

den73 ★★★★★
()
Ответ на: комментарий от AndreyKl

если вики не врёт конечно

Врёт. Я так понял, ты статью не осилил?

контракт можно задать как угодно, это ежу понятно. вот только нормальные люди задают контракты нормально.

Именно! Я тебе приводил пример с заказчиком и чёрным экраном. Любой нормальный контракт должен содержать слова о том, что «виджет окружность рисует окружность», а «виджет круг рисует круг». Контракт весь целиком подпадает под принцип Лисков. А ты похоже, хочешь сказать «когда я пишу документ для заказчика, то это контракт, а когда применяю принцип Лисков, то это не контракт». В статье написано: любое (выбранное не тобой) свойство, доказуемое из спецификации. Если ты начинаешь _сам_ выбирать свойства, к которым применять принцип Лисков, то тогда принцип Лисков вообще ни к чему не обязывает: можно на время его применения сделать контракт пустым. И, соответственно, нет смысла обсуждать его. И главное, твои слова о его «применении» не гарантируют надёжность работы программы. Потому что из принципа имеется следствие: можно заменить одно на другое и _никакая_ программа не сломается. В твоём случае это не так.

На каком основании ты меняешь контракт во времени? Помнится, в книжке «Несвятые святые» повествуется о том, как заменили товарища в делегации, и вместо тёти за границу поехал дядя.

На границе его тормознули и он стал говорить: «Вообще-то я Иван Иванович, но в данном списке я - Ольга Алексеевна». В итоге он проехал через границу (это был довольно крутой церковный дядя).

Пожалуйста, если тебе нравится так работать - то работай, но я не думаю, что заказчик тебе заплатит и я бы с тобой работать не стал :)

То же замечание касается и tailgunner.

Ну и да, убеждения это концентрированное знание. В моём случае.

Ты переоцениваешь свои знания.

В общем, это ваши с ним проблемы, давайте не будем тратить время :) Спасибо за беседу.

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 2)
Ответ на: комментарий от den73

Абстрактный метод - это контракт на то, что клиент сможет вызвать данный метод. Когда ты перекроешь абстрактный метод, у тебя появится контракт на то, как ты его реализовал. Реализовал окружность - значит клиенты будут ожидать окружность. Где гарантия, что на каком-то уровне иерархии потомок окружности не нарисует радужного квадратного пони? В соблюдении SOLID. Если ты перекрыл окружность таким образом, что метод начал рисовать заполненную окружность, ты нарушил контракт. Это повод задуматься, правильно ли ты выстроил иерархию классов. Возможно, тебе нужна абстрактная окружность, потомки которой будут реализовывать пустую и заполненную окружности. Возможно, тебе нужен потомок окружности с примесью fill. Возможно, тебе нужно не наследование, а делегирование.

А вообще, это все условности. На практике ведь никто не держит перед собой чек лист с пунктами SOLID, делают по интуиции. К бест практис прибегают, когда нужно обосновать проектное решение или рефакторинг имеющегося решения.

winlook38 ★★
()
Ответ на: комментарий от AndreyKl

Ну, вот это уже чуть серьезней. Тем не менее, если уж влезать в эти дебри, можно задаться вопросом: «что есть время»? Это категория «истинного бытия» или только ограниченной человеческой реальности. Скорей, второе. Поэтому, вполне.

linearisation
() автор топика
Ответ на: комментарий от winlook38

В соблюдении SOLID.

Ага, именно в соблюдении буквы L в данном случае.

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

Спасибо за поддержку :) А то когда все вокруг мне пытаются объяснить, что 2х2=5, это как-то некомфортно.

Возможно, тебе нужно не наследование, а делегирование.

Угу.

А вообще, это все условности.

Во! Именно, кто-то прочитал про SOLID, но некоторые настолько по интуиции делают, что даже не поняли, в чём состоит L.

К бест практис прибегают, когда нужно обосновать проектное решение или рефакторинг имеющегося решения.

Отличное замечание! Как Ходжа Насреддин прибегал к астрологии, когда ему нужно было обосновать то или иное решение перед султаном.

den73 ★★★★★
()
Ответ на: комментарий от winlook38

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

Только если контракт был на незаполненную окружность.

tailgunner ★★★★★
()
Ответ на: комментарий от den73

Ага, именно в соблюдении буквы L в данном случае.

Почему же, L - это всего лишь тема данного топика.

Спасибо за поддержку :) А то когда все вокруг мне пытаются объяснить, что 2х2=5, это как-то некомфортно.

А иначе я не знаю, как можно соблюсти L и S.

Как Ходжа Насреддин прибегал к астрологии, когда ему нужно было обосновать то или иное решение перед султаном.

Я не знаю, согласился ты или троллишь меня, но на практике упоминания о том или ином хорошем подходе я слышу в основном когда готовятся к рефакторингу, реже на этапе ревью. А разработчик по возможности сам придерживается хороших практик (интуитивно или сознательно).

winlook38 ★★
()
Ответ на: комментарий от tailgunner

Только если контракт был на незаполненную окружность.

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

den73 ★★★★★
()
Ответ на: комментарий от winlook38

Я согласился.

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

Почему же, L - это всего лишь тема данного топика.

Пускай, не суть.

den73 ★★★★★
()
Ответ на: комментарий от tailgunner

Только если контракт был на незаполненную окружность.

Вот тут для меня не совсем ясный момент, из-за которого, как я понимаю, возникают основные разногласия. Я понимаю, что если мы что-то реализовали и сказали (условно, тестами или еще как-то), что гарантируем такое поведение, то перекрытие будет нарушением контракта. Если мы не заявили в чем контракт, то его и нет. Но это мне и кажется странным. Я плохо представляю себе ситуацию, когда реализованное поведение не является гарантированным (получается, реализация есть, а ответственности за нее нет). Точнее представляю, но это ограниченный перечень случаев, какое-то дефолтное поведение. Если можешь, приведи примеры, когда такая реализация будет оправданной. Я могу предположить, что это ассерты, в языках, в которых нет абстрактных методов, или минимальное дефолтное поведение, которое, нас устраивает, но скорее всего будет перекрыто в потомках.

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

winlook38 ★★
()
Ответ на: комментарий от AndreyKl

Кстати, да, мы могли бы сформулировать парадокс автомобиля, именно в таком же ключе: если машина может ездить и вперед и назад, то почему она не может ездить одновременно вперед и назад. Это, пожалуй, был бы эквивалент того парадокса всемогущества, с тз логики.

linearisation
() автор топика
Ответ на: комментарий от den73

Я на это уже ответил: ты заказчик, я исполнитель. Я тебе сдаю библиотеку виджетов, которая рисует чёрные экраны. Я выполнил ТЗ, каждый виджет «что-то рисует». Подписывай акт и гони деньги.

А при чем тут ТЗ?

anonymous
()
Ответ на: комментарий от den73

Любой нормальный контракт должен содержать слова о том, что «виджет окружность рисует окружность», а «виджет круг рисует круг».

Ну так и в чем тут проблема того, что виджет круга является потомком виджета окружности? Вот у меня есть какойто виджет-окружность, контракт - нарисовать окружность (какую-то, любую), на его место приходит виджет круг, рисует круг (что является некоей окружностью), контракт выполнен, проблемы?

anonymous
()
Ответ на: комментарий от winlook38

Я понимаю, что если мы что-то реализовали и сказали (условно, тестами или еще как-то), что гарантируем такое поведение, то перекрытие будет нарушением контракта

Я правильно понял - любое перекрытие будет нарушением контракта? Если да, то почему?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

любое перекрытие будет нарушением контракта?

Расширение поведения может не нарушать контракта, согласен. Собственно, иначе, наверное, не было бы места букве O в SOLID.

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

winlook38 ★★
()
Ответ на: комментарий от den73

Врёт. Я так понял, ты статью не осилил?

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

AndreyKl ★★★★★
()
Ответ на: комментарий от linearisation

хороший пример, есть над чем подумать.

и всё таки (чёрт тебя дери анонимус):

Тут такая штука: камень, который бог не может поднять, может существовать или нет?
Если уж бог его может создать, то камень однозначно может существовать. И если создан и существует, то пока он существует/существовал, могущество бога ограничено. Что как бы противоречит идеи всемогущести.

Елси же такого камня не может существовать, то это только в том случае если бог не смог его создать. Что тоже противоречит идее всемогущества бога.

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 1)
Ответ на: комментарий от AndreyKl

Современные люди, употребляя слово «имеет значение», всегда забывают подумать «для кого имеет». Одна и та же вещь имеет значение для одного, но не имеет для другого. Какое может иметь, скажем, значение время, для властителя и творца времени? Рассуждения в безаппеляционной форме, в форме «истины в последней инстанции» обречены на провал, люди, рассуждающие подобным образом обречены на то, что они рано или поздно запутаются в 2-х соснах. Это особенно характерно для матлогики, где есть какая то «истина», и какая-то «ложь», причем, в какой-то «абсолютной» порнографической форме.

linearisation
() автор топика
Ответ на: комментарий от AndreyKl

может существовать или нет?

Да, я сказал выше, что, на мой взгляд, может.

Что как бы противоречит идеи всемогущести.

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

Ты можешь переформулировать этот парадокс так: может ли Всемогущий создать камень, котрый он одновременно может и не может поднять?

Парадокс это или глупость, все-таки?

linearisation
() автор топика
Ответ на: комментарий от AndreyKl

Кстати, и парадокс лжеца, собственно, есть ни что иное как глупость, по сути(а туда же и Геделевские теоремы). Если мы определяем Лжеца, то его фраза «я лгу» является невозможной, так как лжец не может сказать правду, если мы определяем его как «идеального лжеца»(а другого рассматривать бессмысленно), исходя из того, что он всегда лжет(по-определению), говоря о том что он лжет, нарушает «контракты лжеца». Противоречивое определение не может дать ничего удобоваримого на выходе. Как если бы ты сказал: глухонемой говорит, например. Есть ли тут противоречие, lol. Вместо того, чтобы остановится тут, логики передергивают, и начинают сами себе трахать мозг. Само определение парадоксов парадоксально по-сути.

linearisation
() автор топика
Ответ на: комментарий от linearisation

Ты матлогику-то поучи на досуге. Истина и ложь там в самой что ни на есть относительной форме из возможных.

alpha ★★★★★
()
Ответ на: комментарий от linearisation

Если мы определяем Лжеца, то его фраза «я лгу» является невозможной, так как лжец не может сказать правду, если мы определяем его как «идеального лжеца»(а другого рассматривать бессмысленно), исходя из того, что он всегда лжет(по-определению), говоря о том что он лжет, нарушает «контракты лжеца». Противоречивое определение не может дать ничего удобоваримого на выходе.

И это рассуждение и называется «парадокс лжеца»...

alpha ★★★★★
()
Ответ на: комментарий от alpha

да что ты говоришь, маленький. Может ли математическая истина быть ложью? true == false — это корректное с тз математики выражение?

То то я и гляжу, почему это они на свое «божество» — непротиворечивость никогда не дрочат

linearisation
() автор топика
Ответ на: комментарий от alpha

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

linearisation
() автор топика
Ответ на: комментарий от AndreyKl

Еще можешь так подойти к вопросу: может ли некий «всемогущий» сделать невозможное? Вот это и будет разрешение парадокса.

Соль в том, что если ты определяешь «всемогущего» как того, для кого нет невозможного, значит он может все, а абсолютно невозможное — невозможно. Значит он может создать камень, который сам не сможет поднять, и поднять камень, который сам не может поднять. Парадокс заключается уже в формулировке парадокса. Либо твой всемогущий — не всемогущ, либо невозможное — возможно. А гниение мозга начинается именно с того момента, когда ты формулируешь это таким образом, что подразумеваются взаимопротиворечащие вещи : и всемогущий всемогущ и невозможное (камень, который кто-либо может и поднять и не поднять одновременно) — невозможно.

linearisation
() автор топика
Ответ на: комментарий от AndreyKl

Вот так вот обобщим:

Либо есть всемогущий и нет [абсолютно] невозможного(невозможного ни для кого), либо есть [абсолютно] невозможное, но нет всемогущего (для которого нет невозможного), но не оба сразу.

Таким образом, «красивый» парадокс легким движением руки превращается в банальный оксюморон, типа, «сладкая горечь». Подозреваю, что вообще любой парадокс является оксюмороном. Есть ли тут над чем задумываться?

linearisation
() автор топика
Ответ на: комментарий от linearisation

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

Вообще-то нет. Из того что предположение о том что лжец сказал «я лгу»" приводит на любой интерпретации к противоречию, как раз и следует,что лжец сказать этой фразы не может. Все. И никто никому ничего не трахает.

И аналогично с теоремой геделя - именно так она и доказываетс.

anonymous
()
Ответ на: комментарий от AndreyKl

Задавать такие вопросы на ЛОР'е, ещё и в разделе по программированию. Это ли не дурдом?

LupusAlbus
()
Ответ на: комментарий от anonymous

противоречие заложено в определение этого парадокса. Нет нужды ничего доказывать, это изначально противоречивое высказывание.

linearisation
() автор топика
Ответ на: комментарий от anonymous

парадокс лжеца можно редуцировать до: «неспособный говорить правду говорит правду»

linearisation
() автор топика
Ответ на: комментарий от linearisation

нет, я не забыл о времени. этот вопрос не имеет отношения ко времени. ведь я взял предикат «может». Т.е. это в безвременье. Либо может впринципе, либо не может впринципе. Если камень, который бог поднять не может, существовать может впринципе , то это ограничивает могущество бога, впринципе. Если ты перейдёшь в категорию времени, то значит что бог будет ограничен некоторое, пусть и очень малое время. А это невозможно для всемогущего существа.

AndreyKl ★★★★★
()
Ответ на: комментарий от linearisation

Ты можешь переформулировать этот парадокс так: может ли Всемогущий создать камень, котрый он одновременно может и не может поднять?

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

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 1)
Ответ на: комментарий от linearisation

Либо твой всемогущий — не всемогущ, либо невозможное — возможно.

именно.

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

чёрта с два гниение. просто определение говно. либо невозможного, либо всемогущего.

AndreyKl ★★★★★
()
Ответ на: комментарий от AndreyKl

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

Все же, если отделять чистую логику от эвристики (типа, мы знаем из опыта, что этого не бывает), то само по себе понятие «всемогущество» не противоречиво без того, что мы предполагаем, что нет никого, кто мог бы сделать невозможное, или что абсолютно невозможное(невозможное ни для кого, например) существует. Тут все зависит от аксиматики.

***************

Если мы исходим из допущения, что __есть__ нечто, абсолютно невозможное, то это автоматически исключает то, что существует всемогущий.

***************

В формулировке данного парадокса слишком много буков.

linearisation
() автор топика
Ответ на: комментарий от linearisation

Гм.

Ты прав, противоречие тут простое: может ли всемогущий сделать невозможное.

Это из той же оперы что и «может ли всепробивающее ядро пробить ничем не пробиваемую стену» и прочих подобных вещей.

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

Спасибо за беседу.

AndreyKl ★★★★★
()

В общем я понял, что подкласс, вообще говоря - не подтип. Т.е. в стандарте CL ошибка, а в С++ и Яве отношение «являться» некорректно терминологически, хотя логической ошибки в самом языке нет. И вообще, подтип - это понятие «логическое». С физической точки зрения нет отношения подтип, а есть просто «тип», т.е. способ размещения в памяти и идентификации объекта.

Т.е. в нормальном объектном языке программирования должны различаться понятие «подтип», которое служит основой для отношения «являться», и понятие «наследник», которое служит для полиморфизма наследников класса и которое в реальности чаще встречается.

Я это раньше выражал в том, что требовал наличия понятия «только конкретно этот класс, не считая потомков», но в реальности тут появляется больше понятий:

  • «этот тип (логически)» - здесь подходит и любой подтип в смысле Лисков
  • «этот тип (физически), в точности» - здесь мы ждём ровно нужный нам тег типа
  • «этот класс или его наследники (физически)» - для работы с виртуальными функциями и полями, которые случайно оказались на том же месте в С++ из-за наследования.
  • «этот класс или его наследники (логически)» - для языков, у которых более сложно устроены классы и поэтому мы не можем рассчитывать на ту же оптимизацию за счёт совместимости расположения полей, что в С++. В C++ в этот случай можно условно поместить множественное наследование.

Если иерархия удовлетворяет принципу Лисков, то подкласс становится подтипом. В идеальном ООП языке это понимает компилятор.

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.