И снова про equals и LSP
От: Курилка Россия http://kirya.narod.ru/
Дата: 18.04.07 18:13
Оценка: 1 (1) +1
Тут как-то пару месяцев обсуждали этот метод у Object из .Net в рамках наследования. Нашёл интересную статью по этому поводу (правда там Ява, но ничего это не меняет). Там высказывается вполне корректная на мой взгляд точка зрения: equals не должен быть методом объекта, иначе он будет не симметричным, что ведёт к логическим ошибкам.
Re: И снова про equals и LSP
От: ZevS  
Дата: 20.04.07 08:13
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Тут как-то пару месяцев обсуждали этот метод у Object из .Net в рамках наследования. Нашёл интересную статью по этому поводу (правда там Ява, но ничего это не меняет). Там высказывается вполне корректная на мой взгляд точка зрения: equals не должен быть методом объекта, иначе он будет не симметричным, что ведёт к логическим ошибкам.


Ну не зря же этот метод виртуальный?
Re[2]: И снова про equals и LSP
От: Курилка Россия http://kirya.narod.ru/
Дата: 20.04.07 08:18
Оценка:
Здравствуйте, ZevS, Вы писали:

ZS>Здравствуйте, Курилка, Вы писали:


К>>Тут как-то пару месяцев обсуждали этот метод у Object из .Net в рамках наследования. Нашёл интересную статью по этому поводу (правда там Ява, но ничего это не меняет). Там высказывается вполне корректная на мой взгляд точка зрения: equals не должен быть методом объекта, иначе он будет не симметричным, что ведёт к логическим ошибкам.


ZS>Ну не зря же этот метод виртуальный?


Если подходить с т.зр. логики — зря.
Практически в угоду ООП извратили суть отношения равенства, а ёжики "плевались, но лезли на кактус"
Правда с практической т.зр. проблема не такая уж страшная.
Re[3]: И снова про equals и LSP
От: ZevS  
Дата: 20.04.07 09:14
Оценка:
Здравствуйте, Курилка, Вы писали:

...

ZS>>Ну не зря же этот метод виртуальный?


К>Если подходить с т.зр. логики — зря.

К>Практически в угоду ООП извратили суть отношения равенства, а ёжики "плевались, но лезли на кактус"
К>Правда с практической т.зр. проблема не такая уж страшная.

Использование классовых методов, реализованных через экземплярные спасет мир.

class Object
...
public static bool Equals(object objA, object objB)
{
    if (objA == objB)
    {
        return true;
    }
    if ((objA != null) && (objB != null))
    {
        return objA.Equals(objB);
    }
    return false;
}
Re[4]: И снова про equals и LSP
От: Курилка Россия http://kirya.narod.ru/
Дата: 20.04.07 09:20
Оценка:
Здравствуйте, ZevS, Вы писали:

ZS>Здравствуйте, Курилка, Вы писали:


ZS>...


ZS>>>Ну не зря же этот метод виртуальный?


К>>Если подходить с т.зр. логики — зря.

К>>Практически в угоду ООП извратили суть отношения равенства, а ёжики "плевались, но лезли на кактус"
К>>Правда с практической т.зр. проблема не такая уж страшная.

ZS>Использование классовых методов, реализованных через экземплярные спасет мир.


Классовые — это статические типа чтоль?
Чем твоя схема отличается от objA.equals(objB), которая несимметрична?
Доп. проверки на равенство экземпляров и null роли тут не играют
Re[5]: И снова про equals и LSP
От: ZevS  
Дата: 20.04.07 09:39
Оценка:
Здравствуйте, Курилка, Вы писали:

..

ZS>>Использование классовых методов, реализованных через экземплярные спасет мир.


К>Классовые — это статические типа чтоль?

К>Чем твоя схема отличается от objA.equals(objB), которая несимметрична?
К>Доп. проверки на равенство экземпляров и null роли тут не играют

Ну, я обычно сравниваю объекты на равенство статическим методом базового класса. И мне не важен тип объекта, часто я его и не знаю. По-моему, удобно. Пусть и извращение.
Re[6]: И снова про equals и LSP
От: Курилка Россия http://kirya.narod.ru/
Дата: 20.04.07 09:45
Оценка:
Здравствуйте, ZevS, Вы писали:

ZS>Здравствуйте, Курилка, Вы писали:


ZS>..


ZS>>>Использование классовых методов, реализованных через экземплярные спасет мир.


К>>Классовые — это статические типа чтоль?

К>>Чем твоя схема отличается от objA.equals(objB), которая несимметрична?
К>>Доп. проверки на равенство экземпляров и null роли тут не играют

ZS>Ну, я обычно сравниваю объекты на равенство статическим методом базового класса. И мне не важен тип объекта, часто я его и не знаю. По-моему, удобно. Пусть и извращение.


Ну почему извращение, это как раз по сути логически более правильный способ.
Просто проблема с перегрузкой оператора, которая-то и делает его несимметричным. Если же один метод в базовом классе, который ещё и final, то это почти идентично выносу его из класса.
Re[7]: И снова про equals и LSP
От: ZevS  
Дата: 20.04.07 15:04
Оценка:
Здравствуйте, Курилка, Вы писали:

..

ZS>>Ну, я обычно сравниваю объекты на равенство статическим методом базового класса. И мне не важен тип объекта, часто я его и не знаю. По-моему, удобно. Пусть и извращение.


К>Ну почему извращение, это как раз по сути логически более правильный способ.


Вот и получается, что виртуальный метод Equal необходим.

К>Просто проблема с перегрузкой оператора, которая-то и делает его несимметричным. Если же один метод в базовом классе, который ещё и final, то это почти идентично выносу его из класса.
Re[8]: И снова про equals и LSP
От: Курилка Россия http://kirya.narod.ru/
Дата: 20.04.07 16:18
Оценка:
Здравствуйте, ZevS, Вы писали:

ZS>Здравствуйте, Курилка, Вы писали:


ZS>..


ZS>>>Ну, я обычно сравниваю объекты на равенство статическим методом базового класса. И мне не важен тип объекта, часто я его и не знаю. По-моему, удобно. Пусть и извращение.


К>>Ну почему извращение, это как раз по сути логически более правильный способ.


ZS>Вот и получается, что виртуальный метод Equal необходим.


Откуда получается-то?
Проблема в том, что это в базовый класс запёхано, поэтому приходиться находить обходные пути.
Скажи, зачем тебе реально тут виртуальность нужна?
ObjectA.Equals(a,b) даже визуально гораздо "чище", чем a.equals(b)
Re[9]: И снова про equals и LSP
От: ZevS  
Дата: 20.04.07 18:07
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Здравствуйте, ZevS, Вы писали:


ZS>>Здравствуйте, Курилка, Вы писали:


ZS>>..


ZS>>>>Ну, я обычно сравниваю объекты на равенство статическим методом базового класса. И мне не важен тип объекта, часто я его и не знаю. По-моему, удобно. Пусть и извращение.


К>>>Ну почему извращение, это как раз по сути логически более правильный способ.


ZS>>Вот и получается, что виртуальный метод Equal необходим.


К>Откуда получается-то?

К>Проблема в том, что это в базовый класс запёхано, поэтому приходиться находить обходные пути.
К>Скажи, зачем тебе реально тут виртуальность нужна?
К>ObjectA.Equals(a,b) даже визуально гораздо "чище", чем a.equals(b)

А если a и b на самом деле являются экземплярами наследника ObjectA?
Re[10]: И снова про equals и LSP
От: Курилка Россия http://kirya.narod.ru/
Дата: 20.04.07 18:10
Оценка:
Здравствуйте, ZevS, Вы писали:

ZS>Здравствуйте, Курилка, Вы писали:


К>>Проблема в том, что это в базовый класс запёхано, поэтому приходиться находить обходные пути.

К>>Скажи, зачем тебе реально тут виртуальность нужна?
К>>ObjectA.Equals(a,b) даже визуально гораздо "чище", чем a.equals(b)

ZS>А если a и b на самом деле являются экземплярами наследника ObjectA?


Если
Ну а даже и если, и если один ObjectA1, другой ObjectA2, плюс в обоих метод переопределён, получаем веселуху
Re[11]: И снова про equals и LSP
От: ZevS  
Дата: 20.04.07 19:32
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Здравствуйте, ZevS, Вы писали:


ZS>>Здравствуйте, Курилка, Вы писали:


К>>>Проблема в том, что это в базовый класс запёхано, поэтому приходиться находить обходные пути.

К>>>Скажи, зачем тебе реально тут виртуальность нужна?
К>>>ObjectA.Equals(a,b) даже визуально гораздо "чище", чем a.equals(b)

ZS>>А если a и b на самом деле являются экземплярами наследника ObjectA?


К>Если

К>Ну а даже и если, и если один ObjectA1, другой ObjectA2, плюс в обоих метод переопределён, получаем веселуху

Ну это — по желанию. Можно и статический метод идиотски закодировать.
Re[12]: И снова про equals и LSP
От: Курилка Россия http://kirya.narod.ru/
Дата: 20.04.07 20:13
Оценка:
Здравствуйте, ZevS, Вы писали:

ZS>Здравствуйте, Курилка, Вы писали:


К>>Здравствуйте, ZevS, Вы писали:


ZS>>>Здравствуйте, Курилка, Вы писали:


К>>>>Проблема в том, что это в базовый класс запёхано, поэтому приходиться находить обходные пути.

К>>>>Скажи, зачем тебе реально тут виртуальность нужна?
К>>>>ObjectA.Equals(a,b) даже визуально гораздо "чище", чем a.equals(b)

ZS>>>А если a и b на самом деле являются экземплярами наследника ObjectA?


К>>Если

К>>Ну а даже и если, и если один ObjectA1, другой ObjectA2, плюс в обоих метод переопределён, получаем веселуху

ZS>Ну это — по желанию. Можно и статический метод идиотски закодировать.


Ну ты серьёзно чтоль не улавливаешь разницу? Или тебе надо рассказывать, что статический определён на этапе компиляции, а виртуальный нет?
Re[13]: И снова про equals и LSP
От: ZevS  
Дата: 21.04.07 05:27
Оценка:
Здравствуйте, Курилка, Вы писали:

...

ZS>>Ну это — по желанию. Можно и статический метод идиотски закодировать.


К>Ну ты серьёзно чтоль не улавливаешь разницу? Или тебе надо рассказывать, что статический определён на этапе компиляции, а виртуальный нет?


А собственно Equal то тут при чем?
То что виртульные мотоды определяются через vtm — фича.
Re: И снова про equals и LSP
От: lxa http://aliakseis.livejournal.com
Дата: 21.04.07 07:25
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Тут как-то пару месяцев обсуждали этот метод у Object из .Net в рамках наследования...

Кое-что по теме здесь и здесь.
Re[14]: И снова про equals и LSP
От: Курилка Россия http://kirya.narod.ru/
Дата: 21.04.07 08:17
Оценка:
Здравствуйте, ZevS, Вы писали:

ZS>Здравствуйте, Курилка, Вы писали:


ZS>...


ZS>>>Ну это — по желанию. Можно и статический метод идиотски закодировать.


К>>Ну ты серьёзно чтоль не улавливаешь разницу? Или тебе надо рассказывать, что статический определён на этапе компиляции, а виртуальный нет?


ZS>А собственно Equal то тут при чем?

блин, я думал ты поймёшь, что он статический
ZS>То что виртульные мотоды определяются через vtm — фича.
попробуй понять статью, надоело уже повторять, если честно
Re[2]: И снова про equals и LSP
От: Курилка Россия http://kirya.narod.ru/
Дата: 21.04.07 08:23
Оценка:
Здравствуйте, lxa, Вы писали:

lxa>Здравствуйте, Курилка, Вы писали:


К>>Тут как-то пару месяцев обсуждали этот метод у Object из .Net в рамках наследования...

lxa>Кое-что по теме здесь и здесь.

Сильно не вчитывался, как говорят "много букав"
Только вот всё это похоже на шаманские танцы вокруг грабель.
Вынос в статический метод сделал бы ситуацию много понятней и проще.
Re[12]: И снова про equals и LSP
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.04.07 17:34
Оценка:
Ребяты, вы не офигели так оверквотить?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: И снова про equals и LSP
От: vdimas Россия  
Дата: 23.04.07 21:04
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Тут как-то пару месяцев обсуждали этот метод у Object из .Net в рамках наследования. Нашёл интересную статью по этому поводу (правда там Ява, но ничего это не меняет). Там высказывается вполне корректная на мой взгляд точка зрения: equals не должен быть методом объекта, иначе он будет не симметричным, что ведёт к логическим ошибкам.


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

А во-вторых, у тебе есть требуемая возможность — определяй себе на здоровье static bool operator==(T a, T b) {...}

-----
А фатанатичное стремление соблюдать LSP вообще не понимаю. Согласен лишь с тем, что несоблюдение принципа может привести к популярным ошибкам проетиктирования (наиболее популярная — неоправданное увеличение связанности и последующая трудность независимого развития частей системы), однако его строгое соблюдение так же может спровоцировать лишние телодвижения на ровном месте. ИМХО, зачастую принадлежность некоей классификации удобней устанавливать напрямую через аттрибуты состояния (виртуальные), чем через сетку двойных диспечеризаций и прочих "посетителей".

Простой пример, предположим есть поток, у потока есть метод "Seek(args)", и парный аттрибут "bool CanSeek". Яркий пример нарушения LSP, тем не менее крайне удобный для использования, позволяющий одним if-ом выбрать наиболее подходящий способ работы с потоком.

Так что если нарушение LSP в конкретных случаях не добавляет связанности, но упрощает представление алгоритмов, то почему бы и нет? В обсуждаемом Equals(arg) мы обычно приводим к тому типу, коим являемся, т.е. связанность увеличиться никак не может, наоборот, может резко снизиться, за счёт использования методов уровня базового фреймворка.
Re[2]: И снова про equals и LSP
От: EvilChild Ниоткуда  
Дата: 24.04.07 19:02
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Простой пример, предположим есть поток, у потока есть метод "Seek(args)", и парный аттрибут "bool CanSeek". Яркий пример нарушения LSP, тем не менее крайне удобный для использования, позволяющий одним if-ом выбрать наиболее подходящий способ работы с потоком.


А где он тут нарушается?
now playing: DJ Krust — How To Mutate
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.