У меня есть проект, достаточно большой по размеру, и я не могу больше держать в голове каждый аспект. Я имею дело с рядом классов и функций, и я передаю данные.
Со временем я заметил, что получаю ошибки, потому что забыл, какую точную форму должны иметь данные, когда я передаю их различным функциям ( например, одна функция принимает и выводит массив строк, другая функция, которую я написал гораздо позже, принимает строки, которые хранятся в словаре и т. д., поэтому мне нужно преобразовать строки, с которыми я работаю, из массива в словарь ).
Чтобы избежать необходимости всегда выяснять, что и где сломалось, я начал рассматривать каждую функцию и класс как «изолированную сущность» в том смысле, что он не может полагаться на внешний код, предоставляющий ему правильный ввод, и должен сам выполнять проверки ввода (или, в некоторых случаях переделывают данные, если данные приведены в неправильной форме).
Это значительно сократило время, затрачиваемое на то, чтобы данные, которые я передаю, «вписывались» в каждую функцию, потому что сами классы и функции теперь предупреждают меня, когда какой-то ввод неверен (а иногда даже исправляет это), а я нет Я должен идти с отладчиком через весь код, чтобы выяснить, где что-то пошло не так.
С другой стороны, это также увеличило общий код.
У меня вопрос, подходит ли этот стиль кода для решения этой проблемы?
Конечно, лучшим решением будет полная реорганизация проекта и обеспечение единообразной структуры данных для всех функций - но, поскольку этот проект постоянно растет, я бы в конечном итоге тратил больше и беспокоился о чистом коде, чем фактически добавлял новые вещи. ,
(К вашему сведению: я все еще новичок, поэтому извините, если этот вопрос был наивным; мой проект на Python.)
источник
Ответы:
Лучшее решение - использовать все преимущества возможностей и инструментов языка Python.
Эта проблема смягчена с
namedtuple
. Это легкий и дает легкий смысловой смысл для членов вашего массива.Чтобы воспользоваться преимуществами автоматической проверки типов без переключения языков, вы можете воспользоваться подсказками типов . Хорошая IDE может использовать это, чтобы сообщить вам, когда вы делаете что-то глупое.
Вы также, похоже, беспокоитесь о том, что функции устаревают при изменении требований. Это можно поймать с помощью автоматического тестирования .
Хотя я не говорю, что ручная проверка никогда не подходит, более эффективное использование доступных языковых функций может помочь вам решить эту проблему более удобным способом.
источник
namedtuple
и все другие приятные вещи. Я не думал об этомnamedtuple
- и хотя я знал об автоматизированном тестировании, я никогда особо не использовал его и не понимал, насколько это поможет мне в этом случае. Все это действительно похоже на статический анализ. (Автоматическое тестирование может быть даже лучше, так как я могу уловить все тонкие вещи, которые не будут обнаружены при статическом анализе!) Если вы знаете что-нибудь другое, пожалуйста, дайте мне знать. Я собираюсь держать вопрос открытым еще немного, но если другие ответы не придут, я приму ваши.ОК, настоящая проблема описана в комментарии ниже этого ответа:
Проблема здесь заключается в использовании списка строк, где порядок обозначает семантику. Это действительно подверженный ошибкам подход. Вместо этого вы должны создать собственный класс с двумя полями с именами
title
иbibliographical_reference
. Таким образом, вы не собираетесь смешивать их, и вы избежите этой проблемы в будущем. Конечно, это требует некоторого рефакторинга, если вы уже используете списки строк во многих местах, но, поверьте мне, это будет дешевле в долгосрочной перспективе.Общим подходом в языках с динамическими типами является «типизированная утка», что означает, что вы на самом деле не заботитесь о «типе» передаваемого объекта, вам важно только, если он поддерживает методы, которые вы вызываете для него. В вашем случае вы просто прочитаете поле, которое вызывается,
bibliographical_reference
когда вам это нужно. Если это поле не существует в переданном объекте, вы получите сообщение об ошибке, и это означает, что в функцию передан неправильный тип. Это такая же хорошая проверка типа, как и любая.источник
Прежде всего, то, что вы испытываете сейчас, это запах кода - постарайтесь вспомнить, что привело вас к осознанию запаха, и постарайтесь отточить свой «ментальный» нос, так как чем раньше вы заметите запах кода, тем быстрее - и легче - Вы можете исправить основную проблему.
Оборонительное программирование - так называется эта техника - является допустимым и часто используемым инструментом. Однако, как и во всех вещах, важно использовать правильное количество, слишком мало проверок, и вы не поймаете проблем, слишком много, и ваш код будет чрезмерно раздутым.
Это может быть не очень хорошая идея. Если вы заметили, что часть вашей программы вызывает функцию с неправильно отформатированными данными, FIX THAT PART , не изменяйте вызываемую функцию, чтобы в любом случае иметь возможность переваривать неверные данные.
Повышение качества и удобства сопровождения вашего кода в долгосрочной перспективе экономит время (в этом смысле я должен снова предостеречь от функций самокоррекции, встроенных в некоторые из ваших функций - они могут быть коварным источником ошибок. Просто потому, что ваши программа не вылетает и не горит не означает, что она работает правильно ...)
Чтобы, наконец, ответить на ваш вопрос: Да, защитное программирование (то есть проверка правильности предоставленных параметров) является - в хорошей степени - хорошей стратегией. Тем не менее , как вы сказали сами, ваш код не отвечает требованиям, и я настоятельно рекомендую потратить некоторое время на рефакторинг частей, которые пахнут - вы сказали, что не хотите постоянно беспокоиться о чистом коде, тратя больше времени на «чистка», чем на новые функции ... Если вы не будете содержать в чистоте свой код, вы можете потратить вдвое больше времени на «спасение» от несоблюдения чистоты кода при устранении ошибок, и вам будет трудно реализовать новые функции - техническая задолженность может раздавить вас.
источник
Это нормально. Я имел обыкновение кодировать в FoxPro, где у меня были блоки TRY..CATCH почти в каждой большой функции. Теперь я пишу код в JavaScript / LiveScript и редко проверяю параметры во «внутренних» или «частных» функциях.
«Сколько проверять» зависит от выбранного проекта / языка больше, чем от вашего навыка кода.
источник