Pull to refresh

Comments 35

А делов-то, применить выделение метода да следить, что бы одна функция работала только с одним уровнем абстракции… ну еще SRP не забывать… ну и Лисков… ну и инкапсуляцию… МакКоннела тоже… чаще вспоминать.

Ещё можно подписаться, к примеру, на codereview.stackexchange.com.
Спасибо! Первый раз узнал про этот ресурс.
Я вообще обожаю, когда мне удаётся без изменения логики сократить объём кода или улучшить читаемость или упростить/улучшить архитектуру.
Вы затронули важную вещь, но очень уж кратко. Остается только надеяться, что статья вдохновит джуниоров читать литературу.
З.Ы. Добро пожаловать на хабр.
Я просто сам не очень люблю читать длинные статьи и придерживаюсь идеи, что статью можно считать законченной, когда из неё ничего нельзя выкинуть. Хотя эта статья — капля в море, безусловно.

И спасибо, за «З.Ы.» )
Желательно эти функции еще и инлайнить и вообще обьявлять как static чтобы интерфейс не засоряли!
При чем тут static? Чтоб интерфейс не засоряли, нужно в private объявлять.
Увы, оно даже в привате будет интерфейс засорять и потенциально ломать бинарную совместимость. То есть или pimpl делать или же в реализации пару static функций сделать, чтобы не экспортились зазря.

И вообще, чем меньше методов у обьекта тем лучше!
Как невиртуальный метод сломает бинарную совместимость?
Никак. Но стоит добавить новое поле или не дай бог виртуальный метод и привет! И честно сказать, не слишком приятно читать обьявление класса со 100500 приватными методами из 3х строчек каждый
Вы яркий пример человека, неспособного мыслить абстрактными категориями. Всё пытаетесь упасть на более низкий уровень абстракции. Ну вот каким боком к проектированию ПО все то, о чем вы пишете? Принципы, о которых говорит человек в статье, вообще не привязаны к языку программирования. К чему плести бинарную совместимость, статик ф-ии, перекомпиляцию зависимых исходников и прочую мишуру, зависящую от языка?
А вы пример человека, делающего далеко идущие выводы при недостатке информации!
При проектировании ПО разве не надо учитывать особенности языка и его недостатки? Я что-то говорил против самого подхода?
Надоели некоторые программисты с ООП головного мозга, которые насоздают абстракций и потом через них продираться приходится! Overengineering тоже зло!
ООП головного мозга

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

Этот метод рано или поздно пригодится, поверьте. Я видел, как серьёзнейшие программисты копипастили подобные условия в другие методы. Я ещё ни разу не пожалел, что вынес в метод тривиальное условие, даже встречающееся только один раз в классе. Иногда бывает трудно определить, в какой момент условие перестает быть тривиальным, и я перестраховываюсь. Тем более трудно предсказать, когда оно понадобится (я же не Нострадамус). «Ой, надо добавить условие; хмм, кажется в каком-то методе оно встречалось; а черт с ним заново напишу; а нет, нашел, ctrl+c, ctrl-v.» И опять, я выношу метод, чтобы все вызовы внутри находились на одном уровне абстракции. И он мне совсем не мешает, он обычно константный, лежит себе спокойно в подвале cpp-файла.
Ну и перекомпиляцию зависимых исходников никто не отменял, со статиками этой проблемы не будет!
Зачем объявлять в статическом контексте что-то, хранящее или определяющее состояние?
Честно говоря, не понял, что здесь специфичного именно для C++.

Пост замечательный, кстати. Спасибо
что здесь специфичного именно для C++

Я люблю C++
А так, в общем-то, ничего )

И вам спасибо!
Статья как-то внезапно закончилась. Ждал еще нескольких примеров, описание «Extract metod» — как и когда им нужно пользоваться и всё в этом духе. Но идея правильная, да, спасибо.
Только надо добавить один коммент, делать все красиво надо только тогда, когда точно знаете, что должно получиться и как оно должно получиться. Если пишется прототип, исследовательский код или используется новая технология, не надо этой красоты и правильности. Надо писать быстро, а потом удалять. Не надо всегда стараться делать правильно ибо никакого терпения не хватит все это менять постоянно, а в случае с чем-то новым, менять придется, и не раз.
Когда «всё красиво», то и изменения делать легче.
При создании прототипа вы всё равно используете примерно те же абстракции, что и в готовом коде. Некоторые части кода прототипа можно будет спокойно перенести в готовый код.
Легче то оно легче, только вот объем работы увеличивается значительно. Но все зависит от задачи, лично мне частенько надо делать прототипы, конечную архитектуру которых мне весьма и весьма сложно представить (потому и делаю:)). А перенос кода прототипа в готовый код — первый шаг к тому, что прототип станет этим самым готовым кодом со всеми вытекающими последствиями, IMHO.
Интересный пост. Также, в С++ есть ключевые слова and, or, not, not_eq и другие для повышения человечности кода. Не хватает только «is» и «as» вместо dynamic_cast.
Если честно, они не для человечности, а для совместимости со старыми системами, не поддерживающими небуквы. То же самое относится к диграфам и триграфам.
(Источник: Страуструс, Язык С++, 905 страница).
>>Не хватает только «is» и «as» вместо dynamic_cast.

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

Насчет and, or и not: они ничуть не читабельнее &&, ||,!
Спасибо за уточнение. Но в контексте топика, думаю актуально.
if( not serverReady() )

или
if( !isServerReady() )

Не принципиально, и вторая запись более знакома. Однако…
Роберт Мартин считает, что предпочтительнее положительные проверки, так как они проще вспринимаются мозгом:
if( serverIsNotReady() )
Сомнительно. Те же тролли считают по другому и их подход мне больше нравится.
Считаю что функция с частицей not выглядит странно, лучше уж !isServerReady()
Ооо, спасибо, сам сейчас Макконнелла читаю.
Вобщем, вывод: код в методе должен находиться на одном уровне абстракции.
код в методе должен находиться на одном уровне абстракции

Совершенно верно! Надо было мне это вынести в заголовок, а содержимое поста оставить пустым )
Абстрагируемся дальше: код в методе должен быть наиболее легко понятным человеку, который видит его впервые в жизни!
наиболее легко понятным человеку, который видит его впервые в жизни!

Да, а с увеличением времени работы с кодом человек всё хуже бы в нём разбирался? )
Это было бы просто идеально для работодателя! Можно было бы менять программистов как перчатки!
Особенно ценными при этой логике стает возможность писать подфункции. Код начинает выглядеть так:

def some_func():
def do_a():
# ...
def do_b():
# ...
# ... (другие def'ы)
do_a()
do_b()
foo = do_foo()
return do_bar(foo)

Sign up to leave a comment.

Articles