Правила программирования на Си и Си++


Если проект не ориетирован на объекты, то используйте Си


Позвольте мне начать, сказав, что нет абсолютно ничего дурного в хорошо выполненном структурном проектировании. Как-то так получилось, что я предпочитаю объектно-ориентированный (ОО) подход, ибо мне кажется, что я мыслю ОО способом, но было бы самонадеянным назвать ОО

проектирование "лучшим". Я верю, что ОО подход дает вам легче сопровождаемый код, если программа большая. Выгода менее явна в случае программ меньшего размера, потому что объектная ориентация обычно добавляет сложность на уровне приложения. (Главная выгода ОО заключается в лучшем сопровождении за счет абстракции данных, а не в сокращении сложности).

Си++ особенно не выносит небрежного проектирования. Мой опыт говорит, что программы на Си++, которые не придерживаются объектно-ориентированного подхода, почти несопровождаемы, соединяя все худшие свойства структурного и объектно-ориентированного проектов и не давая каких-либо выгод как ни от того, так и ни от другого. Со мной не проходит такой аргумент, что можно использовать Си++ как "улучшенный" Си. Для того, чтобы это было правдой, этот язык слишком сложный — кривая обучения слишком крутая. Если вы не используете преимущества объектно-ориентированных свойств этого языка, то в его использовании мало смысла. Некорректное использование объектно-ориентированных свойств лишь увеличит число проблем.

К сожалению, многие программисты знают, как сделать объектно-ориентированный проект, но на самом деле этого не делают. Оправдания варьируются в пределах от "слишком много хлопот (или у меня нет времени), чтобы делать все правильно" до "строгий объектно-ориентированный проект — это учебное упражнение: на него нет времени в реальной жизни, где вы вынуждены работать быстро и не очень чисто". Возможно, что наиболее возмутительным оправданием, слышанным мной по поводу плохого проекта (в этом случае библиотеки классов), было следующее: "Недостаточное число наших заказчиков знают Си++ достаточно хорошо, чтобы его правильно использовать, поэтому мы спроектировали библиотеку классов так, чтобы ей было легче пользоваться". (В переводе на нормальный язык: "Средние пользователи слишком тупые, чтобы делать все правильно; на самом деле они даже не заинтересованы в том, чтобы научиться работать правильно, и научить их будет очень трудно. Так что мы даже не будем делать ни того, ни другого. Мы просто оглупим свой продукт"). Проблема была отягощена учебным руководством, которое нарушало объектно-ориентированные принципы налево и направо, и, к сожалению, это руководство используется тысячами программистов, которые не знают ничего лучшего в качестве примера того, как написать приложение при помощи этой библиотеки классов. Они вполне разумно ожидают, что руководство покажет им, как сделать все правильно, поэтому они никогда не подозревают, что все было намеренно сделано неверно, чтобы сделать руководство "более понятным".


Си++ —
язык трудный как для изучения, так и для использования. При написании программ на Си++ столько тонкостей, что даже опытные программисты временами их забывают. Кроме того, даже простой поиск достаточного количества программистов на Си++, чтобы писать, и значительно меньшего, чтобы сопровождать ваш код — трудный процесс. Вы вводите себя в заблуждение, если верите, что Си++ может быть использован безыскусно. Слишком просто для неопытного программиста сделать что-нибудь неправильно и даже не знать об этом, способствуя бесполезным затратам времени на выслеживание ошибки, которая и так хорошо видна. Многие ошибки такого типа даже проникают необнаруженными через этап тестирования и попадают в конечный продукт, делая сопровождение сомнительным предприятием.
Зачем же вообще использовать Си++? Ответ состоит в том, что должным образом использованный
Си++ дает вам существенные выгоды в сопровождении. Вы можете делать значительные изменения в поведении программы (типа перевода всей программы с английского языка на японский или переноса в другую операционную среду) при помощи незначительных изменений в исходном коде, ограниченных малым уголком этого кода. Подобные изменения в структурной системе обычно потребуют модификации поистине каждой функции в программе.
Однако если вы не придерживаетесь правил, то вы в итоге получите в свое распоряжение недостатки обоих систем. Структурные проекты обычно имеют проблемы с отношениями сцепления, которые не встречаются в хорошем объектно-ориентированном проекте, но если вы остановитесь на полдороге, многие из этих ошибок будут скрыты в классах, где их будет трудно найти. Кроме того, многие объектно-ориентированные проекты обычно бывают очень сложными, а взаимоотношения между объектами иногда непредсказуемы. (Это также одно из главных преимуществ методологии: возможно моделирование системы такой сложности, что ее поведение заранее предсказать невозможно). Инструменты типа диаграмм объектов становятся необходимыми, потому что если эта система не работает, то вероятнее всего причина в потоке сообщений. Если не работает индивидуальный объект, то его легко исправить при условии, что его интерфейс корректен, потому что изменения будут ограничены определением одного класса. Когда вы делаете что-то неверно, то эти проблемы становится очень тяжело выследить, потому что для передачи информации используются тайные ходы, а изменения в одном классе могут передаваться в другие.
Поэтому, если у вас "нет времени, чтобы делать все правильно", то вам гораздо лучше остановиться на структурном проектировании и простой реализации на языке Си. Будет проще искать ошибки, потому что код более однороден, и у вас не будет дополнительных сложностей с системой передачи сообщений, сбивающей с толку. Введение упрощений сегодня может сделать программу "типа объектно-ориентированной" неподдающейся сопровождению год спустя: вам придется выбросить всю программу и начать сначала. Перспектива лучшего сопровождения может реализоваться, лишь если вы следуете правилам.
Так как эта книга не является книгой по ОО-проектированию, то я отсылаю вас к книге Буча, упомянутой во введении к этой главе, если вам нужно познакомиться с процессом объектно-ориентированного проектирования. Эта книга рассматривает правила, которые облегчают протекание этого процесса.

Содержание раздела