| 2. Выдох под водой | |
| К сожалению, при проектировании архитектуры не существует четкой последовательности действий, которая приводила бы к оптимальному результату. Даже самый опытный программист-архитектор не способен избежать всех возможных подводных камней, которые обязательно рано или поздно всплывут на поверхность. Что же касается рядовых программистов — их участь вообще весьма плачевна в случае если они задумают заняться проектированием. | |
| Конечно же, строить правильную композицию сущностей, правильно объединять более мелкие сущности в более крупные и вообще, правильно программировать, вам поможет только опыт и здравый смысл. Однако, существуют некоторые правила, придерживаясь которых вы сможете обезопасить себя от некоторых проблем и на более ранних этапах (или при недостатке здравого смысла). | |
| Первая рекомендация, которую вам даст любой тренер по плаванию, состоит в том, что во время плавания выдыхать нужно под водой. И окажется прав, хотя человеку абсолютно все равно, куда он делает выдох — под воду или в воздух, это никак не сказывается на его физическом развитии. Суть здесь в следующем. Выдыхая под водой, человек тем самым контролирует ритм своего дыхания — вдох на воздухе, выдох под водой. А вот правильное дыхание уже и является ключом к успеху. Если вы когда-нибудь занимались бегом на большие дистанции, то вы помните, что во время бега вам самим приходится контролировать дыхание — никаких внешних факторов, заставляющих вас дышать определенным образом, как например в бассейне, нет. Выдох под водой — это правило, которое косвенным образом позволяет вам держать дыхание в нужном ритме. Подобные правила есть и в программировании. |  Авдиенко Виктор Борисович. Заслуженный тренер СССР и России. |
| | |
| Кросс-платформенность | |
| Пишите программу не привязываясь к платформе. Даже если вы точно знаете, что ей уготована жизнь только в определенной операционной системе. При этом и не думайте надеяться на кросс-платформенность используемых API и библиотек (за исключением, быть может, только библиотеки boost). Для всего «внешнего мира» делайте свои «обертки». Весь платформно-зависимый код локализуйте и выносите в отдельные файлы-имплементации. Кроме того, не делайте никаких завязок и даже предположений относительно любых платформно-зависимых понятий, таких как размер и значение указателя, порядок байт в машинном слове, конвенции вызова функций, и так далее. | |
| Широко применяйте идиому «pimpl». Не давайте пользователю вашего кода ни единого шанса завязаться на какие-то платформно-зависимые интерфейсы или сущности. Собственные интерфейсы базируйте на наиболее естественных с точки зрения языка понятиях — базовых типах, а также типах библиотек STL и boost. Используйте ссылки вместо указателей там, где вам не требуется работа с массивами. | |
| | |
| Безопасность с точки зрения многопоточности | |
| Старайтесь программировать безопасным с точки зрения многопоточности способом, даже если вы точно знаете, что в вашей программе никогда не будет более одного потока. Речь, естественно, идет не о том, чтобы обкладываться с ног до головы мутексами, семафорами и прочими объектами синхронизации. Речь, прежде всего, о безопасности с точки зрения используемых языковых конструкций. Минимизируйте число глобальных переменных и объектов, избегайте необоснованного использования статических переменных и объектов, не используйте синглтоны там, где они реально не нужны. | |
| Минимизируйте число конкурирующих точек (логических элементов, обращающихся к одним и тем же ресурсам параллельно), однако при этом избегайте искусственных приемов — стремитесь программировать таким образом, чтобы минимальное число конкурирующих точек было естественным результатом вашей деятельности. | |
| | |
| Безопасность с точки зрения исключений | |
| Пишите программы безопасным с точки зрения исключений способом, даже если вы уверены, что в вашей программе не может быть исключений (что, кстати, является заблуждением). Каждый раз, вызывая очередную функцию, представьте себе, что она сгенерировала исключение, и подумайте, как вы сможете обезопасить себя в этом случае. При этом избегайте «ремонта» программы в блоках обработки исключений — программа должна «приходить в себя» естественным способом. В блоках обработки должно быть (точнее, к этому нужно стремиться) лишь оповещение об исключении (ошибке). | |
| Старайтесь при имплементации функциональности придерживаться семантики транзакций. Повсеместно применяйте идиому владения. Не используйте выделение и освобождение каких-либо ресурсов, не защищенные этой идиомой, будь то работа с указателями, хендлами или какими-то иными сущностями, обеспечивающими дополнительный уровень косвенности. | |
| Минимизируйте число сущностей с глобальной точкой доступа. Старайтесь писать такие const-функции, которые не только не модифицируют сам объект, но и оставляют нетронутыми вообще весь контекст приложения. | |
| | |
| Семантика | |
| Старайтесь насыщать семантикой весь программный код, в то же время сохраняя его естественным с точки зрения языка. | |
| Не берите правила с потолка, не используйте правила, известные только вам. Старайтесь выдерживать код наиболее естественным с точки зрения языка способом. «Говорите» на языке программирования кратко и по делу, не отвлекайтесь на вещи, не имеющие отношения к текущей задаче, не сообщайте информацию, не влияющую на результат. | |
| Помните, что семантика важнее, чем десяток сэкономленных тактов процессорного времени. | |
| Операторы имеют очень ярко выраженную семантику. Перегружайте операторы только тогда, когда их логика предельна ясна и однозначна. Не перегружайте операторы, если результат их работы для указанных типов не очевиден или не однозначен. Вместо этого реализовывайте соответствующие функции. | |
| Помните, что лучший код это код, понятный без комментариев. | |
| | |
| Не делайте исключений из правил | |
| Исключения из правил подтверждают сами правила только в обычной жизни. Никогда не руководствуйтесь этим правилом в программировании. Постарайтесь минимизировать использование модификатора mutable, очень постарайтесь исключить const_cast (не говоря уже о reinterpret_cast и самом неприятном — так называемом c-style cast), избегайте приведений вниз по иерархии классов, и вообще, избегайте любых попыток обмануть компилятор. Если у вас возникла необходимость в каком-то конкретном месте «нарушить покой», скорее всего это означает что вы где-то ошиблись. Считайте это правило исключением из правила «Исключения из правил подтверждают сами правила». | |