Выбрать главу

Большинству разработчиков никогда не приходилось создавать такие базовые программные компоненты, а потому они лишь поверхностно разбираются в работе этих «колес». В результате все подобные модули и библиотеки считаются таинственным черным ящиком, который каким-то образом работает. Если вы видите только поверхность воды, этого недостаточно для понимания опасностей, таящихся в ее глубине. Если вы ничего не знаете о создании более низкоуровневого программного обеспечения, это ограничивает вашу способность создавать действительно выдающиеся продукты.

Попытаться изобрести колесо и потерпеть неудачу полезнее успеха с первой же попытки. Уроки, полученные методом проб и ошибок, имеют эмоциональную составляющую, которую простое чтение технической книги не способно создать!

Запоминать факты и читать умные книги важно, но в становлении выдающегося программиста приобретение опыта имеет такое же значение, как накопление фактов. Изобретение колеса так же важно для образования и мастерства программиста, как поднятие тяжестей для культуриста.

Не поддавайтесь очарованию шаблона Singleton

Сэм Сааристе

Шаблон Singleton решает многие ваши проблемы. Вы знаете, что вам нужен единственный экземпляр. Вы получаете гарантию, что этот экземпляр будет инициализирован перед использованием. Архитектура остается простой благодаря наличию глобальной точки доступа. Все прекрасно. Ну что может не понравиться в этом классическом шаблоне проектирования?

Если подумать, то весьма многое. Как ни соблазнительно применение синглтонов, они, как показывает опыт, приносят больше вреда, чем пользы. Они затрудняют тестирование и усложняют сопровождение. К сожалению, это понимание не столь распространено, как хотелось бы, и синглтоны сохраняют свое обаяние для множества программистов. Хотя есть основания задуматься, так ли они хороши:

• Ограничение на число экземпляров класса часто иллюзорно. Во многих случаях утверждение, что в будущем не понадобятся дополнительные экземпляры, ничем не подкреплено. Домыслы в основе архитектуры приложения обязательно приведут к неприятностям в будущем. Технические требования меняются. Хорошая архитектура это учитывает. Синглтоны — нет.

• Синглтоны создают неявные зависимости между концептуально независимыми модулями кода. Беда в том, что, во-первых, эти зависимости незаметны, а во-вторых, создают ненужные связи между модулями. Этот запашок в коде становится острее, когда вы пытаетесь писать модульные тесты, основанные на слабом связывании и возможности выборочно применять реализации-макеты вместо настоящих. Синглтоны не дают осуществлять такое простое моделирование.

• Синглтоны неявно хранят состояние, что опять-таки препятствует модульному тестированию. Модульное тестирование предполагает, что тесты независимы друг от друга, благодаря чему их можно выполнять в любом порядке, а программу можно возвращать в известное состояние перед выполнением каждого модульного теста. Как только появляются синглтоны с изменяемым (mutable) состоянием, обеспечить такие условия может оказаться затруднительно. Кроме того, такое глобально доступное долгоживущее состояние затрудняет интерпретацию кода человеком, особенно в многопоточной среде.

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

Избавление от синглтонов может стать в окончательном итоге сложной задачей:

• Явное уничтожение объектов синглтонов не поддерживается. В отдельных контекстах это может оказаться проблемой, например в архитектуре с подключаемыми модулями, где модуль можно безопасно выгрузить, только если все его объекты удалены из памяти.

• При завершении программы порядок неявной зачистки синглтонов не определен. Это может вызвать проблемы в приложениях, содержащих синглтоны с взаимными зависимостями. При завершении таких приложений одни синглтоны могут продолжать обращаться к другим, которые к тому моменту уже уничтожены.