Liskov substitution principle говорит о типах, которые наследуют друг от друга. Как насчет ситуации, когда типы не связаны наследованием, но выполняют похожие функции, например массивы и списки в .NET? Для такой ситуации тоже полезно сделать интерфейс этих классов максимально близким, чтобы можно было заменить один на другой с минимумом гемора.
Для этого принципа есть какое-то формальное название?
Здравствуйте, Codealot, Вы писали:
C>Liskov substitution principle говорит о типах, которые наследуют друг от друга. Как насчет ситуации, когда типы не связаны наследованием, но выполняют похожие функции, например массивы и списки в .NET? Для такой ситуации тоже полезно сделать интерфейс этих классов максимально близким, чтобы можно было заменить один на другой с минимумом гемора.
Если мне склероз не изменяет, для этой цели придуман IEnumerable.
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, Codealot, Вы писали:
SVZ>>Если мне склероз не изменяет, для этой цели придуман IEnumerable.
C>Будет очень эффективно, если ты попытаешься сделать через него Reverse
Он для этого и не предназначен.
Ты же не пытаешься обращаться к элементам списка по индексу?
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, Codealot, Вы писали:
C>Нет. Если названия и сигнатуры методов в похожих типах не совпадают, то никакой duck typing не сработает.
Ну должен же компилятор как-то догадаться, что некие два метода по сути своей одинаковые. Duck typing предлагает конкретный, весьма простой, механизм, как ему это объяснить.
Здравствуйте, Pzz, Вы писали:
Pzz>Ну должен же компилятор как-то догадаться, что некие два метода по сути своей одинаковые. Duck typing предлагает конкретный, весьма простой, механизм, как ему это объяснить.
Чтобы он догадался, у них должна быть сделана одинаковая сигнатура. И вот именно про это и был мой вопрос, а не про то, что происходит после.
Здравствуйте, Muxa, Вы писали:
M>Дык ты обозначь что за похожие функции, выполняемые списком и массивом ты имеешь в виду. Хранение более чем одного элемента чтоли?
Как я уже писал — Reverse, в качестве примера.
Работает одинаково для обоих коллекций. Значит, и сигнатура у методов должна быть максимально одинаковой, чтобы можно было легко заменить в коде один класс на другой. Вопрос — у этой идеи есть какое-нибудь умное название, чтобы вдолбить в голову тех, кто не понимает зачем это нужно?
C>Как я уже писал — Reverse, в качестве примера. C>Работает одинаково для обоих коллекций. Значит, и сигнатура у методов должна быть максимально одинаковой, чтобы можно было легко заменить в коде один класс на другой. Вопрос — у этой идеи есть какое-нибудь умное название, чтобы вдолбить в голову тех, кто не понимает зачем это нужно?
Здравствуйте, Codealot, Вы писали:
Pzz>>Ну должен же компилятор как-то догадаться, что некие два метода по сути своей одинаковые. Duck typing предлагает конкретный, весьма простой, механизм, как ему это объяснить.
C>Чтобы он догадался, у них должна быть сделана одинаковая сигнатура. И вот именно про это и был мой вопрос, а не про то, что происходит после.
Ну вот, сведение типов по сигнатурам методов и называется duck typing.
Здравствуйте, Codealot, Вы писали:
C>Liskov substitution principle говорит о типах, которые наследуют друг от друга. Как насчет ситуации, когда типы не связаны наследованием, но выполняют похожие функции, например массивы и списки в .NET? Для такой ситуации тоже полезно сделать интерфейс этих классов максимально близким, чтобы можно было заменить один на другой с минимумом гемора. C>Для этого принципа есть какое-то формальное название?
Здравствуйте, Codealot, Вы писали:
C>Для этого принципа есть какое-то формальное название?
interface segregation principle вполне достаточно. Вкупе с такой фичей как Intersection Types, чтоб не городить новых интерфейсов которые являются
комбинацией более мелких.
Здравствуйте, Codealot, Вы писали:
C>Здравствуйте, omgOnoz, Вы писали:
O>>сабж?
C>Нет. Если названия и сигнатуры методов в похожих типах не совпадают, то никакой duck typing не сработает.
А кто тебе сказал, что они НЕ СОВПАДАЮТ?? Duck принцип про то и говорит — если ты можешь это "открыть", "записать" и "закрыть", значит это ФАЙЛ! Независимо от объекта. Значит вызовы априори идентичны.
Здравствуйте, Codealot, Вы писали:
C>Liskov substitution principle говорит о типах, которые наследуют друг от друга. Как насчет ситуации, когда типы не связаны наследованием, но выполняют похожие функции, например массивы и списки в .NET? Для такой ситуации тоже полезно сделать интерфейс этих классов максимально близким, чтобы можно было заменить один на другой с минимумом гемора. C>Для этого принципа есть какое-то формальное название?
Структурный полиморфизм или статическая утиная типизация. Примеры можно посмотреть в интерфейсах go и в питоновских протоколах. Если же вопрос касается только .net, то в C# в явном виде такого нет, но массивы и списки реализуют IList<T>.
Здравствуйте, Kolesiki, Вы писали:
K>А кто тебе сказал, что они НЕ СОВПАДАЮТ??
А вот потому что кто-то сделал так, что они не совпадают.
duck typing — это система типизации, а не принципы проектирования классов. А мой вопрос — про принципы проектирования классов.
Здравствуйте, Codealot, Вы писали:
C>Liskov substitution principle говорит о типах, которые наследуют друг от друга. Как насчет ситуации, когда типы не связаны наследованием, но выполняют похожие функции, например массивы и списки в .NET? Для такой ситуации тоже полезно сделать интерфейс этих классов максимально близким, чтобы можно было заменить один на другой с минимумом гемора. C>Для этого принципа есть какое-то формальное название?
Здравствуйте, Codealot, Вы писали:
C>А вот потому что кто-то сделал так, что они не совпадают. C>duck typing — это система типизации, а не принципы проектирования классов. А мой вопрос — про принципы проектирования классов.
Система типизации и принципы проектирования классов это разные стороны одного явления.
Если мы закладываемся на duck typing, то наши родственные сущности должны иметь одинаковый дизайн
1. одна и та же операция должна в разнх классах иметь одно и то же имя, совместимые параметры и выхлоп
2. один и тот же набор операций
3. одна и та же структура апи
4. п1 ... п3 распространяется на связанное с этим классом апи
Например, если у нас есть операция "получить сведения" у разных классов, принимает время от, время до, фильр, и тд.
п1 Тогда во всех этих классов операция имеет одно и то же имя, совместимый список параметров, включая особенности параметра фильтра.
Скажем, будет странно, если у одного класса эта операция принимает фильтр строку, а в другом — лямбду, а в третьем — экземпрял класса
п2,п3. например, у нас есть способ тащить данные целиком, частями, через объект ридер begin...end, — все родственные классы должны поддерживать этот набор операций
п4 если экземпляр класс мы можем передать куда нибудь, скажем, в рендерер, то очевидено и рендерер должен использовать этот самый duck typing. И тогда для нескольких вариантов рендерера мы будем закладываться на те же самые принципы.
То есть, duck typing как система типизации есть в чистом виде принцип проектирования классов.
Здравствуйте, Ikemefula, Вы писали:
I>Система типизации и принципы проектирования классов это разные стороны одного явления.
В данном случае, вообще ортогонально. Если у тебя статическая система типов и ты выделяешь явный интерфейс или базовый класс, то матчить сигнатуры методов тоже нужно. Казалось бы, при чем тут duck typing? А вообще ни при чем.
Здравствуйте, Codealot, Вы писали:
I>>Система типизации и принципы проектирования классов это разные стороны одного явления.
C>В данном случае, вообще ортогонально. Если у тебя статическая система типов и ты выделяешь явный интерфейс или базовый класс, то матчить сигнатуры методов тоже нужно. Казалось бы, при чем тут duck typing? А вообще ни при чем.
Слово "тоже" означает что есть минимум две стороны. При этом статическая типизация есть инструмент проектирования — способ обеспечить расширенную поддержку со стороны компилятора-иде-анализаторов и тд.
Соответсвенно и duck typing есть вполне конкретные принципы проектирования. Его можно комбинировать как с динамической типизацией, так и со статической.
Здравствуйте, Ikemefula, Вы писали:
I>Соответсвенно и duck typing есть вполне конкретные принципы проектирования. Его можно комбинировать как с динамической типизацией, так и со статической.
Duck typing is a concept related to dynamic typing
Просто по определению.
Здравствуйте, Codealot, Вы писали:
I>>Соответсвенно и duck typing есть вполне конкретные принципы проектирования. Его можно комбинировать как с динамической типизацией, так и со статической.
C>Duck typing is a concept related to dynamic typing C>Просто по определению.
"related" это никакое не определение При этом, как ни крути, а любой typing это еще и принцип проектирования типов-классов-операций-компонентов-итд.
Здравствуйте, Codealot, Вы писали:
C>Duck typing is a concept related to dynamic typing C>Просто по определению.
Смотри, в шарпе есть duck typing с самых первых версий. Когда ты создаешь экземпляр делегата на конкретный метод, там именно оно — требуется только совпадение сигнатуры. Это делает делегаты dynamic typing?
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Смотри, в шарпе есть duck typing с самых первых версий. Когда ты создаешь экземпляр делегата на конкретный метод, там именно оно — требуется только совпадение сигнатуры. Это делает делегаты dynamic typing?
Нет. О чем я и говорю.
Вообще, эта концепция с вооот такой бородой еще задолго до появления идеи утиной типизации.