Шаблон проектирования

Поделись знанием:
(перенаправлено с «Методы проектирования»)
Перейти к: навигация, поиск

Шаблон проектирования или паттерн (англ. design pattern) в разработке программного обеспечения — повторимая архитектурная конструкция, представляющая собой решение проблемы проектирования в рамках некоторого часто возникающего контекста.

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

«Низкоуровневые» шаблоны, учитывающие специфику конкретного языка программирования, называются идиомами. Это хорошие решения проектирования, характерные для конкретного языка или программной платформы, и потому не универсальные.

На наивысшем уровне существуют архитектурные шаблоны, они охватывают собой архитектуру всей программной системы.

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





История

В 1970-е годы архитектор Кристофер Александр составил набор шаблонов проектирования. В области архитектуры эта идея не получила такого развития, как позже в области программной разработки.

В 1987 году Кент Бэк (Kent Beck) и Вард Каннингем (Ward Cunningham) взяли идеи Александра и разработали шаблоны применительно к разработке программного обеспечения для разработки графических оболочек на языке Smalltalk.

В 1988 году Эрих Гамма (Erich Gamma) начал писать докторскую диссертацию при цюрихском университете об общей переносимости этой методики на разработку программ.

В 1989—1991 годах Джеймс Коплин (James Coplien) трудился над разработкой идиом для программирования на C++ и опубликовал в 1991 году книгу Advanced C++ Idioms.

В этом же году Эрих Гамма заканчивает свою докторскую диссертацию и переезжает в США, где в сотрудничестве с Ричардом Хелмом (Richard Helm), Ральфом Джонсоном (Ralph Johnson) и Джоном Влиссидсом (John Vlissides) публикует книгу Design Patterns — Elements of Reusable Object-Oriented Software. В этой книге описаны 23 шаблона проектирования. Также команда авторов этой книги известна общественности под названием «Банда четырёх» (англ. Gang of Four, часто сокращается до GoF). Именно эта книга стала причиной роста популярности шаблонов проектирования.

Плюсы

В сравнении с полностью самостоятельным проектированием, шаблоны обладают рядом преимуществ. Основная польза от использования шаблонов состоит в снижении сложности разработки за счёт готовых абстракций для решения целого класса проблем. Шаблон даёт решению своё имя, что облегчает коммуникацию между разработчиками, позволяя ссылаться на известные шаблоны. Таким образом, за счёт шаблонов производится унификация деталей решений: модулей, элементов проекта, — снижается количество ошибок. Применение шаблонов концептуально сродни использованию готовых библиотек кода. Правильно сформулированный шаблон проектирования позволяет, отыскав удачное решение, пользоваться им снова и снова. Набор шаблонов помогает разработчику выбрать возможный, наиболее подходящий вариант проектирования.[1]

Минусы

Хотя легкое изменение кода под известный шаблон может упростить понимание кода, по мнению Стива Макконнелла, с применением шаблонов могут быть связаны две сложности. Во-первых, слепое следование некоторому выбранному шаблону может привести к усложнению программы. Во-вторых, у разработчика может возникнуть желание попробовать некоторый шаблон в деле без особых оснований.[2]

Многие шаблоны проектирования в объектно-ориентированном проектировании можно рассматривать как идиоматическое воспроизведение элементов функциональных языков[3]. Питер Норвиг утверждает, что 16 из 23 шаблонов, описанных в книге «Банды Четверых», в Lisp или Dylan реализуются существенно проще, чем в С++, либо оказываются незаметны[4]. Пол Грэхэм считает саму идею шаблонов проектирования — антипаттерном, сигналом о том, что система не обладает достаточным уровнем абстракции, и необходима её тщательная переработка[5]. Нетрудно видеть, что само определение шаблона как «готового решения, но не прямого обращения к библиотеке» по сути означает отказ от повторного использования в пользу дублирования. Это, очевидно, может быть неизбежным для сложных систем при использовании языков, не поддерживающих комбинаторы и полиморфизм типов, и это в принципе может быть исключено в языках, обладающих свойством гомоиконичности[en] (хотя и не обязательно эффективно), так как любой шаблон может быть реализован в виде исполнимого кода[6].

Типы шаблонов проектирования

Основные

Название Оригинальное название Описание Описан в Design Patterns
Основные шаблоны (Fundamental)
Шаблон делегирования Delegation pattern Объект внешне выражает некоторое поведение, но в реальности передаёт ответственность за выполнение этого поведения связанному объекту. Н/д
Шаблон функционального дизайна Functional design Гарантирует, что каждый модуль компьютерной программы имеет только одну обязанность и исполняет её с минимумом побочных эффектов на другие части программы. Н/д
Неизменяемый интерфейс Immutable interface Создание неизменяемого объекта. Н/д
Интерфейс Interface Общий метод для структурирования компьютерных программ для того, чтобы их было проще понять. Н/д
Интерфейс-маркер Marker interface В качестве атрибута (как пометки объектной сущности) применяется наличие или отсутствие реализации интерфейса-маркера. В современных языках программирования вместо этого могут применяться атрибуты или аннотации. Н/д
Контейнер свойств Property container Позволяет добавлять дополнительные свойства для класса в контейнер (внутри класса), вместо расширения класса новыми свойствами. Н/д
Event Channel Event channel Расширяет шаблон Publish/Subscribe, создавая централизованный канал для событий. Использует объект-представитель для подписки и объект-представитель для публикации события в канале. Представитель существует отдельно от реального издателя или подписчика. Подписчик может получать опубликованные события от более чем одного объекта, даже если он зарегистрирован только на одном канале. Н/д
Порождающие шаблоны (Creational) — шаблоны проектирования, которые абстрагируют процесс инстанцирования. Они позволяют сделать систему независимой от способа создания, композиции и представления объектов. Шаблон, порождающий классы, использует наследование, чтобы изменять инстанцируемый класс, а шаблон, порождающий объекты, делегирует инстанцирование другому объекту.
Абстрактная фабрика Abstract factory Класс, который представляет собой интерфейс для создания компонентов системы. Да
Строитель Builder Класс, который представляет собой интерфейс для создания сложного объекта. Да
Фабричный метод Factory method Определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс инстанцировать. Да
Отложенная инициализация Lazy initialization Объект, инициализируемый во время первого обращения к нему. Нет
Пул одиночек Multiton Гарантирует, что класс имеет поименованные экземпляры объекта и обеспечивает глобальную точку доступа к ним. Нет
Объектный пул Object pool Класс, который представляет собой интерфейс для работы с набором инициализированных и готовых к использованию объектов. Нет
Прототип Prototype Определяет интерфейс создания объекта через клонирование другого объекта вместо создания через конструктор. Да
Получение ресурса есть инициализация Resource acquisition is initialization (RAII) Получение некоторого ресурса совмещается с инициализацией, а освобождение — с уничтожением объекта. Нет
Одиночка Singleton Класс, который может иметь только один экземпляр. Да
Структурные шаблоны (Structural) определяют различные сложные структуры, которые изменяют интерфейс уже существующих объектов или его реализацию, позволяя облегчить разработку и оптимизировать программу.
Адаптер Adapter / Wrapper Объект, обеспечивающий взаимодействие двух других объектов, один из которых использует, а другой предоставляет несовместимый с первым интерфейс. Да
Мост Bridge Структура, позволяющая изменять интерфейс обращения и интерфейс реализации класса независимо. Да
Компоновщик Composite Объект, который объединяет в себе объекты, подобные ему самому. Да
Декоратор или Wrapper/Обёртка Decorator Класс, расширяющий функциональность другого класса без использования наследования. Да
Фасад Facade Объект, который абстрагирует работу с несколькими классами, объединяя их в единое целое. Да
Единая точка входа Front controller Обеспечивает унифицированный интерфейс для интерфейсов в подсистеме. Front Controller определяет высокоуровневый интерфейс, упрощающий использование подсистемы. Нет
Приспособленец Flyweight Это объект, представляющий себя как уникальный экземпляр в разных местах программы, но по факту не являющийся таковым. Да
Заместитель Proxy Объект, который является посредником между двумя другими объектами, и который реализует/ограничивает доступ к объекту, к которому обращаются через него. Да
Поведенческие шаблоны (Behavioral) определяют взаимодействие между объектами, увеличивая таким образом его гибкость.
Цепочка обязанностей Chain of responsibility Предназначен для организации в системе уровней ответственности. Да
Команда, Action, Transaction Command Представляет действие. Объект команды заключает в себе само действие и его параметры. Да
Интерпретатор Interpreter Решает часто встречающуюся, но подверженную изменениям, задачу. Да
Итератор, Cursor Iterator Представляет собой объект, позволяющий получить последовательный доступ к элементам объекта-агрегата без использования описаний каждого из объектов, входящих в состав агрегации. Да
Посредник Mediator Обеспечивает взаимодействие множества объектов, формируя при этом слабую связанность и избавляя объекты от необходимости явно ссылаться друг на друга. Да
Хранитель Memento Позволяет не нарушая инкапсуляцию зафиксировать и сохранить внутренние состояния объекта так, чтобы позднее восстановить его в этих состояниях. Да
Null Object Null Object Предотвращает нулевые указатели, предоставляя объект «по умолчанию». Нет
Наблюдатель или Publish/subscribe[en] Observer Определяет зависимость типа «один ко многим» между объектами таким образом, что при изменении состояния одного объекта все зависящие от него оповещаются об этом событии. Да
Слуга[en] Servant Используется для обеспечения общей функциональности группе классов. Нет
Спецификация Specification Служит для связывания бизнес-логики. Нет
Состояние State Используется в тех случаях, когда во время выполнения программы объект должен менять своё поведение в зависимости от своего состояния. Да
Стратегия Strategy Предназначен для определения семейства алгоритмов, инкапсуляции каждого из них и обеспечения их взаимозаменяемости. Да
Шаблонный метод Template method Определяет основу алгоритма и позволяет наследникам переопределять некоторые шаги алгоритма, не изменяя его структуру в целом. Да
Посетитель Visitor Описывает операцию, которая выполняется над объектами других классов. При изменении класса Visitor нет необходимости изменять обслуживаемые классы. Да
Простая политика Simple Policy Нет
Event listener Нет
Одноразовый посетитель[en] Single-serving visitor Оптимизирует реализацию шаблона посетитель, который инициализируется, единожды используется, и затем удаляется. Нет
Иерархический посетитель[en] Hierarchical visitor Предоставляет способ обхода всех вершин иерархической структуры данных (напр. древовидной). Нет

Concurrency — Параллелизм

Частные

Шаблоны параллельного программирования (Concurrency)

Используются для более эффективного написания многопоточных программ, и предоставляет готовые решения проблем синхронизации.

Название Оригинальное название Описание
Active Object Active object Служит для отделения потока выполнения метода от потока, в котором он был вызван. Использует шаблоны асинхронный вызов методов и планировщик.
Balking[en] Balking Служит для выполнения действия над объектом только тогда, когда тот находится в корректном состоянии.
Binding properties Комбинирует несколько наблюдателей для обеспечения синхронизации свойств в различных объектах[7]
Обмен сообщениями[en] Messaging pattern, Messaging design pattern (MDP) Позволяет компонентам и приложениям обмениваться информацией (сообщениями).
Блокировка с двойной проверкой Double checked locking Предназначен для уменьшения накладных расходов, связанных с получением блокировки.
Event-based asynchronous[en] Event-Based Asynchronous Адресные проблемы с Асинхронным паттерном, которые возникают в программах с несколькими потоками.[8]
Охраняемая приостановка Guarded suspension Используется для блокировки выполнения действия над объектом только тогда, когда тот находится в корректном состоянии.
Half-Sync/Half-Async
Leaders/followers
Блокировка Lock Один поток блокирует ресурс для предотвращения доступа или изменения его другими потоками.[9]
Монитор Monitor Объект, предназначенный для безопасного использования более чем одним потоком.
Reactor[en] Reactor Предназначен для синхронной передачи запросов сервису от одного или нескольких источников.
Read/write lock[en] Read/write lock Позволяет нескольким потокам одновременно считывать информацию из общего хранилища, но позволяя только одному потоку в текущий момент времени её изменять.
Планировщик Scheduler Обеспечивает механизм реализации политики планирования, но при этом не зависящих ни от одной конкретной политики.
Thread pool[en] Предоставляет пул потоков для обработки заданий, представленных обычно в виде очереди.
Thread-Specific Storage[en] Служит для предоставления различных глобальных переменных для разных потоков.
Однопоточное выполнение Single thread execution Препятствует конкурентному вызову метода, тем самым запрещая параллельное выполнение этого метода.
Кооперативный паттерн Cooperative pattern Обеспечивает механизм безопасной остановки потоков исполнения, используя общий флаг для сигнализирования прекращения работы потоков.

Шаблоны архитектуры системы

Enterprise

Прочие

Другие типы шаблонов

Также на сегодняшний день существует ряд других шаблонов:

  • Carrier Rider Mapper описывают предоставление доступа к хранимой информации
  • Аналитические шаблоны описывают основной подход для составления требований для программного обеспечения (requirement analysis) до начала самого процесса программной разработки
  • Коммуникационные шаблоны описывают процесс общения между отдельными участниками/сотрудниками организации
  • Организационные шаблоны описывают организационную иерархию предприятия/фирмы
  • Антипаттерны (Anti-Design-Patterns) описывают, как не следует поступать при разработке программ, показывая характерные ошибки в дизайне и в реализации

См. также

Напишите отзыв о статье "Шаблон проектирования"

Примечания

  1. Макконнелл, 2005, с. 100-101.
  2. Макконнелл, 2005, с. 101.
  3. [blog.ezyang.com/2010/05/design-patterns-in-haskel/ Design Patterns in Haskell]
  4. [norvig.com/design-patterns/design-patterns.pdf Peter Norvig — Design Patterns in Dynamic Languages (slides)]
  5. [www.paulgraham.com/icad.html Revenge of the Nerds]. — «In the OO world you hear a good deal about "patterns". I wonder if these patterns are not sometimes evidence of case (c), the human compiler, at work. When I see patterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Any other regularity in the code is a sign, to me at least, that I'm using abstractions that aren't powerful enough-- often that I'm generating by hand the expansions of some macro that I need to write.»
  6. Абельсон, Сассман. Структура и интерпретация компьютерных программ (SICP).. цитаты: «Можно строить абстракции процедур и данных, можно использовать функции высших порядков, чтобы охватить общие шаблоны их использования, ... и можно с легкостью реализовывать встроенные языки.» (с.16); «Одна из тех вещей, которых мы должны требовать от мощного языка программирования — это возможность строить абстракции путём присвоения имен общим схемам, а затем прямо работать с этими абстракциями. ... Часто одна и та же схема программы используется с различными процедурами. Для того чтобы выразить эти схемы как понятия, нам нужно строить процедуры, которые принимают другие процедуры как аргументы либо возвращают их как значения.» (с.70); «определение шаблонных схем в виде процедур служит средством абстракции.» (с.263); глава 4.1.5 «Данные как программы» (с.357-360); понятие о «средствах абстракции» и их роли дано на с.25.
  7. [c2.com/cgi/wiki?BindingProperties Binding Properties]
  8. Christian Nagel, Bill Evjen, Jay Glynn, Karli Watson, and Morgan Skinner. Event-based Asynchronous Pattern // Professional C# 2008. — Wiley, 2008. — P. 570–571. — ISBN 0470191376.
  9. [c2.com/cgi/wiki?LockPattern Lock Pattern]
  10. [www.infoq.com/articles/haywood-ddd-no Interview and Book Excerpt: Dan Haywood's Domain-Driven Design Using Naked Objects ]

Литература

  • Джейсон Мак-Колм Смит. [www.williamspublishing.com/Books/978-5-8459-1818-5.html Элементарные шаблоны проектирования] = Elemental Design Patterns. — М.: «Вильямс», 2012. — 304 с. — ISBN 978-5-8459-1818-5.
  • Мартин Фаулер. [www.williamspublishing.com/Books/5-8459-0579-6.html Шаблоны корпоративных приложений (Signature Series)] = Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series). — М.: «Вильямс», 2012. — 544 с. — ISBN 978-5-8459-1611-2.
  • Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес. Приемы объектно-ориентированного проектирования. Паттерны проектирования = Design Patterns: Elements of Reusable Object-Oriented Software. — СПб: «Питер», 2007. — С. 366. — ISBN 978-5-469-01136-1. (также ISBN 5-272-00355-1)
  • Марк Гранд. Шаблоны проектирования в JAVA. Каталог популярных шаблонов проектирования, проиллюстрированных при помощи UML = Patterns in Java, Volume 1. A Catalog of Reusable Design Patterns Illustrated with UML. — М.: «Новое знание», 2004. — С. 560. — ISBN 5-94735-047-5.
  • Крэг Ларман. Применение UML 2.0 и шаблонов проектирования = Applying UML and Patterns : An Introduction to Object-Oriented Analysis and Design and Iterative Development. — М.: «Вильямс», 2006. — С. 736. — ISBN 0-13-148906-2.
  • Стив Макконнелл. Совершенный код = Code complete. — СПб.: Питер, 2005. — С. 896. — (Мастер-класс). — ISBN 5-7502-0064-7, 5-469-00822-3.

Ссылки

  • Ольга Дубина. [citforum.ru/SE/project/pattern/ Обзор паттернов проектирования]. — Обзор нескольких наиболее значительных монографий, посвященных паттернам проектирования информационных систем. Проверено 5 сентября 2006. [www.webcitation.org/619W7dTlR Архивировано из первоисточника 23 августа 2011].
  • [www.perldesignpatterns.com/ Один из многих сайтов с шаблонами проектирования на Perl]
  • [c2.com/cgi/wiki?CategoryPattern Portland Pattern Repository] — список шаблонов проектирования на движке вики
  • [www.XMLPatterns.com/ Структурные шаблоны проектирования в XML]
  • [www.developers.org.ua/archives/a4/2007/02/14/resign-patterns/ Resign Patterns] — проломы проектно-дизориентированного проектирования (пародия на паттерны)
  • [artima.com/lejava/articles/eclipse_culture.html Eclipse’s Culture of Shipping] (англ.) Erich Gamma
  • [www.fluffycat.com/PHP-Design-Patterns/ PHP Design Patterns Reference and Examples]
  • [www.youtube.com/view_play_list?p=67C644F846BB4DED Видео-вебкаст 'Design Patterns'] — вебкаст о шаблонах проектирования, 23 шаблона
  • [www.javenue.info/themes/ood/ Javenue] — Объектно-ориентированное проектирование, паттерны проектирования (шаблоны)
  • [github.com/iluwatar/java-design-patterns java-design-patterns] — Примеры реализации паттернов на java



Отрывок, характеризующий Шаблон проектирования

Я бы выговорил, чтобы все реки были судоходны для всех, чтобы море было общее, чтобы постоянные, большие армии были уменьшены единственно до гвардии государей и т.д.
Возвратясь во Францию, на родину, великую, сильную, великолепную, спокойную, славную, я провозгласил бы границы ее неизменными; всякую будущую войну защитительной; всякое новое распространение – антинациональным; я присоединил бы своего сына к правлению империей; мое диктаторство кончилось бы, в началось бы его конституционное правление…
Париж был бы столицей мира и французы предметом зависти всех наций!..
Потом мои досуги и последние дни были бы посвящены, с помощью императрицы и во время царственного воспитывания моего сына, на то, чтобы мало помалу посещать, как настоящая деревенская чета, на собственных лошадях, все уголки государства, принимая жалобы, устраняя несправедливости, рассевая во все стороны и везде здания и благодеяния.]
Он, предназначенный провидением на печальную, несвободную роль палача народов, уверял себя, что цель его поступков была благо народов и что он мог руководить судьбами миллионов и путем власти делать благодеяния!
«Des 400000 hommes qui passerent la Vistule, – писал он дальше о русской войне, – la moitie etait Autrichiens, Prussiens, Saxons, Polonais, Bavarois, Wurtembergeois, Mecklembourgeois, Espagnols, Italiens, Napolitains. L'armee imperiale, proprement dite, etait pour un tiers composee de Hollandais, Belges, habitants des bords du Rhin, Piemontais, Suisses, Genevois, Toscans, Romains, habitants de la 32 e division militaire, Breme, Hambourg, etc.; elle comptait a peine 140000 hommes parlant francais. L'expedition do Russie couta moins de 50000 hommes a la France actuelle; l'armee russe dans la retraite de Wilna a Moscou, dans les differentes batailles, a perdu quatre fois plus que l'armee francaise; l'incendie de Moscou a coute la vie a 100000 Russes, morts de froid et de misere dans les bois; enfin dans sa marche de Moscou a l'Oder, l'armee russe fut aussi atteinte par, l'intemperie de la saison; elle ne comptait a son arrivee a Wilna que 50000 hommes, et a Kalisch moins de 18000».
[Из 400000 человек, которые перешли Вислу, половина была австрийцы, пруссаки, саксонцы, поляки, баварцы, виртембергцы, мекленбургцы, испанцы, итальянцы и неаполитанцы. Императорская армия, собственно сказать, была на треть составлена из голландцев, бельгийцев, жителей берегов Рейна, пьемонтцев, швейцарцев, женевцев, тосканцев, римлян, жителей 32 й военной дивизии, Бремена, Гамбурга и т.д.; в ней едва ли было 140000 человек, говорящих по французски. Русская экспедиция стоила собственно Франции менее 50000 человек; русская армия в отступлении из Вильны в Москву в различных сражениях потеряла в четыре раза более, чем французская армия; пожар Москвы стоил жизни 100000 русских, умерших от холода и нищеты в лесах; наконец во время своего перехода от Москвы к Одеру русская армия тоже пострадала от суровости времени года; по приходе в Вильну она состояла только из 50000 людей, а в Калише менее 18000.]
Он воображал себе, что по его воле произошла война с Россией, и ужас совершившегося не поражал его душу. Он смело принимал на себя всю ответственность события, и его помраченный ум видел оправдание в том, что в числе сотен тысяч погибших людей было меньше французов, чем гессенцев и баварцев.


Несколько десятков тысяч человек лежало мертвыми в разных положениях и мундирах на полях и лугах, принадлежавших господам Давыдовым и казенным крестьянам, на тех полях и лугах, на которых сотни лет одновременно сбирали урожаи и пасли скот крестьяне деревень Бородина, Горок, Шевардина и Семеновского. На перевязочных пунктах на десятину места трава и земля были пропитаны кровью. Толпы раненых и нераненых разных команд людей, с испуганными лицами, с одной стороны брели назад к Можайску, с другой стороны – назад к Валуеву. Другие толпы, измученные и голодные, ведомые начальниками, шли вперед. Третьи стояли на местах и продолжали стрелять.
Над всем полем, прежде столь весело красивым, с его блестками штыков и дымами в утреннем солнце, стояла теперь мгла сырости и дыма и пахло странной кислотой селитры и крови. Собрались тучки, и стал накрапывать дождик на убитых, на раненых, на испуганных, и на изнуренных, и на сомневающихся людей. Как будто он говорил: «Довольно, довольно, люди. Перестаньте… Опомнитесь. Что вы делаете?»
Измученным, без пищи и без отдыха, людям той и другой стороны начинало одинаково приходить сомнение о том, следует ли им еще истреблять друг друга, и на всех лицах было заметно колебанье, и в каждой душе одинаково поднимался вопрос: «Зачем, для кого мне убивать и быть убитому? Убивайте, кого хотите, делайте, что хотите, а я не хочу больше!» Мысль эта к вечеру одинаково созрела в душе каждого. Всякую минуту могли все эти люди ужаснуться того, что они делали, бросить всо и побежать куда попало.
Но хотя уже к концу сражения люди чувствовали весь ужас своего поступка, хотя они и рады бы были перестать, какая то непонятная, таинственная сила еще продолжала руководить ими, и, запотелые, в порохе и крови, оставшиеся по одному на три, артиллеристы, хотя и спотыкаясь и задыхаясь от усталости, приносили заряды, заряжали, наводили, прикладывали фитили; и ядра так же быстро и жестоко перелетали с обеих сторон и расплюскивали человеческое тело, и продолжало совершаться то страшное дело, которое совершается не по воле людей, а по воле того, кто руководит людьми и мирами.
Тот, кто посмотрел бы на расстроенные зады русской армии, сказал бы, что французам стоит сделать еще одно маленькое усилие, и русская армия исчезнет; и тот, кто посмотрел бы на зады французов, сказал бы, что русским стоит сделать еще одно маленькое усилие, и французы погибнут. Но ни французы, ни русские не делали этого усилия, и пламя сражения медленно догорало.
Русские не делали этого усилия, потому что не они атаковали французов. В начале сражения они только стояли по дороге в Москву, загораживая ее, и точно так же они продолжали стоять при конце сражения, как они стояли при начале его. Но ежели бы даже цель русских состояла бы в том, чтобы сбить французов, они не могли сделать это последнее усилие, потому что все войска русских были разбиты, не было ни одной части войск, не пострадавшей в сражении, и русские, оставаясь на своих местах, потеряли половину своего войска.
Французам, с воспоминанием всех прежних пятнадцатилетних побед, с уверенностью в непобедимости Наполеона, с сознанием того, что они завладели частью поля сраженья, что они потеряли только одну четверть людей и что у них еще есть двадцатитысячная нетронутая гвардия, легко было сделать это усилие. Французам, атаковавшим русскую армию с целью сбить ее с позиции, должно было сделать это усилие, потому что до тех пор, пока русские, точно так же как и до сражения, загораживали дорогу в Москву, цель французов не была достигнута и все их усилия и потери пропали даром. Но французы не сделали этого усилия. Некоторые историки говорят, что Наполеону стоило дать свою нетронутую старую гвардию для того, чтобы сражение было выиграно. Говорить о том, что бы было, если бы Наполеон дал свою гвардию, все равно что говорить о том, что бы было, если б осенью сделалась весна. Этого не могло быть. Не Наполеон не дал своей гвардии, потому что он не захотел этого, но этого нельзя было сделать. Все генералы, офицеры, солдаты французской армии знали, что этого нельзя было сделать, потому что упадший дух войска не позволял этого.
Не один Наполеон испытывал то похожее на сновиденье чувство, что страшный размах руки падает бессильно, но все генералы, все участвовавшие и не участвовавшие солдаты французской армии, после всех опытов прежних сражений (где после вдесятеро меньших усилий неприятель бежал), испытывали одинаковое чувство ужаса перед тем врагом, который, потеряв половину войска, стоял так же грозно в конце, как и в начале сражения. Нравственная сила французской, атакующей армии была истощена. Не та победа, которая определяется подхваченными кусками материи на палках, называемых знаменами, и тем пространством, на котором стояли и стоят войска, – а победа нравственная, та, которая убеждает противника в нравственном превосходстве своего врага и в своем бессилии, была одержана русскими под Бородиным. Французское нашествие, как разъяренный зверь, получивший в своем разбеге смертельную рану, чувствовало свою погибель; но оно не могло остановиться, так же как и не могло не отклониться вдвое слабейшее русское войско. После данного толчка французское войско еще могло докатиться до Москвы; но там, без новых усилий со стороны русского войска, оно должно было погибнуть, истекая кровью от смертельной, нанесенной при Бородине, раны. Прямым следствием Бородинского сражения было беспричинное бегство Наполеона из Москвы, возвращение по старой Смоленской дороге, погибель пятисоттысячного нашествия и погибель наполеоновской Франции, на которую в первый раз под Бородиным была наложена рука сильнейшего духом противника.



Для человеческого ума непонятна абсолютная непрерывность движения. Человеку становятся понятны законы какого бы то ни было движения только тогда, когда он рассматривает произвольно взятые единицы этого движения. Но вместе с тем из этого то произвольного деления непрерывного движения на прерывные единицы проистекает большая часть человеческих заблуждений.
Известен так называемый софизм древних, состоящий в том, что Ахиллес никогда не догонит впереди идущую черепаху, несмотря на то, что Ахиллес идет в десять раз скорее черепахи: как только Ахиллес пройдет пространство, отделяющее его от черепахи, черепаха пройдет впереди его одну десятую этого пространства; Ахиллес пройдет эту десятую, черепаха пройдет одну сотую и т. д. до бесконечности. Задача эта представлялась древним неразрешимою. Бессмысленность решения (что Ахиллес никогда не догонит черепаху) вытекала из того только, что произвольно были допущены прерывные единицы движения, тогда как движение и Ахиллеса и черепахи совершалось непрерывно.
Принимая все более и более мелкие единицы движения, мы только приближаемся к решению вопроса, но никогда не достигаем его. Только допустив бесконечно малую величину и восходящую от нее прогрессию до одной десятой и взяв сумму этой геометрической прогрессии, мы достигаем решения вопроса. Новая отрасль математики, достигнув искусства обращаться с бесконечно малыми величинами, и в других более сложных вопросах движения дает теперь ответы на вопросы, казавшиеся неразрешимыми.
Эта новая, неизвестная древним, отрасль математики, при рассмотрении вопросов движения, допуская бесконечно малые величины, то есть такие, при которых восстановляется главное условие движения (абсолютная непрерывность), тем самым исправляет ту неизбежную ошибку, которую ум человеческий не может не делать, рассматривая вместо непрерывного движения отдельные единицы движения.
В отыскании законов исторического движения происходит совершенно то же.
Движение человечества, вытекая из бесчисленного количества людских произволов, совершается непрерывно.
Постижение законов этого движения есть цель истории. Но для того, чтобы постигнуть законы непрерывного движения суммы всех произволов людей, ум человеческий допускает произвольные, прерывные единицы. Первый прием истории состоит в том, чтобы, взяв произвольный ряд непрерывных событий, рассматривать его отдельно от других, тогда как нет и не может быть начала никакого события, а всегда одно событие непрерывно вытекает из другого. Второй прием состоит в том, чтобы рассматривать действие одного человека, царя, полководца, как сумму произволов людей, тогда как сумма произволов людских никогда не выражается в деятельности одного исторического лица.
Историческая наука в движении своем постоянно принимает все меньшие и меньшие единицы для рассмотрения и этим путем стремится приблизиться к истине. Но как ни мелки единицы, которые принимает история, мы чувствуем, что допущение единицы, отделенной от другой, допущение начала какого нибудь явления и допущение того, что произволы всех людей выражаются в действиях одного исторического лица, ложны сами в себе.
Всякий вывод истории, без малейшего усилия со стороны критики, распадается, как прах, ничего не оставляя за собой, только вследствие того, что критика избирает за предмет наблюдения большую или меньшую прерывную единицу; на что она всегда имеет право, так как взятая историческая единица всегда произвольна.
Только допустив бесконечно малую единицу для наблюдения – дифференциал истории, то есть однородные влечения людей, и достигнув искусства интегрировать (брать суммы этих бесконечно малых), мы можем надеяться на постигновение законов истории.
Первые пятнадцать лет XIX столетия в Европе представляют необыкновенное движение миллионов людей. Люди оставляют свои обычные занятия, стремятся с одной стороны Европы в другую, грабят, убивают один другого, торжествуют и отчаиваются, и весь ход жизни на несколько лет изменяется и представляет усиленное движение, которое сначала идет возрастая, потом ослабевая. Какая причина этого движения или по каким законам происходило оно? – спрашивает ум человеческий.
Историки, отвечая на этот вопрос, излагают нам деяния и речи нескольких десятков людей в одном из зданий города Парижа, называя эти деяния и речи словом революция; потом дают подробную биографию Наполеона и некоторых сочувственных и враждебных ему лиц, рассказывают о влиянии одних из этих лиц на другие и говорят: вот отчего произошло это движение, и вот законы его.
Но ум человеческий не только отказывается верить в это объяснение, но прямо говорит, что прием объяснения не верен, потому что при этом объяснении слабейшее явление принимается за причину сильнейшего. Сумма людских произволов сделала и революцию и Наполеона, и только сумма этих произволов терпела их и уничтожила.
«Но всякий раз, когда были завоевания, были завоеватели; всякий раз, когда делались перевороты в государстве, были великие люди», – говорит история. Действительно, всякий раз, когда являлись завоеватели, были и войны, отвечает ум человеческий, но это не доказывает, чтобы завоеватели были причинами войн и чтобы возможно было найти законы войны в личной деятельности одного человека. Всякий раз, когда я, глядя на свои часы, вижу, что стрелка подошла к десяти, я слышу, что в соседней церкви начинается благовест, но из того, что всякий раз, что стрелка приходит на десять часов тогда, как начинается благовест, я не имею права заключить, что положение стрелки есть причина движения колоколов.
Всякий раз, как я вижу движение паровоза, я слышу звук свиста, вижу открытие клапана и движение колес; но из этого я не имею права заключить, что свист и движение колес суть причины движения паровоза.
Крестьяне говорят, что поздней весной дует холодный ветер, потому что почка дуба развертывается, и действительно, всякую весну дует холодный ветер, когда развертывается дуб. Но хотя причина дующего при развертыванье дуба холодного ветра мне неизвестна, я не могу согласиться с крестьянами в том, что причина холодного ветра есть раэвертыванье почки дуба, потому только, что сила ветра находится вне влияний почки. Я вижу только совпадение тех условий, которые бывают во всяком жизненном явлении, и вижу, что, сколько бы и как бы подробно я ни наблюдал стрелку часов, клапан и колеса паровоза и почку дуба, я не узнаю причину благовеста, движения паровоза и весеннего ветра. Для этого я должен изменить совершенно свою точку наблюдения и изучать законы движения пара, колокола и ветра. То же должна сделать история. И попытки этого уже были сделаны.
Для изучения законов истории мы должны изменить совершенно предмет наблюдения, оставить в покое царей, министров и генералов, а изучать однородные, бесконечно малые элементы, которые руководят массами. Никто не может сказать, насколько дано человеку достигнуть этим путем понимания законов истории; но очевидно, что на этом пути только лежит возможность уловления исторических законов и что на этом пути не положено еще умом человеческим одной миллионной доли тех усилий, которые положены историками на описание деяний различных царей, полководцев и министров и на изложение своих соображений по случаю этих деяний.


Силы двунадесяти языков Европы ворвались в Россию. Русское войско и население отступают, избегая столкновения, до Смоленска и от Смоленска до Бородина. Французское войско с постоянно увеличивающеюся силой стремительности несется к Москве, к цели своего движения. Сила стремительности его, приближаясь к цели, увеличивается подобно увеличению быстроты падающего тела по мере приближения его к земле. Назади тысяча верст голодной, враждебной страны; впереди десятки верст, отделяющие от цели. Это чувствует всякий солдат наполеоновской армии, и нашествие надвигается само собой, по одной силе стремительности.
В русском войске по мере отступления все более и более разгорается дух озлобления против врага: отступая назад, оно сосредоточивается и нарастает. Под Бородиным происходит столкновение. Ни то, ни другое войско не распадаются, но русское войско непосредственно после столкновения отступает так же необходимо, как необходимо откатывается шар, столкнувшись с другим, с большей стремительностью несущимся на него шаром; и так же необходимо (хотя и потерявший всю свою силу в столкновении) стремительно разбежавшийся шар нашествия прокатывается еще некоторое пространство.
Русские отступают за сто двадцать верст – за Москву, французы доходят до Москвы и там останавливаются. В продолжение пяти недель после этого нет ни одного сражения. Французы не двигаются. Подобно смертельно раненному зверю, который, истекая кровью, зализывает свои раны, они пять недель остаются в Москве, ничего не предпринимая, и вдруг, без всякой новой причины, бегут назад: бросаются на Калужскую дорогу (и после победы, так как опять поле сражения осталось за ними под Малоярославцем), не вступая ни в одно серьезное сражение, бегут еще быстрее назад в Смоленск, за Смоленск, за Вильну, за Березину и далее.
В вечер 26 го августа и Кутузов, и вся русская армия были уверены, что Бородинское сражение выиграно. Кутузов так и писал государю. Кутузов приказал готовиться на новый бой, чтобы добить неприятеля не потому, чтобы он хотел кого нибудь обманывать, но потому, что он знал, что враг побежден, так же как знал это каждый из участников сражения.
Но в тот же вечер и на другой день стали, одно за другим, приходить известия о потерях неслыханных, о потере половины армии, и новое сражение оказалось физически невозможным.
Нельзя было давать сражения, когда еще не собраны были сведения, не убраны раненые, не пополнены снаряды, не сочтены убитые, не назначены новые начальники на места убитых, не наелись и не выспались люди.
А вместе с тем сейчас же после сражения, на другое утро, французское войско (по той стремительной силе движения, увеличенного теперь как бы в обратном отношении квадратов расстояний) уже надвигалось само собой на русское войско. Кутузов хотел атаковать на другой день, и вся армия хотела этого. Но для того чтобы атаковать, недостаточно желания сделать это; нужно, чтоб была возможность это сделать, а возможности этой не было. Нельзя было не отступить на один переход, потом точно так же нельзя было не отступить на другой и на третий переход, и наконец 1 го сентября, – когда армия подошла к Москве, – несмотря на всю силу поднявшегося чувства в рядах войск, сила вещей требовала того, чтобы войска эти шли за Москву. И войска отступили ещо на один, на последний переход и отдали Москву неприятелю.
Для тех людей, которые привыкли думать, что планы войн и сражений составляются полководцами таким же образом, как каждый из нас, сидя в своем кабинете над картой, делает соображения о том, как и как бы он распорядился в таком то и таком то сражении, представляются вопросы, почему Кутузов при отступлении не поступил так то и так то, почему он не занял позиции прежде Филей, почему он не отступил сразу на Калужскую дорогу, оставил Москву, и т. д. Люди, привыкшие так думать, забывают или не знают тех неизбежных условий, в которых всегда происходит деятельность всякого главнокомандующего. Деятельность полководца не имеет ни малейшего подобия с тою деятельностью, которую мы воображаем себе, сидя свободно в кабинете, разбирая какую нибудь кампанию на карте с известным количеством войска, с той и с другой стороны, и в известной местности, и начиная наши соображения с какого нибудь известного момента. Главнокомандующий никогда не бывает в тех условиях начала какого нибудь события, в которых мы всегда рассматриваем событие. Главнокомандующий всегда находится в средине движущегося ряда событий, и так, что никогда, ни в какую минуту, он не бывает в состоянии обдумать все значение совершающегося события. Событие незаметно, мгновение за мгновением, вырезается в свое значение, и в каждый момент этого последовательного, непрерывного вырезывания события главнокомандующий находится в центре сложнейшей игры, интриг, забот, зависимости, власти, проектов, советов, угроз, обманов, находится постоянно в необходимости отвечать на бесчисленное количество предлагаемых ему, всегда противоречащих один другому, вопросов.