Как стать автором
Обновить

Комментарии 13

Ваши лекции наверняка интересно слушать вживую. :)


По поводу паттернов из GoF. Я помню был хайп лет 10 тому назад, может чуть больше. На каждом собеседовании обязано был вопрос. Какие паттерны вы используете чаще всего? В чем отличие абстрактной фабрики от фабричного метода? Почему синлтон это антипаттерн? Эх, ностальгия. Сначала спрашивали меня. Потом спрашивал сам. А потом всем надоело, и тема паттернов сама по себе стала антипаттерном. Для программиста через-чур абстрактно, для архитектора — слишком мелко.

Знаете, я на лекциях (напомню, это второй курс, они только-только на первом курсе самим плюсам чуть-чуть типа научились) рассказываю многие вещи именно затем, чтобы они не стали ни жупелом, ни молитвой, а стали именно тем, чем являются — обычными техническими приёмами, которые постоянно будешь использовать, если работаешь с объектами. Чтобы человек на собеседовании не падал в обморок при словах «Template Method», а уверенно кривил губы: «Вы точно хотите этот примитивный приём обсуждать с такой помпой?». Так что цель в этом. Если надо тренироваться работе с объектами, то лучше это делать на не совсем тривиальных приёмах, а заодно и сразу прививку от хайпа на этой теме сделать. Если не впитал это с детства с молоком преподавателя матери, есть риск потом сделаться евангелистом :)
Статья хорошо, но вы говорите о С++, указателях и тд, но при этом вы сами не управляете памятью в примерах (у всех весь пример CoR утек, new — есть, а delete — нету, тоже самое и в Command). Потом есть всякие мелочи С++, которым стоило бы сразу рассказывать студентам, чтобы привыкали. Никакого NULL — в давно есть nullptr, для конструкторов\деструкторов можно писать = default\delete, printf — оставьте в С и тд.
За статью спасибо.
Я ж говорю, я в плюсах не умею, я в матлабе, питоне, в sql, в haskell и ещё в одном, что называть нельзя, чтобы не заминусовали :). Не стреляйте в пианиста, играет как умеет :). Мне бы уместить у людей в головах понимание абстракций уровня «указатель на указатель», и я уже сочту свою миссию исполненной :)
Здравствуйте, я хотел бы добавить свой комментарий в этом обсуждении исключительно потому, что вы показываете этот код студентам (ну и здесь вы пометили материал как Tutorial). Пожалуйста, потратьте какое-то количество времени на прочистку — на благо вашим студентам и человечества в целом. Используйте std::unique_ptr вместо T* там, где структура данных владеет объектом T (и, в целом, постарайтесь избегать * по возможности, используйте &). Используйте nullptr вместо NULL (в объявлении чистых виртуальных методов пишите "= 0", не "= NULL"). Определитесь, как вы обозначаете перекрытие вирутального метода в наследующем классе (я бы однозначно рекомендовал override — у вас в коде это ключевое слово отсутсвует, а virtual то есть, то нет). Используйте !X вместо X == false.

Дайте знать в случае, если вам нужны пояснения к этим рекомендациям: я попробую их предоставить (ссылаясь, например, на C++ Core Guidelines: isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html).

Про «абстракцию указатель на указатель» — может оказаться опасной педагогическая затеей, на мой взгляд, при отсутствии базовых понятий об управлении памятью. Работая с аллоцируемой в куче памятью на C++, прежде всего, учите пользоваться std::unique_ptr (плюс std::make_unique — чтобы в коде решения задачи не светились не только явные delete, но и явные new) и & ссылками с первого дня. Окупится сторицей. Если нужен дополнительный материал для пытливых студентов, дайте им std::shared_ptr (c std::make_shared) и настоятельно отговаривайте от использования «голых» C указателей, new, delete.
В этих предложениях, безусловно, всё правда, но тогда, возможно, легче просто использовать C# или java, тем более, что они его большей частью и используют там, где можно не использовать С++. Меня беспокоит, что умные указатели для студентов второго курса будут однозначно магией, а я этого категорически не хочу.
Вы правы, в курсе по ООП лучше использовать Java, C#. Однако, если вы выбрали C++, пожалуйста, не демонстрируйте студентам код от преподавателя с ошибками в управлении памятью. В вашем первом примере (с беззаботной по части управления памяти передачей ответственности в DivisionChecker)

queue = new DivisionChecker(i, queue);

классическая, учебниковая утечка памяти (вызывающий код, вероятно, предполагает передачу владения старого queue в новый экземпляр DivisionChecker, который к этой неожиданной для него дополнительной задаче относится несколько беззаботно). Можно использовать как простую задачу на зачете или разогревный вопрос на интервью.
Спасибо за комментарий, изменения внёс.
Спасибо и вам! При случае (если вам захочется) можно обсудить, так ли уж магичны смартпойнтеры (после того, как вызовы delete в деструкторах / завершениях функции начнут казаться студентам чем-то, заслуживающим обобщения как переиспользуемый, один раз реализованный «паттерн автоматического управления памятью в C++») и как объявлять функцию так, чтобы её взаимоотношения на счёт владения объектами с вызывающим кодом были ясны уже из объявления, без необходимости заглядывания в реализацию — но это уже C++-специфично, к вашему курсе, вероятно, плохо подойдёт.
Я видимо не смог правильно свою мысль донести в предыдущем комментарии. Это не со мной нужно обсуждать, магичны ли смартпойнтеры :). Это надо придумать, что и как рассказывать конкретным студентам конкретного потока, которые в подавляющем большинстве еще не успели понять, почему функция вида void inc(int x) {x = x+1;} работает совсем не так, как функция void inc(int &x) {x = x+1;}. С этим бессмысленно спорить, это реальность, данная мне в ощущениях. Я вижу сплошь и рядом такую проблему при изучении программирования, что студенты пишут код как магические заклинания. То есть они понимают, что фраза «вингааардиум левиооооса» заставляет предмет взлететь, но почему так происходит — не понимают. И именно это меня не устраивает, я до этого докапываюсь и перевожу магию в инженерию. Но вынужден делать выбор, что я успею объяснить, а что нет. Поэтому стараюсь использовать только то, что для них (не всех вообще — а только моих студентов) будет здесь и сейчас инженерией, а не магией.
Интересно, какой код потом будут писать ваши студенты?

На моей практике всё же лучше заходили описания от живых примеров, когда сначала даётся ситуация/проблема, потом ищется хорошее решение, а потом показывается, что это за паттерн.
Часто так удавалось вправить мозги тем, кто книжку читал или на курсах (или в институте) изучал паттерны.

Вариант с синтетическим кодом, имхо, плох тем, что в памяти останется реализация, а не сам паттерн. Потом оказывается, что они не могут применить паттерн в другой ситуации, или в упор не видят паттер в коде реального приложения.

Сам я про паттерны узнал (и книжку GoF) узнал позже, чем начал их применять. Было прикольно читать описания паттернов и вспоминать, где я так делал :)
Я не склонен преувеличивать свой ущерб вклад в их профессиональный путь. Думаю, они бы и без меня нормально работали по всяким яндексам, гуглам и фейсбукам, кто достоин. Да, вы всё правильно говорите, но в рамках бакалавриата у них просто нет времени на этот полноценный эволюционный путь. Приходится вот так, «на стероидах», отправлять в полёт с помощью катапульты. Предложите другой вариант? Что мне делать? У меня 14 лекций и 8 лабораторных работ, а дальше — открытый космос самообразования.
Подозреваю, многое от программы обучения зависит? Но если есть гибкость, наверно лучше сконцентрироваться на нескольких самых употребимых и научить их писать реализацию и читать описание. Они потом хоть смогу прочесть про остальные и хоть с каким-то шансом суметь написать реализацию.
А то ведь как бывает: приходит на собеседование студент, что-то писал даже, паттерны изучал в институте. А спросишь его, встречался ли они с ними в своей практике, отвечает, что нет. Хотя что-то работающее писал на ASP.Net, а там ведь паттерны на каждом шагу.
Если уж спросить, в чём суть — объяснить не могут, зачем они нужны — тоже. Грустно.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории