Я всегда вижу, что абстракция - очень полезная функция, предоставляемая ОО для управления базой кода. Но как управлять большими базами не-OO кода? Или они просто становятся " Большим Грязевым комом "?
Обновление:
казалось, все думают, что «абстракция» - это просто модульность или скрытие данных. Но IMHO, это также означает использование «абстрактных классов» или «интерфейсов», которые необходимы для внедрения зависимостей и, следовательно, для тестирования. Как не-OO кодовые базы управляют этим? Кроме того, помимо абстракции, инкапсуляция также очень помогает в управлении большими базами кода, поскольку она определяет и ограничивает отношения между данными и функциями.
С C очень возможно написать псевдо-OO-код. Я не знаю много о других не-ОО языках. Итак, это способ управлять большими базами кода C?
Ответы:
Вы, кажется, думаете, что ООП является единственным средством достижения абстракции.
Хотя ООП, безусловно, очень хорошо это делает, это ни в коем случае не единственный способ. Большие проекты также можно поддерживать управляемыми с помощью бескомпромиссной модульности (достаточно взглянуть на Perl или Python, оба из которых в этом преуспели, как и функциональные языки, такие как ML и Haskell), а также с помощью таких механизмов, как шаблоны (в C ++).
источник
static
доступ к Модификатор прилагается.Модули, (внешние / внутренние) функции, подпрограммы ...
Как сказал Конрад, ООП - не единственный способ управления большими базами кода. Фактически, до этого было написано довольно много программного обеспечения (до C ++ *).
источник
Принцип модульности не ограничивается объектно-ориентированными языками.
источник
Реально либо редкие изменения (например, расчеты пенсий по социальному обеспечению) и / или глубоко укоренившиеся знания, потому что люди, обслуживающие такие системы, делали это некоторое время (циничный подход - это гарантия занятости).
Лучшими решениями являются повторяемая валидация, под которой я подразумеваю автоматический тест (например, модульное тестирование) и тестирование на людях, которое следует за запрещенными шагами (например, регрессионное тестирование) «вместо того, чтобы щелкать и смотреть, что ломается».
Чтобы начать двигаться к некоторому типу автоматизированного тестирования с существующей кодовой базой, я рекомендую прочитать книгу Майкла Фезера «Эффективная работа с унаследованным кодом» , в которой подробно описываются способы доведения существующих кодовых баз до некоторой повторяющейся структуры тестирования OO или нет. Это приводит к таким идеям, на которые другие ответили, таких как модульность, но в книге описан правильный подход к этому, не ломая вещи.
источник
Хотя внедрение зависимостей, основанное на интерфейсах или абстрактных классах, является очень хорошим способом проведения тестирования, в этом нет необходимости. Не забывайте, что почти любой язык имеет либо указатель на функцию, либо eval, который может делать все, что вы можете делать с интерфейсом или абстрактным классом (проблема в том, что они могут делать больше , включая много плохих вещей, и что они не сами по себе предоставляют метаданные). Такая программа может на самом деле добиться внедрения зависимости с этими механизмами.
Я обнаружил, что строгая работа с метаданными очень полезна. В ОО-языках отношения между битами кода определяются (до некоторой степени) структурой класса, достаточно стандартизированным способом, чтобы иметь такие вещи, как API отражения. На процедурных языках может быть полезно придумать их самостоятельно.
Я также обнаружил, что генерация кода гораздо более полезна в процедурном языке (по сравнению с объектно-ориентированным языком). Это гарантирует, что метаданные синхронизируются с кодом (поскольку он используется для его генерации) и дает вам что-то похожее на точки отсечения аспектно-ориентированного программирования - место, где вы можете вводить код, когда вам это нужно. Иногда это единственный способ сделать СУХОЕ программирование в такой среде, что я могу понять.
источник
На самом деле, как вы недавно обнаружили , функции первого порядка - это все, что вам нужно для инверсии зависимостей.
C поддерживает функции первого порядка и даже замыкания в некоторой степени . А макросы Си являются мощной функцией для общего программирования, если с ними обращаться с необходимой осторожностью.
Это все там. SGLIB - хороший пример того, как C может быть использован для написания кода многократного использования. И я верю, что там намного больше.
источник
Даже без абстракции большинство программ разбиваются на какие-то разделы. Эти разделы, как правило, относятся к конкретным задачам или действиям, и вы работаете над ними так же, как и над наиболее конкретными частями абстрактных программ.
В небольших и средних проектах это иногда проще сделать с помощью пуристической ОО-реализации.
источник
Абстракция, абстрактные классы, внедрение зависимостей, инкапсуляция, интерфейсы и т. Д. Не являются единственным способом управления большими базами кода; это справедливый и объектно-ориентированный способ.
Главный секрет заключается в том, чтобы не думать оОП при кодировании не-ООП.
Модульность является ключом в неOO языках. В Си это достигается так же, как Дэвид Торнли только что упомянул в комментарии:
источник
Одним из способов управления кодом является его разложение на следующие типы кода в соответствии с архитектурой MVC (модель-представление-контроллер).
Этот метод организации кода хорошо работает для программного обеспечения, написанного на любом языке OO или не-OO, потому что общие шаблоны проектирования часто являются общими для каждой из областей. Кроме того, эти виды границ кода часто являются наиболее слабосвязанными, за исключением алгоритмов, поскольку они связывают воедино форматы данных от входов к модели, а затем к выходам.
Эволюция системы часто принимает форму того, что ваше программное обеспечение обрабатывает больше видов входов или больше видов выходов, но модели и представления одинаковы, а контроллеры ведут себя очень схожим образом. Или система может со временем поддерживать все больше и больше различных видов выходных данных, даже если входные данные, модели, алгоритмы одинаковы, а контроллеры и представления аналогичны. Или система может быть дополнена для добавления новых моделей и алгоритмов для того же набора входов, аналогичных выходов и аналогичных представлений.
Один из способов ОО-программирования усложняет организацию кода, поскольку некоторые классы тесно связаны с постоянными структурами данных, а некоторые - нет. Если постоянные структуры данных тесно связаны с такими вещами, как каскадные отношения 1: N или отношения m: n, очень трудно определить границы классов, пока вы не закодируете значимую и значимую часть своей системы, прежде чем узнаете, что поняли ее правильно. , Любой класс, связанный с постоянными структурами данных, будет трудно развить при изменении схемы постоянных данных. Классы, которые обрабатывают алгоритмы, форматирование и синтаксический анализ, менее подвержены изменениям в схеме постоянных структур данных. Использование организации кода типа MVC лучше изолирует самые грязные изменения кода в коде модели.
источник
При работе с языками, в которых отсутствуют встроенная структура и организационные функции (например, если у него нет пространств имен, пакетов, сборок и т. Д.) Или если их недостаточно для контроля кодовой базы такого размера, естественным ответом является разработка наши собственные стратегии для организации кода.
Эта стратегия организации, вероятно, включает в себя стандарты, касающиеся того, где должны храниться разные файлы, что должно произойти до / после определенных типов операций, а также соглашения об именах и другие стандарты кодирования, а также многое из того, «как это настроено» - не связывайтесь с этим! " введите комментарии - которые действительны, если они объясняют почему!
Поскольку стратегия, скорее всего, в конечном итоге будет адаптирована к конкретным потребностям проекта (людям, технологиям, среде и т. Д.), Трудно предложить универсальное решение для управления большими базами кода.
Поэтому я считаю, что лучший совет - принять стратегию, специфичную для проекта, и сделать ее управление ключевым приоритетом: документировать структуру, почему это так, процессы внесения изменений, проверять ее, чтобы убедиться, что она соблюдается, и главное: измените это, когда это должно измениться.
Мы в основном знакомы с рефакторингом классов и методов, но с большой базой кода на таком языке именно организационная стратегия (в комплекте с документацией) должна быть реорганизована по мере необходимости.
Мотивация та же, что и при рефакторинге: вы создадите умственный блок для работы с небольшими частями системы, если почувствуете, что общая организация системы беспорядочная, и в конечном итоге допустите ее ухудшение (по крайней мере, это мое мнение) Это).
Предостережения также одинаковы: используйте регрессионное тестирование, убедитесь, что вы можете легко вернуться, если рефакторинг идет не так, и спроектируйте его так, чтобы в первую очередь упростить рефакторинг (или вы просто не будете этого делать!).
Я согласен, что это намного сложнее, чем рефакторинг прямого кода, и это сложнее проверить / скрыть время от менеджеров / клиентов, которые могут не понимать, почему это нужно делать, но это также типы проектов, наиболее подверженных программному гниению вызвано негибкими конструкциями верхнего уровня ...
источник
Если вы спрашиваете об управлении большой кодовой базой, вы спрашиваете, как сохранить свою кодовую базу хорошо структурированной на относительно грубом уровне (библиотеки / модули / построение подсистем / использование пространств имен / наличие правильных документов в нужных местах так далее.). Принципы ОО, особенно «абстрактные классы» или «интерфейсы», являются принципами для поддержания вашего кода в чистоте внутри на очень детальном уровне. Таким образом, методы для поддержания большой базы кода управляемой не отличаются для ОО или не ОО-кода.
источник
Как это обрабатывается, так это то, что вы узнаете границы элементов, которые вы используете. Например, следующие элементы в C ++ имеют четкую границу, и любые зависимости вне границы должны быть тщательно продуманы:
Комбинируя эти элементы и распознавая их границы, вы можете создать практически любой стиль программирования в C ++.
Примером этого для функции может быть признание того, что вызывать другие функции из функции плохо, потому что это вызывает зависимость; вместо этого следует вызывать только функции-члены параметров исходной функции.
источник
Самая большая техническая проблема - это проблема пространства имен. Частичное связывание может быть использовано для обхода этого. Лучший подход заключается в разработке с использованием стандартов кодирования. В противном случае все символы становятся беспорядком.
источник
Emacs является хорошим примером этого:
В тестах Emacs Lisp используются
skip-unless
иlet-bind
используются средства обнаружения и тестирования функций:Как и SQLite. Вот это дизайн:
sqlite3_open () → Открыть соединение с новой или существующей базой данных SQLite. Конструктор для sqlite3.
sqlite3 → Объект подключения к базе данных. Создается sqlite3_open () и уничтожается sqlite3_close ().
sqlite3_stmt → Подготовленный объект выписки. Создается с помощью sqlite3_prepare () и уничтожается с помощью sqlite3_finalize ().
sqlite3_prepare () → Скомпилируйте текст SQL в байт-код, который будет выполнять запросы или обновлять базу данных. Конструктор для sqlite3_stmt.
sqlite3_bind () → Сохранить данные приложения в параметры исходного SQL.
sqlite3_step () → Переместить sqlite3_stmt к следующей строке результатов или к завершению.
sqlite3_column () → Значения столбцов в текущей строке результатов для sqlite3_stmt.
sqlite3_finalize () → Деструктор для sqlite3_stmt.
sqlite3_exec () → Функция-обертка, которая выполняет sqlite3_prepare (), sqlite3_step (), sqlite3_column () и sqlite3_finalize () для строки из одного или нескольких операторов SQL.
sqlite3_close () → Деструктор для sqlite3.
SQLite использует различные методы тестирования, в том числе:
Ссылки
Концептуальные представления архитектуры Emacs (pdf)
Интерфейс ОС SQLite или «VFS»
Механизм виртуальных таблиц SQLite
Введение в интерфейс SQLite C / C ++
Emacs-Elisp-Программирование · GitHub
Тесты и их среда - Регрессивное тестирование Emacs Lisp
Как тестируется SQLite
источник