Обновить
13
Денис Щетинин@chaetal

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

4
Подписчики
Отправить сообщение

При попытке продолжить сразу вылезет эта самая инкапсуляция

А вот у меня, знаете, ли никакая "инкапсуляции" ни откуда не вылезает.

Нет, мимо этого и других матных мейнстримовых слов, конечно, не пройти. Но только потому, что их на всех заборах понаписали. Приходится объяснять, что это неадекватные, не отражающие и искажающие смысл исходной идеи слова. Эти слова по какой-то причине были подобранны людьми, которые сами не поняли смысл, но решили донести его до масс. И (вряд ли случайно — тут, очевидно, есть какая-то нехорошая закономерность) таки донесли. По пути и в результате свели к околонулевой вероятности шанс понять эту самую исходную идею без сверхуслий.

Ну, а дальше

…А дальше, чувствую, дискутировать не будет смысла.

У вас уже выстроена некоторая система — трактовка ООП. Она не соответствует исходному замыслу ООП. В ней виден целый ряд несостыковок. Эти несостыковки постоянно вылезают на практике (в данном случае я про себя) и дают повод для критики такого "ООП"… Но, как показывает опыт, в комментариях объяснять и обсуждать это абсолютно бесполезно — пустая трата времени.

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

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

Остаётся ещё два возможных варианта.

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

Если же вы ещё не разбирались или не разобрались, но всё же захотите это сделать — способы найдёте без труда.

А почему бы не объяснять ООП, начиная с …(сюрприз!) ООП? ;)

Там же нет слова "актор". Как нет слов "инкапсуляция", "наследование", "полиморфизм", "абстракция". А вот слово "объект" есть. Может, есть смысл попробовать с него начать?

А ведь когда-то я, дитя ООП, даже представить себе не мог программирование без while. 

Видимо, дитя ООП внебрачное?

BlockClosure>>#whileTrue: aBlock
self value ifTrue: [ aBlock value. self whileTrue: aBlock ].
^ nil

Конечно, поздновато комментировать, надо было сразу… Но всё же скажу:

Может быть всё же не идеи потеряли смысл/суть, а "мы" (в статистическом смысле) "потеряли" смысл и суть этих идей?

Парадигма - это "очки", через которые мы смотрим на какую-либо систему.

Это метафора. Вы действительно считаете, что доказывать метафору с инструментами через метафору с очками может быть убедительно?

Откуда следует, что "парадигма" не может успешно покрыть все системы, с которыми вы имеете дело, когда занимаетесь программированием? Да, наверное, объектная и функциональные парадигмы не всегда хороши. Например, строить личные отношения, объективируя или представляя функциями других людей — вряд ли хорошая идея. (Хотя некоторые именно так и делают — и ничего, как-то существуют.) Но это другая область. Что же конкретно ограничивает применимость парадигм в области разработки программных систем?

Я вам ещё мысль подкину.

Как вы считаете, можно ли одну парадигму полностью отразить в другую? Например, в объектной парадигме смоделировать функциональную? И наоборот?

Если вдруг да, то не сводится ли вопрос выбора парадигмы к вопросу выбора языка?

Но в реальности мы вынуждены идти на компромисс.

Бесспорно, но почему? Нас вынуждает ограниченность парадигмы или ограниченность её реализации — в языке, у нас в голове?

Мы можем выбрать одну парадигму, но тогда некоторые части приложения будут невыразительными

А почему они будут невыразительными? Что мешает там, где вам хочется объектно-ориентированного DSL написать его на функциональном языке? Или наоборот?

Я к чему это всё…

Когда IT-индустрия дорастёт до DSL…

Она никогда не дорастёт, если все всегда будут друг другу пересказывать мысль, что "парадигма" это инструмент и её нужно выбирать под конкретную задачу.

Выдвину ещё такую гипотезу.

В идеале, "парадигма" должна отражать способ мышления человека. И вопрос заключается в том, действительно ли у человека есть несколько способов мышления, между которыми он (постоянно) переключается, или же есть некоторая "глубинная" "парадигма", на которую наслаиваются некие "DSL"-и, сформированные в рамках единой "парадигмы" человеческого мышления?

А речь вообще не о выборе языка под задачу.

Здесь возникает по крайней мере два вопроса:

1. Откуда вообще следует это аналогия между (мне не очень нравится термин, но назовём это условно) парадигмой и инструментом?

2. Допустим даже, что есть смысл выбирать парадигму под задачу. Как из этого следует, что смешивать разные парадигмы в одном языке, усложняя его — это хорошая идея?

А что в этом прекрасного?

Тема хорошая и правильная. Но что интересно: и сама статья, и — особенно! — комментарии к ней являются изумительной иллюстрацией к этой теме.

(Не буду говорить про Scrum ` не очень интересно, но, чувствую, с ним та же история.) А с нормальным ООП ни автор, ни комментаторы так и не захотели ведь разобраться! Гораздо проще ведь в очередной раз перемалывать банальную истину про то, что "у каждой технологии есть своя область", не уточняя, где же она находится.

А автор ещё и пропаганду ФП умудрился ввернуть Не совсем беспочвенно, но и не очень-то способствует лучшем пониманию.

Если в голове у ФП последователей такое, я прохожу мимо 😆

Неожиданно, да? Но нет, уважаемый, путаете вы. Точнее, скорее всего, запутали вас.

В нормальном, чистом ООП достаточно двух базовых видов сущностей: объекты и сообщения. Ни конструкторов, ни типов, ни run-/designtime, ни даже классов и, тем более, типов не нужно — всё это, если и будет, то будет в виде "деталей реализации".

Понимаю, что вам — не лично вам; выросло уже не одно, не два, и даже не три поколения программистов, для которых ООП это три (может быть, четыре) "кита" — недосуг и (морально?) тяжело заставить себя более глубоко изучить вопрос "что такое ООП". Но если вы таки заставите себя почитать, например, The Early History of Smallltalk, или — ещё лучше — на практике попробовать Smalltalk (например, в виде Pharo) или Self, то, возможно, увидите что-то интересное для себя. А "ущербная" парадигма может вдруг заиграть неожиданными красками. И, кстати, вы можете найти интересные связи с так любимым вам ФП.

Но если вам удобнее пользоваться, пусть и не логичная, но привычной "мейнстромовой" трактовочкой ООП а-ля Страуструп, то просто игнорируйте мои сообщения.

В ФП ответственность создания не на отдельном объекте, а на контексте / вызывающем сервисе. А в ООП жёстко: либо ответственность на самом объекте (в конструкторе) либо на другом объекте (чистая выдумка), который пытается вобрать в себя контекст, вариации логики создания.

В ООП ответственность за создание объекта ВСЕГДА лежит вне этого объекта. Уже просто потому, что если объект нужно создать, значит этого объекта ещё нет — и как то, чего нет, может отвечать за что либо?

"Конструктор" — это костыль для недоООП-языков, где есть классы, но классы не являются объектами. Известно ровно два логически полноценных подхода к созданию объектов: объект можно создать либо с помощью уже существующего объекта — через клонирование, либо с помощью класса — через создание экземпляра.

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

С "философской" точки зрения всё логично и самоподобно, а потому требует меньшее количество сущностей, и, следовательно, проще.

Получается такая двойственная/сопряжённая задача для задачи разработки "в общем смысле" — войственный/сопряжённый подход. Вопросов и сомнений сразу же возникает очень много. Но раз, как я понимаю, работает, то есть что поизучать и о чём поразмышлять. Спасибо!

Спасибо переводчику за адекватный перевод и — особенно — за выбор статьи. Тема TDD (Test-Driven Development) vs. TDD (Type-Driven Development) весьма интересна — даже несмотря на то, что напоминает вечную проблему курицы и яйца :)

Итак, концепция TDD (Test Driven Development) – достаточно проста: Разработка ведется короткими циклами, каждый из которых состоит из 3‑х стадий:

1)Написание тестов, покрывающий желаемое изменение

В TDD на каждой итерации пишется ровно один(!) тест. И да, это принципиально.

Всё это очень странно.

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

Во-вторых, замечу, что "минимизация" вероятности дублирования не тождественна гарантии отсутствия. Это тоже не принципиально.

Но как может инициализация (а так же очистка после) быть не общей? SetUp/TearDown и их наследники же не просто так в xUnit-е поддерживаются, нет? Даже в этой наитривиальнейшей задачке присутствует дублирование в инициализации тестов. И предложенные вами в комментарии тесты будут это дублирование иметь — если его в какой-то момент не устранить.

Вообще, причин для изменения тестов в процессе разработки просто немерено.

Рефакторинг. Как бы там не плясали вокруг проблему "хрупкости" (по-моему, сильно преувеличенной, но это отдельный разговор), но если меняется дизайн, то может поменяться контекст работы компоненты. Следовательно,. как минимум придётся изменить "инициализацию". А на самом деле может много чего поменяться — на уровне контракта этой компоненты. Как тут без изменения тестов? Старые выкидываем, пишем новые с листа?

Ладно, допустим, рефакторинг каким-то чудом мы исключили из причин для изменения тестов. Но как быть с (независящими от разработчика) изменениями "архитектуры", внешних библиотек/фреймворков/сервисов/…чего-угодно-ещё…

А как быть с квинтэссенцией всего это бардака и тем, ради чего всё это (якобы) вообще затевалось — с изменениями требований к системе в целом…

А ещё вы очень лихо спихнули (только не понятно на кого) проблему оптимизации, которая непосредственно затрагивает TDD: количество тестов будет расти, а значит будет увеличиваться время их работы, а значит время отклика (обратной связи) будет расти — рано или поздно захочется их оптимизировать… Как это делать, не изменяя тестов? Или кто-то будет это делать за нас? Напомню: мы всё ещё про разработку, а не про тестирование и покрытие.

Ах, да — чуть не забыл, возможно, самую главную причину для изменения тестов — разработчика. Он меняется! Меняется его понимание того, что он разрабатывает. Соответственно, меняется язык, которым он своё понимание записывает. Тест в TDD — это спецификация требования на примере. И очень важно, не просто знать, проходит тест или ломается, а понимать его суть. А задача сформулировать тест/спецификацию так, так чтобы и самом разработчик в будущем, и друге люди смогли понять смысла теста — далеко не тривиально. Решить её с первого захода "может не только лишь каждый". У вас это стабильно получается?

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

Если честно, я вообще не могу представить, как вам удаётся не менять тесты?… Без обид (я спрашиваю для понимания, не с целью победить в полемике, честно!), но вы действительно практикуете TDD в "промышленной" (или как то назвать лучше) разработке? Давно?

Покрытие существующего кода тестами — это не TDD. А TDD — это не рутинная и весьма интеллектуальная работа. От применения TDD на практике отпугивает незнание/непонимание смысла TDD.

И жаль, что уточнить нельзя, а то я бы это сделал…

…Подтвердив, что TDD —конечно же! — про обратную связь. Но не только про неё.

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

Но вот только жизнь устроена так, что одного желания обычно недостаточно — нужно ещё придумать, как это желание воплотить в жизнь. И TDD — про комплекс мер по достижению этого (и, на самом деле, не только этого — так как и сама проблема сложная, многокритериальная, да ещё и динамическая).

В итоге как-то так получается, что, с одной стороны, вы подчёркиваете важную деталь, но при этом упускаете целое. И в результате статья больше не помогает, а, скорее, мешает понять (целостный) смысл TDD.

Но при этом есть гипотеза, что стоит лишь чуть-чуть сместить акцент — говорить не про "Главный секрет TDD", а про "одну из (возможно, неочевидных …почему-то) целей, которые (действительно!) позволяет (не просто хочет, а именно позволяет — как раз благодаря комплексности) достичь TDD (…правда не сразу)", — как ценность статьи возрастёт немедленно и очень сильно.

И то, что понял не правильно — хотя очень старался понять правильно, — возможно, подтверждает эту гипотезу?  

(Изложил многословно и сложновато, конечно — требуется рефакторинг. Но сначала надо заставит тест позеленеть.)

Информация

В рейтинге
Не участвует
Откуда
Тверь, Тверская обл., Россия
Дата рождения
Зарегистрирован
Активность