All streams
Search
Write a publication
Pull to refresh
14
0
Send message
Ну, а что делать? Да, это учебный пример, и да, это явный overdesign. На лекции не развернуть реально сложный пример, где рефакторинг ведёт к заметному упрощению.
Да, согласен. Народ уже советовал yield return. Думаю, это вполне можно сделать следующим шагом преобразований.
Да, но как иначе? Это именно учебный пример, потом приходится принять условности — мы явно будем делать больше необходимого. Невозможно на лекции развернуть и показать сложный проект, в котором рефакторинг и в самом деле применим. Или возможно — но я не знаю как.
Позвольте, влезу в обсуждение. Я согласен с вами, что часто ФП может в несколько раз сократить код, сделать его и куда как более читаемым (при намётанном глазе), и исключить многие ошибки. Но отбросить ООП как таковое — слишком решительный шаг. Господствуют на рынке именно ООП-языки, и даже на продвинутом C# сложновато писать функционально. Есть ещё, конечно, Scala, но так ли много людей на ней пишут?
Так вот, статья посвящена была введению именно в ООП. Не вижу, как рассказывать его одновременно с ФП.
Да, согласен — уже многие отметили, что условный yield return подошёл бы лучше.
Я думаю сделать этот ход следующим шагом.
О, это более чем возможно. Переверните её обратно, в таком случае — я готов вас выслушать.
О, здорово, посмотрю.
Прошу прощения, но вы неправы. Если перед нами стоит задача выводить числа в режиме их получения, мы должны её реализовать. Можно рассматривать более сложные варианты — скажем, вызывать событие, когда число найдено. Или возвращать IEnuerable с отложенным вычислением в стиле Хаскеля.
SRP мы нарушаем, когда смешиваем разную логику в одном классе. Здесь же мы — фактически — пришли к тому, что делаем шаг алгоритма, а потом передаём управление кому-то, чтобы там что-то сделали с нашим найденным числом. Логика содержится в этом ком-то. Так что нет, не нарушается SRP.

Но, повторю, согласен с тем, что лучше бы тут вызывать событие.
А если определить, кроме generic только два метода с такой сигнатурой (icell, red-cell) и (red-cell, icell), а потом вызвать с двумя красными, то какой вызовется метод?
Было дерево, где элементы — узлы. Наружу выставлены потомки списком и только. А в значении своя логика, вот с ней и нужно было разбираться.
Ну, да. Кто бы спорил, что функциональные языке с такой задачкой на раз справляются. Но за пример спасибо, хороший!
Тут мне остаётся вам поверить — я не так хорошо знаю F#. Или, может, вы пример приведёте? Любопытно разобраться.
А, ну тут иначе не совладать с задачей. И я бы даже не сказал, что это так уж плохо. Да, мне придётся менять вспомогательные классы, но, меняя их, я хотя бы задумаюсь, какими именно правилами должны пользоваться все мои конкретные обработчики для жёлтой клетки.
Раз речь зашла о F# — что будет если мы добавим новый тип в unit? Нам придётся обновить все использования его и указать, что делать функции в случае жёлтой клетки. И так ли это плохо?
Вам спасибо отзыв!
Не было цели доказать, что C# — самый выразительный язык. На F# match действительно куда проще решил бы эту задачу, ну так там и наследования не приветствуется, а вместо него Union.
Я хотел скорее показать, то такая задача на C# в принципе разрешима при условии, что мы не создаём (N + const) классов. Для меня, по крайней мере, это было не очевидно.

Про SOLID вы что именно имеете в виду? Что я смешал строителя и посетителя, или что-то другое?
Понял теперь вашу идею. Смотрите, вы всё равно не уходите от динамического приведения типов. Например, если я прошу вас вывести не «красное на красном», а что-нибудь из открытых свойств ячейки, вам всё равно придётся приводить тип. А если так, то наша беседа сводится к другому вопросу: что лучше — обычный посетитель или перебор типов через switch? Убийственного аргумента в пользу первого у меня нет. Но, например, если добавляем новый элемент, а использована динамическая типизация, уже куда сложнее найти все места, которые нужно обновить, чтобы поддержать его (предполагаем, что таких switch'ей у нас довольно много), легче что-то пропустить и получить потом runtime exception.
В нашем случае, когда обработка по умолчанию задана исключений не будет, но мы получим какой-то общий объект вместо интересующего нас частного случая. Узнаем об этом тоже, скорее всего, в runtime.

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

Обобщая вышесказанное: 1) при явном приведении типов больше вероятности получить ошибку на этапе исполнения 2) мне было интересно решить задачу без явного приведения типов, что тоже немаловажно.
А как иначе вы её предлагаете решать, если отмести варианты с динамическим приведением типов?
А! Точно. Внимательно читаете — спасибо. Сперва у меня как раз был цвет в интерфейсе, а добыть нужно было, скажем, целое число, которым обладала только красная ячейка. На идее решения эта оплошность никак не скажется, но нужно подумать, как лучше поправить статью.
Что нам нужно в методе Do? Знать цвет первой и второй ячейки, причём обе им обладают независимо друг от друга. Значит, нам нужен простой («классический») визитёр, который цвет добудет.
Вы всё правильно поняли, Color в ICell действительно не нужен. Опечатку поправил.

Information

Rating
Does not participate
Registered
Activity