Обновить
14
0

Пользователь

Отправить сообщение
Ну, а что делать? Да, это учебный пример, и да, это явный 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 действительно не нужен. Опечатку поправил.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность