Программирование — это сложное дело. Поэтому каждая техника, которая помогает его упростить, весьма полезна. Рассмотрим простые и эффективные приемы, которые помогают упростить работу программиста.
1. Функция-обертка
Это самый простой и распространенный способ упрощения. Функция-обертка — это функция, которая вызывает некоторую функцию с заданными параметрами.
Например, мы хотим вывести число в окне сообщений. Для этого служит функция MessageBox. Согласно MSDN эта функция имеет целых четыре аргумента:
1 2 3 4 5 6 |
int WINAPI MessageBox( _In_opt_ HWND hWnd, _In_opt_ LPCTSTR lpText, _In_opt_ LPCTSTR lpCaption, _In_ UINT uType ); |
Если каждый раз при вызове этой функции мы будем вспоминать, что значит каждый аргумент, то это замедлит работу. Поэтому пишем функцию-обертку, которая берет всего один аргумент, а остальные подставляет по умолчанию и вызывает MessageBox.
1 2 3 4 5 6 7 |
void ShowNumber(int x) { char str[1000]; sprintf(str,"Результат=%d",x); MessageBox (0, str, "Message", MB_OK); } |
Как видите, эту функцию проще запомнить и вызвать.
Важно! Функция-обертка не меняет функционал. Иначе вам придется каждый раз вспоминать, что именно вы поменяли и весь выигрыш в простоте вызова пропадет.
Этот прием настолько прост и эффективен, что имеет смысл в начале создания программы сразу написать несколько оберток для часто вызываемых функций.
2. Функция с защитой
Часто бывает, что стандартные функции не могут быть выполнены по разным причинам. Например, нет места на диске или пользователь ввел не те данные. Если за этим не следить, то программа вылетит с ошибкой, что не очень хорошо. Даже если виноват пользователь.
Прием состоит в том, чтобы не вызывать потенциально опасные функции, а писать защищенные функции. Например, часто требуется, чтобы в имени файла были только латинские буквы.
Мы запрашиваем у пользователя имя файла, но перед сохранением файла можно вставить функцию, которая заменит русские буквы на латинскую «a».
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void NameProtect(char *str) { int i = 0; while (str[i]) { if ((unsigned char)str[i]>127) { str[i]='a'; } i++; } } |
Для простоты применения приема можно вначале кодирования писать защищенные функции без защиты, например:
1 2 3 4 |
SaveProtect() { SafeFile(); }; |
А потом уже на этапе окончательной доводки программы вставлять защиту в каждую функцию.
3. Функция с отображением ситуации
Одна из самых сложных задач в работе программиста — это отладка. Конечно же, самый простой способ смотреть состояние данных во время отладки — это окно отладчика. Но отладчик показывает только то, значения стандартных объектов: переменных, строк, массивов.
Но, например, вы пишете игру, а вам нужно найти ошибку в поведении элемента игры. В этом случае информации отладчика будет явно недостаточно.Другой вариант, вы пишете бухгалтерскую программу и у вас неверно считается некоторое число в счет-фактуре. Опять же отладчик тут не помощник.
В подобных случаях пригодится функция с отображением ситуации.
Вы пишете специальную функцию, которая отображает состояние вашего объекта данных максимально приближено к реальной ситуации. После чего вы можете вызывать эту функцию специально для отладки.
4. Функция инициализация объектов данных
Во многих программах какой-то части объектов данных нужно присвоить начальные значения. Это называется инициализацией. Часто программисты делают инициализацию перед первым использованием объекта. Но это порождает трудно находимые ошибки, если объект был использован ранее. Дело в том, что при создании объекта данных там уже содержатся некоторые случайные данные. И в отладчике трудно отличить — это правильные данные или случайные.
Для избежания подобных ошибок рекомендуется добавить функцию инициализации, которую вызывать в самом начале программы. Например.
1 2 3 4 5 6 7 8 9 10 11 |
void Init() { x=0; i=1; Start=0; } int main() { Init(); }; |
И завести привычку при создании объекта данных сразу добавлять в функцию Init инициализацию этого объекта.
5. Сниппеты
Сниппеты — это фрагменты кода. Чтобы сэкономить время и избежать опечаток старайтесь создать как можно больше сниппетов и быстро вставляйте их в программу. Не нужно постоянно вводить одно и тоже. Просто добавляйте фрагменты кода мышкой.
6. Паттерны
Паттерн в разработке программного обеспечения — это повторяемая архитектурная конструкция. Паттерн — это не готовый код, а некоторый общий прием, который вы используете в разных ситуациях.
Например, при работе с файлами есть повторяющиеся действия:
- Открыть файл.
- Считать или записать информацию.
- Закрыть файл.
При работе с файлами вы сразу создаете функции:
- OpenFile()
- Read() и Write()
- CloseFile()
Преимущество паттернов в том, что вы в разных программах имеете функции с одинаковыми именами и одинаковым действием. Это сильно упрощает работу.
Например, вам при открытии файла нужно убедиться, что он есть, а в противном случае создать его. Соеденим этот прием с приемом №2 «Функция с защитой».
1 2 3 4 5 6 7 8 9 10 11 |
int OpenFileProtect(char *filename) { if( IsFileExist(filename)) { // файл есть - открываем } else { // файла нет - создаем } } |
Работа с паттернами не так проста, поэтому рекомендуется описать где-нибудь свои паттерны, чтобы потом можно было их быстро использовать. Иначе информация забудется и все надо будет изобретать по новой.
7. Юниты
Этот прием сэкономит вам много времени и нервов при работе с заказчиками. Юнит — это логическая часть программы, которую можно включать или отключать без ущерба для основного функционала. Говоря на программистском жаргоне юнит — это модуль, подвешенный на логическую переменную:
1 2 3 4 |
if (IsUnit == TRUE) ... else ... |
Если вам нужно убрать юнит из программы, то вы просто обнуляете одну переменную и весь функционал юнита исчезает. Его нет не в меню, не в настройках.
Юнит может использоваться в разных программах с минимальной доработкой. Юнит в обыденном смысле можно сравнить с аптечкой. Вы можете положить аптечку и сумку на уикенд, и в чемодан на отдых, но сама аптечка от этого не меняется.
Примером юнита является блок рекламы. При включенном юните реклама показывается, при выключенном пропадает.
Как же юниты позволяют экономить силы? Часто от программиста требуют дополнительный функционал. Как только программист представил программу, сразу начинается:
- А вот еще такую функцию!
- Еще нужна такая настройка!
- Еще добавь интеграцию с 1С!
Если пойти на поводу. то одну программу можно дорабатывать годами. Юниты легко решают эту проблему. Вместо доработки программы следует сделать отдельный юнит и назначить за него цену.
Если функционал реально нужен, то пользователи будут платить. Если не нужен, то юнит просто повисит, а потом про него можно будет забыть. Это позволяет программисту сберечь массу усилий на реализации функций, которые никому не нужны.
При разработке коммерческих программ следует сосредоточиться на минимально полезном функционале. А дальше делать только через юниты.
Странно … годная статья, а без комментов 🙁
Спасибо, что делитесь знаниями!
Очень полезная статья. Чтобы её написать, надо самому весь материал пропустить через себя. Одна такая статья стоит одного года учёбы в институте.
Действительно странно, что комментариев совсем нет. Спасибо автору!
Доброго дня.
Примите благодарности за наставления нас на путь истинный.
Пожелания: Демонстрировать фрагменты кода на разных ЯП. Python приветствуется.