Comments 35
А делов-то, применить выделение метода да следить, что бы одна функция работала только с одним уровнем абстракции… ну еще SRP не забывать… ну и Лисков… ну и инкапсуляцию… МакКоннела тоже… чаще вспоминать.
Ещё можно подписаться, к примеру, на codereview.stackexchange.com.
+5
Вы затронули важную вещь, но очень уж кратко. Остается только надеяться, что статья вдохновит джуниоров читать литературу.
З.Ы. Добро пожаловать на хабр.
З.Ы. Добро пожаловать на хабр.
+1
Желательно эти функции еще и инлайнить и вообще обьявлять как static чтобы интерфейс не засоряли!
-7
При чем тут static? Чтоб интерфейс не засоряли, нужно в private объявлять.
+3
Увы, оно даже в привате будет интерфейс засорять и потенциально ломать бинарную совместимость. То есть или pimpl делать или же в реализации пару static функций сделать, чтобы не экспортились зазря.
И вообще, чем меньше методов у обьекта тем лучше!
И вообще, чем меньше методов у обьекта тем лучше!
-2
Как невиртуальный метод сломает бинарную совместимость?
0
Никак. Но стоит добавить новое поле или не дай бог виртуальный метод и привет! И честно сказать, не слишком приятно читать обьявление класса со 100500 приватными методами из 3х строчек каждый
-2
Вы яркий пример человека, неспособного мыслить абстрактными категориями. Всё пытаетесь упасть на более низкий уровень абстракции. Ну вот каким боком к проектированию ПО все то, о чем вы пишете? Принципы, о которых говорит человек в статье, вообще не привязаны к языку программирования. К чему плести бинарную совместимость, статик ф-ии, перекомпиляцию зависимых исходников и прочую мишуру, зависящую от языка?
+6
А вы пример человека, делающего далеко идущие выводы при недостатке информации!
При проектировании ПО разве не надо учитывать особенности языка и его недостатки? Я что-то говорил против самого подхода?
Надоели некоторые программисты с ООП головного мозга, которые насоздают абстракций и потом через них продираться приходится! Overengineering тоже зло!
При проектировании ПО разве не надо учитывать особенности языка и его недостатки? Я что-то говорил против самого подхода?
Надоели некоторые программисты с ООП головного мозга, которые насоздают абстракций и потом через них продираться приходится! Overengineering тоже зло!
+2
ООП головного мозга
Ну да, бывает и такое (может это даже я). Но вообще абстракции нужны для того, чтобы как раз не продираться, когда не надо.
0
Поэтому иной раз гораздо читабельнее будет таки обойтись без выделения метода, особенно, если сравнение в условии тривиальное и очевидное, да еще и встречается лишь единожды во всем классе.
0
К тривиальным условиям вопросов нет. Я про те условия, логика которых не всегда может быть понятна из контекста.
Этот метод рано или поздно пригодится, поверьте. Я видел, как серьёзнейшие программисты копипастили подобные условия в другие методы. Я ещё ни разу не пожалел, что вынес в метод тривиальное условие, даже встречающееся только один раз в классе. Иногда бывает трудно определить, в какой момент условие перестает быть тривиальным, и я перестраховываюсь. Тем более трудно предсказать, когда оно понадобится (я же не Нострадамус). «Ой, надо добавить условие; хмм, кажется в каком-то методе оно встречалось; а черт с ним заново напишу; а нет, нашел, ctrl+c, ctrl-v.» И опять, я выношу метод, чтобы все вызовы внутри находились на одном уровне абстракции. И он мне совсем не мешает, он обычно константный, лежит себе спокойно в подвале cpp-файла.
Этот метод рано или поздно пригодится, поверьте. Я видел, как серьёзнейшие программисты копипастили подобные условия в другие методы. Я ещё ни разу не пожалел, что вынес в метод тривиальное условие, даже встречающееся только один раз в классе. Иногда бывает трудно определить, в какой момент условие перестает быть тривиальным, и я перестраховываюсь. Тем более трудно предсказать, когда оно понадобится (я же не Нострадамус). «Ой, надо добавить условие; хмм, кажется в каком-то методе оно встречалось; а черт с ним заново напишу; а нет, нашел, ctrl+c, ctrl-v.» И опять, я выношу метод, чтобы все вызовы внутри находились на одном уровне абстракции. И он мне совсем не мешает, он обычно константный, лежит себе спокойно в подвале cpp-файла.
0
Ну и перекомпиляцию зависимых исходников никто не отменял, со статиками этой проблемы не будет!
0
Зачем объявлять в статическом контексте что-то, хранящее или определяющее состояние?
0
Честно говоря, не понял, что здесь специфичного именно для C++.
Пост замечательный, кстати. Спасибо
Пост замечательный, кстати. Спасибо
+6
Статья как-то внезапно закончилась. Ждал еще нескольких примеров, описание «Extract metod» — как и когда им нужно пользоваться и всё в этом духе. Но идея правильная, да, спасибо.
+1
Только надо добавить один коммент, делать все красиво надо только тогда, когда точно знаете, что должно получиться и как оно должно получиться. Если пишется прототип, исследовательский код или используется новая технология, не надо этой красоты и правильности. Надо писать быстро, а потом удалять. Не надо всегда стараться делать правильно ибо никакого терпения не хватит все это менять постоянно, а в случае с чем-то новым, менять придется, и не раз.
0
Когда «всё красиво», то и изменения делать легче.
При создании прототипа вы всё равно используете примерно те же абстракции, что и в готовом коде. Некоторые части кода прототипа можно будет спокойно перенести в готовый код.
При создании прототипа вы всё равно используете примерно те же абстракции, что и в готовом коде. Некоторые части кода прототипа можно будет спокойно перенести в готовый код.
0
Легче то оно легче, только вот объем работы увеличивается значительно. Но все зависит от задачи, лично мне частенько надо делать прототипы, конечную архитектуру которых мне весьма и весьма сложно представить (потому и делаю:)). А перенос кода прототипа в готовый код — первый шаг к тому, что прототип станет этим самым готовым кодом со всеми вытекающими последствиями, IMHO.
0
Интересный пост. Также, в С++ есть ключевые слова and, or, not, not_eq и другие для повышения человечности кода. Не хватает только «is» и «as» вместо dynamic_cast.
-2
Если честно, они не для человечности, а для совместимости со старыми системами, не поддерживающими небуквы. То же самое относится к диграфам и триграфам.
(Источник: Страуструс, Язык С++, 905 страница).
(Источник: Страуструс, Язык С++, 905 страница).
0
>>Не хватает только «is» и «as» вместо dynamic_cast.
И очень правильно! У кастов сознательно такие длинные имена, чтобы они искались по коду легко и чтобы было меньше желания ими пользоваться!
Насчет and, or и not: они ничуть не читабельнее &&, ||,!
И очень правильно! У кастов сознательно такие длинные имена, чтобы они искались по коду легко и чтобы было меньше желания ими пользоваться!
Насчет and, or и not: они ничуть не читабельнее &&, ||,!
+4
Спасибо за уточнение. Но в контексте топика, думаю актуально.
или
Не принципиально, и вторая запись более знакома. Однако…
if( not serverReady() )
или
if( !isServerReady() )
Не принципиально, и вторая запись более знакома. Однако…
0
Ооо, спасибо, сам сейчас Макконнелла читаю.
Вобщем, вывод: код в методе должен находиться на одном уровне абстракции.
Вобщем, вывод: код в методе должен находиться на одном уровне абстракции.
0
код в методе должен находиться на одном уровне абстракции
Совершенно верно! Надо было мне это вынести в заголовок, а содержимое поста оставить пустым )
0
Абстрагируемся дальше: код в методе должен быть наиболее легко понятным человеку, который видит его впервые в жизни!
0
А я именно так и пишу! ;)
0
Особенно ценными при этой логике стает возможность писать подфункции. Код начинает выглядеть так:
def some_func():
def do_a():
# ...
def do_b():
# ...
# ... (другие def'ы)
do_a()
do_b()
foo = do_foo()
return do_bar(foo)
0
Sign up to leave a comment.
Про абстракции и метод рефакторинга «Extract method»