Стандарты программирования на С++. 101 правило и рекомендация
Шрифт:
Многие из прочих рекомендаций этого и следующего разделов имеют дело с управлением зависимостями — краеугольным камнем проектирования программного обеспечения и часто повторяющейся в данной книге темой. Остановитесь и задумайтесь над произвольной методикой проектирования программного обеспечения — любой хорошей методикой. Какую бы методику вы ни выбрали, так или иначе вы столкнетесь с ослаблением зависимостей. Наследование? Разрабатываемый код должен делать производный класс как можно менее зависимым от базового класса. Минимизация использования глобальных переменных? Снижает дальнодействующие зависимости, осуществляемые посредством широко видимых разным частям программы данных. Абстракция? Устраняет зависимости
В этом разделе самой важной нам кажется рекомендация 6: "Главное — корректность, простота и ясность".
5. Один объект — одна задача
Концентрируйтесь одновременно только на одной проблеме. Каждый объект (переменная, класс, функция, пространство имен, модуль, библиотека) должны решать одну точно поставленную задачу. С ростом объектов, естественно, увеличивается область их ответственности, но они не должны отклоняться от своего предназначения.
Хорошая идея, будучи высказанной вслух, должна быть пояснена одним предложением. Аналогично, каждая сущность в программе должна иметь одно ясное предназначение.
Объект с разнородными предназначениями обычно несоразмерно трудно использовать, поскольку он представляет собой нечто большее, чем просто сумму решений, сложностей и ошибок составляющих его частей. Такой объект больше по размеру (зачастую без особых на то причин) и сложнее в применении и повторном использовании. Зачастую такие объекты имеют весьма убогий интерфейс для каждого из своих отдельных предназначений, поскольку частичное перекрытие разных областей функциональности приводит к невозможности четкой реализации в каждой из них.
Объекты с разнородными функциями обычно трудны для проектирования и реализации. "Множественная ответственность" зачастую приводит к тому, что количество возможных вариантов поведения и состояния объектов разрастается в соответствии с законами комбинаторики. Предпочтительнее использовать короткие функции с четко указанным единственным предназначением (см. также рекомендацию 39), маленькие классы, предназначенные для решения одной конкретной задачи, и компактные модули с четко очерченными границами.
Абстракции высокого уровня предпочтительно строить из меньших низкоуровневых абстракций. Избегайте объединения нескольких низкоуровневых абстракций в большой низкоуровневый конгломерат. Реализация сложного поведения из набора простых существенно легче решения обратной задачи.
Пример 1.
Пример 2.
[Henney02a] • [Henney02b] • [McConnell93] §10.5 • [Stroustrup00] §3.8, §4.9.4, §23.4.3.1 • [Sutter00] §10, §12, §19, §23 • [Sutter02] §1 • [Sutter04] §37-40
6. Главное — корректность, простота и ясность
Корректность лучше быстроты. Простота лучше сложности. Ясность лучше хитроумия. Безопасность лучше ненадежности (см. рекомендации 83 и 99).
Сложно преувеличить значение простоты проектирования и ясности кода. Люди, которые будут сопровождать ваш код, скажут вам только спасибо за то, что вы сделали ваш код понятным. Кстати, зачастую это будете вы сами — когда будете вспоминать, о чем это вы думали полгода назад и как же работает этот код, который вы тогда написали... Прислушайтесь к следующим словам.
Программа должна быть написана для человека, который будет ее читать, и только попутно — для машины, которая будет ее выполнять.
Пишите программы в первую очередь для людей, и только потом для машин.
Самые дешевые, быстрые и надежные компоненты вычислительной системы — те, которых в ней нет.
Эти отсутствующие компоненты также наиболее точны (они никогда не ошибаются), наиболее надежны (никогда не ломаются) и наиболее просты в разработке, документировании, тестировании и сопровождении. Важность простоты дизайна невозможно переоценить.
Многие из рекомендаций этой книги естественным образом приводят к легко изменяемому дизайну и коду, а ясность является наиболее желанным качеством для программы, которую легко сопровождать. То, что вы не в состоянии понять, вы не сможете уверенно и надежно переделать.
Вероятно, наиболее распространенным соперничеством в данной области является соперничество между ясностью кода и его оптимизацией (см. рекомендации 7, 8 и 9). Когда — не если — вы находитесь перед соблазном преждевременной оптимизации для повышения производительности и, таким образом, пессимизации для повышения ясности, — вспомните, что говорит рекомендация 8: гораздо проще сделать корректную программу быстрой, чем быструю — корректной. Избегайте "темных закутков" языка. Используйте простейшие из эффективных методов.
Пример 1. Избегайте неуместной и/или чересчур хитроумной перегрузки операторов. В одной библиотеке пользовательского графического интерфейса пользователей без нужды заставляют писать
Пример 2. В качестве параметров конструктора лучше использовать именованные, а не временные переменные. Это позволит избежать возможных неоднозначностей объявлений, а также зачастую проясняет назначение вашего кода и тем самым упрощает его сопровождение. Кроме того, часто это просто безопаснее (см. рекомендации 13 и 31).