Код с запашком

Поделись знанием:
Перейти к: навигация, поиск

Код с запашко́м (код с душко́м, дурно пахнущий код англ. code smell) — термин, обозначающий код с признаками (запахами) проблем в системе. Был введен Кентом Беком[1] и использован Мартином Фаулером в его книге Рефакторинг. Улучшение существующего кода[2].

Запахи кода[⇨] — это ключевые признаки необходимости рефакторинга[3]. Существуют запахи, специфичные как для парадигм программирования, так и для конкретных языков. Основной проблемой, с которой сталкиваются разработчики при борьбе с запахами кода, является то, что критерии своевременности рефакторинга невозможно четко формализовать без апелляции к эстетике и условному чувству прекрасного. Запахи кода это не набор четких правил, а описание мест, на которые нужно обращать внимание при рефакторинге[4]. Они легко обнаруживаются, но при этом не во всех случаях свидетельствуют о проблемах[1].

Код с запашком ведет к распаду кода, разработчики должны стремиться к устранению запашков путём применения однократного или многократного рефакторинга[5]. В процессе рефакторинга происходит избавление от запахов кода, что обеспечивает возможность дальнейшего развития приложения с той же или большей скоростью. Отсутствие регулярного рефакторинга с течением времени способно полностью парализовать проект, поэтому запахи кода необходимо устранять на ранних стадиях[3]. Существуют инструменты поиска и исправления запахов кода[6], однако опыт показывает, что никакие системы показателей не могут соперничать с человеческой интуицией, основанной на информации[7].





Запахи кода

Общие запахи объектно-ориентированного кода

Дублирование кода

Дублирование кода — это использование одинаковых структур кода в нескольких местах. Объединение этих структур позволит улучшить программный код[7].

Примеры дублирования и методы их устранения:

  • Одно и то же выражение присутствует в двух методах одного и того же класса: необходимо применить «Выделение метода» (Extract Method) и вызывать код созданного метода из обеих точек;
  • Одно и то же выражение есть в двух подклассах, находящихся на одном уровне: необходимо применить «Выделение метода» (Extract Method) для обоих классов с последующим «Подъемом поля» (Pull Up Field) или «Формированием шаблона метода» (Form Template Method), если код похож, но не совпадает полностью. Если оба метода делают одно и то же с помощью разных алгоритмов, можно выбрать более четкий из этих алгоритмов и применить «Замещение алгоритма» (Substitute Algorithm);
  • Дублирующийся код находится в двух разных классах: необходимо применить «Выделение класса» (Extract Class) в одном классе, а затем использовать новый компонент в другом[7].

Длинный метод

Среди объектных программ дольше всего живут программы с короткими методами. Чем длиннее процедура, тем труднее её понять. Если у метода хорошее название, то не нужно смотреть его тело[4].

Следует придерживаться эвристического правила: если ощущается необходимость что-то прокомментировать, нужно написать метод. Даже одну строку имеет смысл выделить в метод, если она нуждается в разъяснениях[8].

  • Для сокращения метода достаточно применить «Выделение метода» (Extract Method);
  • Если локальные переменные и параметры препятствуют выделению метода, можно применить «Замену временной переменной вызовом метода» (Replace Temp with Query), «Введение граничного объекта» (Introduce Parametr Object) и «Сохранение всего объекта» (Preserve Whole Object)[4];
  • Условные операторы и циклы свидетельствуют о возможности выделения в отдельный метод. Для работы с условными выражениями подходит «Декомпозиция условных операторов» (Decompose Conditional). Для работы с циклом — «Выделение метода» (Extract Method)[8].

Большой класс

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

  • Для уменьшения класса используется «Выделение класса» (Extract Class) или «Выделение подкласса» (Extract Subclass). При этом следует обращать внимание на общность в названии атрибутов и на то, использует ли класс их все одновременно[4];
  • Если большой класс является классом GUI, может потребоваться переместить его данные и поведение в отдельный объект предметной области. При этом может оказаться необходимым хранить копии некоторых данных в двух местах и обеспечить их согласованность. «Дублирование видимых данных» (Duplicate Observed Data) предлагает путь, которым можно это осуществить[9].

Длинный список параметров

В длинных списках параметров трудно разбираться, они становятся противоречивыми и сложными в использовании. Использование объектов позволяет, в случае изменения передаваемых данных, модифицировать только сам объект. Работая с объектами, следует передавать ровно столько, чтобы метод мог получить необходимые ему данные[9].

  • «Замена параметра вызовом метода» (Replace Parameter with Method) применяется, когда можно получить данные путём вызова метода объекта. Этот объект может быть полем или другим параметром.
  • «Сохранение всего объекта» (Preserve Whole Object) позволяет взять группу данных, полученных от объекта, и заменить их самим объектом.
  • «Введение граничного объекта» (Introduce Parameter Object) применяется, если есть несколько элементов данных без логического объекта[9].

Расходящиеся модификации

Проблема возникает, когда при модификации в системе невозможно выделить определенное место, которое нужно изменить. Это является следствием плохой структурированности ПО[9] или программирования методом копирования-вставки.

  • Если набор методов необходимо изменять каждый раз при внесении определенных модификаций в код, то применяется «Выделение класса» (Extract Class) (Например, три метода меняются каждый раз когда подключается новая БД, а четыре — при добавлении финансового инструмента)[4].

Стрельба дробью

При выполнении любых модификаций приходится вносить множество мелких изменений в большое число классов. «Стрельба дробью» похожа на «Расходящуюся модификацию», но является её противоположностью. Расходящаяся модификация имеет место, когда есть один класс, в котором производится много различных изменений, а «Стрельба дробью» — это одно изменение, затрагивающее много классов[10].

  • Вынести все изменения в один класс позволят «Перемещение метода» (Move Method) и «Перемещение поля» (Move Field);
  • Если нет подходящего класса, то следует создать новый класс;
  • Если это необходимо, следует воспользоваться «Встраиванием класса» (Inline Class)[4].

Завистливые функции

Метод обращается к данным другого объекта чаще, чем к собственным данным[4].

  • «Перемещение метода» (Move Method) применяется, если метод явно следует перевести в другое место;
  • «Выделение метода» (Extract Method) применяется к части метода, если только эта часть обращается к данным другого объекта;
  • Метод использует функции нескольких классов: определяется, в каком классе находится больше всего данных, и метод помещается в класс вместе с этими данными, или с помощью «Выделения метода» (Extract Method) метод разбивается на несколько частей и они помещаются в разные места[11].

Фундаментальное практическое правило гласит: то, что изменяется одновременно, надо хранить в одном месте. Данные и функции, использующие эти данные, обычно изменяются вместе, но бывают исключения[11].

Группы данных

Группы данных, встречающихся совместно, нужно превращать в самостоятельный класс[11].

  • «Выделение метода» (Extract Method) используется для полей;
  • «Введение граничного объекта» (Introduce Parameter Object) или «Сохранение всего объекта» (Preserve Whole Object) для параметров методов[12].

Хорошая проверка: удалить одно из значений данных и проверить, сохранят ли смысл остальные. Если нет, это верный признак того, что данные напрашиваются на объединение их в объект[11].

Одержимость элементарными типами

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

  • «Замена значения данных объектом» (Replace Data Value with Object);
  • «Замена массива объектом» (Replace Array with Object);
  • Если это код типа, то используйте «Замену кода типа классом» (Replace Type Code with Class), «Замену кода типа подклассами» (Replace Type Code with Subclasses) или «Замену кода типа состоянием/стратегией» (Replace Type Code with State/Strategy)[4].

Операторы типа switch

Одним из очевидных признаков объектно-ориентированного кода служит сравнительно редкое использование операторов типа switch (или case). Часто один и тот же блок switch оказывается разбросанным по разным местам программы. При добавлении в переключатель нового варианта приходится искать все эти блоки switch и модифицировать их. Как правило, заметив блок switch, следует подумать о полиморфизме[13].

  • Если switch переключается по коду типа, то следует использовать «Замену кода типа подклассами» (Replace Type Code with Subclasses) или «Замену кода типа состоянием/стратегией» (Replace Type Code with State/Strategy);
  • Может понадобиться «Выделение метода» (Extract Method) и «Перемещение метода» (Move Method) чтобы изолировать switch и поместить его в нужный класс;
  • После настройки структуры наследования следует использовать «Замену условного оператора полиморфизмом» (Replace Conditional with Polymorphism)[4].

Параллельные иерархии наследования

В коде с таким запашком всякий раз при порождении подкласса одного из классов приходится создавать подкласс другого класса[13].

  • Общая стратегия устранения дублирования состоит в том, чтобы заставить экземпляры одной иерархии ссылаться на экземпляры другой иерархии, а затем убрать иерархию в ссылающемся классе c помощью «Перемещения метода» (Move Method) и «Перемещения поля» (Move Field)[13].

Ленивый класс

Класс, затраты на существование которого не окупаются выполняемыми им функциями, должен быть ликвидирован[13].

  • При наличии подклассов с недостаточными функциями попробуйте «Свертывание иерархии» (Collapse Hierarchy);
  • Почти бесполезные компоненты должны быть подвергнуты «Встраиванию класса» (Inline Class)[13].

Теоретическая общность

Этот случай возникает когда на определенном этапе существования программы обеспечивается набор механизмов, который, возможно, потребуется для некоторой будущей функциональности. В итоге программу становится труднее понимать и сопровождать[14].

  • Для незадействованных абстрактных классов используйте «Сворачивание иерархии» (Collapse Hierarhy);
  • Ненужная делегация может быть удалена с помощью «Встраивания класса» (Inline Class);
  • Методы с неиспользуемыми параметрами должны быть подвергнуты «Удалению параметров» (Remove Parameter)[4].

Временное поле

Временные поля — это поля, которые нужны объекту только при определенных обстоятельствах. Такое положение вещей трудно для понимания, так как ожидается, что объекту нужны все его поля[15].

  • Временные поля и весь код, работающий с ними следует поместить в отдельный класс с помощью «Выделения класса» (Extract Class);
  • Удалить условно выполняемый код можно с помощью «Введения объекта Null» (Introduce Null Object) для создания альтернативного компонента[14].

Цепочка вызовов

Цепочка вызовов появляется тогда, когда клиент запрашивает у одного объекта другой объект, другой объект запрашивает еще один объект и т. д. Такие последовательности вызовов означают, что клиент связан с навигацией по структуре классов. Любые изменения промежуточных связей означают необходимость модификации клиента[14].

  • Для удаления цепочки вызовов применяется прием «Сокрытие делегирования» (Hide Delegate)[14].

Посредник

Чрезмерное использование делегирования может привести к появлению классов, у которых большинство методов состоят только из вызова метода другого класса[14].

  • Если большую часть методов класс делегирует другому классу, нужно воспользоваться «Удалением посредника» (Remove Middle Man)[16].

Неуместная близость

«Неуместная близость» возникает тогда, когда классы чаще, чем следовало бы, погружены в закрытые части друг друга[16].

  • Избавиться от «Неуместной близости» можно с помощью «Перемещения метода» (Move Method) и «Перемещения поля» (Move Field);
  • По возможности следует прибегнуть к «Замене двунаправленной связи однонаправленной» (Change Bidirectional Association to Unidirectional), «Выделению класса» (Extract Class) или воспользоваться «Сокрытием делегирования» (Hide Delegate)[16].

Альтернативные классы с разными интерфейсами

Два класса, в которых часть функциональности общая, но методы, реализующие её, имеют разные параметры[17].

  • Применяйте «Переименование метода» (Rename Method) ко всем методам, выполняющим одинаковые действия, но различающимся сигнатурами[16].

Неполнота библиотечного класса

Библиотеки через некоторое время перестают удовлетворять требованиям пользователей. Естественное решение — поменять кое-что в библиотеках, но библиотечные классы не изменять. Следует использовать методы рефакторинга, специально предназначенные для этой цели[17].

  • Если надо добавить пару методов, используется «Введение внешнего метода» (Introduce Foreign Method);
  • Если надо серьезно поменять поведение класса, используется «Введение локального расширения» (Introduce Local Extension)[17].

Классы данных

Классы данных это классы, которые содержат только поля и методы для доступа к ним, это просто контейнеры для данных, используемые другими классами[17].

  • Следует применить «Инкапсуляцию поля» (Encapsulate Field) и «Инкапсуляцию коллекции» (Encapsulate Collection)[4].

Отказ от наследства

Если наследник использует лишь малую часть унаследованных методов и свойств родителя это является признаком неправильной иерархии.

  • Необходимо создать новый класс на одном уровне с потомком и с помощью «Спуска метода» (Push Down Method) и «Спуска поля» (Push Down Field) вытолкнуть в него все бездействующие методы. Благодаря этому в родительском классе будет содержаться только то, что используется совместно[18].

Комментарии

Часто комментарии играют роль «дезодоранта» кода, который появляется в нем лишь потому, что код плохой. Почувствовав потребность написать комментарий, попробуйте изменить структуру кода так, чтобы любые комментарии стали излишними[18].

  • Если для объяснения действий блока все же требуется комментарий, попробуйте применить «Выделение метода» (Extract Method);
  • Если метод уже выделен, но по-прежнему нужен комментарий для объяснения его действия, воспользуйтесь «Переименованием метода» (Rename Method);
  • Если требуется изложить некоторые правила, касающиеся необходимого состояния системы, примените «Введение утверждения» (Introduce Assertion)[18].

См. также

Напишите отзыв о статье "Код с запашком"

Примечания

Литература

  • Fowler Martin. [books.google.ru/books?id=HmrDHwgkbPsC Refactoring. Improving the Design of Existing Code]. — Addison-Wesley, 1999. — ISBN 0-201-48567-2.
  • Фаулер М. Глава 3. Код с душком // Рефакторинг. Улучшение существующего кода = Refactoring: Improving the Design of Existing Code / Пер. с англ. С. Маккавеева. — 1-е изд. — СПб.: Символ-Плюс, 2003. — С. 54—62. — 432 с с. — ISBN 5-93286-045-6.
  • Mantyla M. V., Vanhanen J., Lassenius C [www.csie.ntut.edu.tw/labsdtl/99-1/Bad%20Smells%20-%20Humans%20as%20Code%20Critics.pdf Bad smells-humans as code critics] (англ.) // Software Maintenance, 2004. Proceedings. 20th IEEE International Conference on : журнал. — 2004. — P. 399—408. — ISSN [www.sigla.ru/table.jsp?f=8&t=3&v0=1063-6773&f=1003&t=1&v1=&f=4&t=2&v2=&f=21&t=3&v3=&f=1016&t=3&v4=&f=1016&t=3&v5=&bf=4&b=&d=0&ys=&ye=&lng=&ft=&mt=&dt=&vol=&pt=&iss=&ps=&pe=&tr=&tro=&cc=UNION&i=1&v=tagged&s=0&ss=0&st=0&i18n=ru&rlf=&psz=20&bs=20&ce=hJfuypee8JzzufeGmImYYIpZKRJeeOeeWGJIZRrRRrdmtdeee88NJJJJpeeefTJ3peKJJ3UWWPtzzzzzzzzzzzzzzzzzbzzvzzpy5zzjzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzztzzzzzzzbzzzzzzzzzzzzzzzzzzzzzzzzzzzvzzzzzzyeyTjkDnyHzTuueKZePz9decyzzLzzzL*.c8.NzrGJJvufeeeeeJheeyzjeeeeJh*peeeeKJJJJJJJJJJmjHvOJJJJJJJJJfeeeieeeeSJJJJJSJJJ3TeIJJJJ3..E.UEAcyhxD.eeeeeuzzzLJJJJ5.e8JJJheeeeeeeeeeeeyeeK3JJJJJJJJ*s7defeeeeeeeeeeeeeeeeeeeeeeeeeSJJJJJJJJZIJJzzz1..6LJJJJJJtJJZ4....EK*&debug=false 1063-6773].
  • S. Counsell, R. M. Hierons, H. Hamza, S. Black, and M. Durrand [downloads.hindawi.com/journals/ase/2010/820103.pdf Exploring the Eradication of Code Smells: An Empirical and Theoretical Perspective] (англ.) // Advances in Software Engineering Volume 2010 : журнал. — 2010.

Ссылки

  • [codingcraft.ru/resources/REFACTORING/refactoring.htm Рефакторинг кода]. Codingcraft.ru. Проверено 6 ноября 2013.
  • [codingcraft.ru/resources/REFACTORING/TemporaryField.htm Временное поле (Temporary Field)]. Codingcraft.ru. Проверено 5 ноября 2013.
  • [glan-saratov.ru/2009/02/2-%D0%BF%D1%80%D0%B8%D0%B7%D0%BD%D0%B0%D0%BA%D0%B0-%D0%BA%D0%BE%D0%B4%D0%B0-%D1%81-%D0%B4%D1%83%D1%88%D0%BA%D0%BE%D0%BC/ 2 признака кода с душком: убей его и лови всё молча]. Glan-saratov.ru. Проверено 22 сентября 2013.
  • [martinfowler.com/bliki/CodeSmell.html CodeSmell] (англ.). Martinfowler.com. Проверено 13 октября 2013.
  • [vihv.org/index.php?e=CodeSmells Запахи плохого кода]. Vihv.org. Проверено 13 октября 2013.
  • [xp.1024.info/Articles/CodeSmells.html Экстремальное программирование по-русски, дурно пахнущий код]. xp.1024.info. Проверено 26 октября 2013.
  • [c2.com/cgi/wiki?CodeSmell Code Smell] (англ.). Cunningham & Cunningham, Inc. (c2.com). Проверено 23 ноября 2013.
  • Андрей Вокин. [2012.devconf.ru/offers/77 Рефакторинг и анализ Ruby и Rails кода]. DevConf. devconf.ru (9 июня 2012). Проверено 22 декабря 2013.

Отрывок, характеризующий Код с запашком

Вся деятельность его, старательная и энергическая (насколько она была полезна и отражалась на народ – это другой вопрос), вся деятельность его была направлена только на то, чтобы возбудить в жителях то чувство, которое он сам испытывал, – патриотическую ненависть к французам и уверенность в себе.
Но когда событие принимало свои настоящие, исторические размеры, когда оказалось недостаточным только словами выражать свою ненависть к французам, когда нельзя было даже сражением выразить эту ненависть, когда уверенность в себе оказалась бесполезною по отношению к одному вопросу Москвы, когда все население, как один человек, бросая свои имущества, потекло вон из Москвы, показывая этим отрицательным действием всю силу своего народного чувства, – тогда роль, выбранная Растопчиным, оказалась вдруг бессмысленной. Он почувствовал себя вдруг одиноким, слабым и смешным, без почвы под ногами.
Получив, пробужденный от сна, холодную и повелительную записку от Кутузова, Растопчин почувствовал себя тем более раздраженным, чем более он чувствовал себя виновным. В Москве оставалось все то, что именно было поручено ему, все то казенное, что ему должно было вывезти. Вывезти все не было возможности.
«Кто же виноват в этом, кто допустил до этого? – думал он. – Разумеется, не я. У меня все было готово, я держал Москву вот как! И вот до чего они довели дело! Мерзавцы, изменники!» – думал он, не определяя хорошенько того, кто были эти мерзавцы и изменники, но чувствуя необходимость ненавидеть этих кого то изменников, которые были виноваты в том фальшивом и смешном положении, в котором он находился.
Всю эту ночь граф Растопчин отдавал приказания, за которыми со всех сторон Москвы приезжали к нему. Приближенные никогда не видали графа столь мрачным и раздраженным.
«Ваше сиятельство, из вотчинного департамента пришли, от директора за приказаниями… Из консистории, из сената, из университета, из воспитательного дома, викарный прислал… спрашивает… О пожарной команде как прикажете? Из острога смотритель… из желтого дома смотритель…» – всю ночь, не переставая, докладывали графу.
На все эта вопросы граф давал короткие и сердитые ответы, показывавшие, что приказания его теперь не нужны, что все старательно подготовленное им дело теперь испорчено кем то и что этот кто то будет нести всю ответственность за все то, что произойдет теперь.
– Ну, скажи ты этому болвану, – отвечал он на запрос от вотчинного департамента, – чтоб он оставался караулить свои бумаги. Ну что ты спрашиваешь вздор о пожарной команде? Есть лошади – пускай едут во Владимир. Не французам оставлять.
– Ваше сиятельство, приехал надзиратель из сумасшедшего дома, как прикажете?
– Как прикажу? Пускай едут все, вот и всё… А сумасшедших выпустить в городе. Когда у нас сумасшедшие армиями командуют, так этим и бог велел.
На вопрос о колодниках, которые сидели в яме, граф сердито крикнул на смотрителя:
– Что ж, тебе два батальона конвоя дать, которого нет? Пустить их, и всё!
– Ваше сиятельство, есть политические: Мешков, Верещагин.
– Верещагин! Он еще не повешен? – крикнул Растопчин. – Привести его ко мне.


К девяти часам утра, когда войска уже двинулись через Москву, никто больше не приходил спрашивать распоряжений графа. Все, кто мог ехать, ехали сами собой; те, кто оставались, решали сами с собой, что им надо было делать.
Граф велел подавать лошадей, чтобы ехать в Сокольники, и, нахмуренный, желтый и молчаливый, сложив руки, сидел в своем кабинете.
Каждому администратору в спокойное, не бурное время кажется, что только его усилиями движется всо ему подведомственное народонаселение, и в этом сознании своей необходимости каждый администратор чувствует главную награду за свои труды и усилия. Понятно, что до тех пор, пока историческое море спокойно, правителю администратору, с своей утлой лодочкой упирающемуся шестом в корабль народа и самому двигающемуся, должно казаться, что его усилиями двигается корабль, в который он упирается. Но стоит подняться буре, взволноваться морю и двинуться самому кораблю, и тогда уж заблуждение невозможно. Корабль идет своим громадным, независимым ходом, шест не достает до двинувшегося корабля, и правитель вдруг из положения властителя, источника силы, переходит в ничтожного, бесполезного и слабого человека.
Растопчин чувствовал это, и это то раздражало его. Полицеймейстер, которого остановила толпа, вместе с адъютантом, который пришел доложить, что лошади готовы, вошли к графу. Оба были бледны, и полицеймейстер, передав об исполнении своего поручения, сообщил, что на дворе графа стояла огромная толпа народа, желавшая его видеть.
Растопчин, ни слова не отвечая, встал и быстрыми шагами направился в свою роскошную светлую гостиную, подошел к двери балкона, взялся за ручку, оставил ее и перешел к окну, из которого виднее была вся толпа. Высокий малый стоял в передних рядах и с строгим лицом, размахивая рукой, говорил что то. Окровавленный кузнец с мрачным видом стоял подле него. Сквозь закрытые окна слышен был гул голосов.
– Готов экипаж? – сказал Растопчин, отходя от окна.
– Готов, ваше сиятельство, – сказал адъютант.
Растопчин опять подошел к двери балкона.
– Да чего они хотят? – спросил он у полицеймейстера.
– Ваше сиятельство, они говорят, что собрались идти на французов по вашему приказанью, про измену что то кричали. Но буйная толпа, ваше сиятельство. Я насилу уехал. Ваше сиятельство, осмелюсь предложить…
– Извольте идти, я без вас знаю, что делать, – сердито крикнул Растопчин. Он стоял у двери балкона, глядя на толпу. «Вот что они сделали с Россией! Вот что они сделали со мной!» – думал Растопчин, чувствуя поднимающийся в своей душе неудержимый гнев против кого то того, кому можно было приписать причину всего случившегося. Как это часто бывает с горячими людьми, гнев уже владел им, но он искал еще для него предмета. «La voila la populace, la lie du peuple, – думал он, глядя на толпу, – la plebe qu'ils ont soulevee par leur sottise. Il leur faut une victime, [„Вот он, народец, эти подонки народонаселения, плебеи, которых они подняли своею глупостью! Им нужна жертва“.] – пришло ему в голову, глядя на размахивающего рукой высокого малого. И по тому самому это пришло ему в голову, что ему самому нужна была эта жертва, этот предмет для своего гнева.
– Готов экипаж? – в другой раз спросил он.
– Готов, ваше сиятельство. Что прикажете насчет Верещагина? Он ждет у крыльца, – отвечал адъютант.
– А! – вскрикнул Растопчин, как пораженный каким то неожиданным воспоминанием.
И, быстро отворив дверь, он вышел решительными шагами на балкон. Говор вдруг умолк, шапки и картузы снялись, и все глаза поднялись к вышедшему графу.
– Здравствуйте, ребята! – сказал граф быстро и громко. – Спасибо, что пришли. Я сейчас выйду к вам, но прежде всего нам надо управиться с злодеем. Нам надо наказать злодея, от которого погибла Москва. Подождите меня! – И граф так же быстро вернулся в покои, крепко хлопнув дверью.
По толпе пробежал одобрительный ропот удовольствия. «Он, значит, злодеев управит усех! А ты говоришь француз… он тебе всю дистанцию развяжет!» – говорили люди, как будто упрекая друг друга в своем маловерии.
Через несколько минут из парадных дверей поспешно вышел офицер, приказал что то, и драгуны вытянулись. Толпа от балкона жадно подвинулась к крыльцу. Выйдя гневно быстрыми шагами на крыльцо, Растопчин поспешно оглянулся вокруг себя, как бы отыскивая кого то.
– Где он? – сказал граф, и в ту же минуту, как он сказал это, он увидал из за угла дома выходившего между, двух драгун молодого человека с длинной тонкой шеей, с до половины выбритой и заросшей головой. Молодой человек этот был одет в когда то щегольской, крытый синим сукном, потертый лисий тулупчик и в грязные посконные арестантские шаровары, засунутые в нечищеные, стоптанные тонкие сапоги. На тонких, слабых ногах тяжело висели кандалы, затруднявшие нерешительную походку молодого человека.
– А ! – сказал Растопчин, поспешно отворачивая свой взгляд от молодого человека в лисьем тулупчике и указывая на нижнюю ступеньку крыльца. – Поставьте его сюда! – Молодой человек, брянча кандалами, тяжело переступил на указываемую ступеньку, придержав пальцем нажимавший воротник тулупчика, повернул два раза длинной шеей и, вздохнув, покорным жестом сложил перед животом тонкие, нерабочие руки.
Несколько секунд, пока молодой человек устанавливался на ступеньке, продолжалось молчание. Только в задних рядах сдавливающихся к одному месту людей слышались кряхтенье, стоны, толчки и топот переставляемых ног.
Растопчин, ожидая того, чтобы он остановился на указанном месте, хмурясь потирал рукою лицо.
– Ребята! – сказал Растопчин металлически звонким голосом, – этот человек, Верещагин – тот самый мерзавец, от которого погибла Москва.
Молодой человек в лисьем тулупчике стоял в покорной позе, сложив кисти рук вместе перед животом и немного согнувшись. Исхудалое, с безнадежным выражением, изуродованное бритою головой молодое лицо его было опущено вниз. При первых словах графа он медленно поднял голову и поглядел снизу на графа, как бы желая что то сказать ему или хоть встретить его взгляд. Но Растопчин не смотрел на него. На длинной тонкой шее молодого человека, как веревка, напружилась и посинела жила за ухом, и вдруг покраснело лицо.
Все глаза были устремлены на него. Он посмотрел на толпу, и, как бы обнадеженный тем выражением, которое он прочел на лицах людей, он печально и робко улыбнулся и, опять опустив голову, поправился ногами на ступеньке.
– Он изменил своему царю и отечеству, он передался Бонапарту, он один из всех русских осрамил имя русского, и от него погибает Москва, – говорил Растопчин ровным, резким голосом; но вдруг быстро взглянул вниз на Верещагина, продолжавшего стоять в той же покорной позе. Как будто взгляд этот взорвал его, он, подняв руку, закричал почти, обращаясь к народу: – Своим судом расправляйтесь с ним! отдаю его вам!
Народ молчал и только все теснее и теснее нажимал друг на друга. Держать друг друга, дышать в этой зараженной духоте, не иметь силы пошевелиться и ждать чего то неизвестного, непонятного и страшного становилось невыносимо. Люди, стоявшие в передних рядах, видевшие и слышавшие все то, что происходило перед ними, все с испуганно широко раскрытыми глазами и разинутыми ртами, напрягая все свои силы, удерживали на своих спинах напор задних.
– Бей его!.. Пускай погибнет изменник и не срамит имя русского! – закричал Растопчин. – Руби! Я приказываю! – Услыхав не слова, но гневные звуки голоса Растопчина, толпа застонала и надвинулась, но опять остановилась.
– Граф!.. – проговорил среди опять наступившей минутной тишины робкий и вместе театральный голос Верещагина. – Граф, один бог над нами… – сказал Верещагин, подняв голову, и опять налилась кровью толстая жила на его тонкой шее, и краска быстро выступила и сбежала с его лица. Он не договорил того, что хотел сказать.
– Руби его! Я приказываю!.. – прокричал Растопчин, вдруг побледнев так же, как Верещагин.
– Сабли вон! – крикнул офицер драгунам, сам вынимая саблю.
Другая еще сильнейшая волна взмыла по народу, и, добежав до передних рядов, волна эта сдвинула переднии, шатая, поднесла к самым ступеням крыльца. Высокий малый, с окаменелым выражением лица и с остановившейся поднятой рукой, стоял рядом с Верещагиным.
– Руби! – прошептал почти офицер драгунам, и один из солдат вдруг с исказившимся злобой лицом ударил Верещагина тупым палашом по голове.
«А!» – коротко и удивленно вскрикнул Верещагин, испуганно оглядываясь и как будто не понимая, зачем это было с ним сделано. Такой же стон удивления и ужаса пробежал по толпе.
«О господи!» – послышалось чье то печальное восклицание.
Но вслед за восклицанием удивления, вырвавшимся У Верещагина, он жалобно вскрикнул от боли, и этот крик погубил его. Та натянутая до высшей степени преграда человеческого чувства, которая держала еще толпу, прорвалось мгновенно. Преступление было начато, необходимо было довершить его. Жалобный стон упрека был заглушен грозным и гневным ревом толпы. Как последний седьмой вал, разбивающий корабли, взмыла из задних рядов эта последняя неудержимая волна, донеслась до передних, сбила их и поглотила все. Ударивший драгун хотел повторить свой удар. Верещагин с криком ужаса, заслонясь руками, бросился к народу. Высокий малый, на которого он наткнулся, вцепился руками в тонкую шею Верещагина и с диким криком, с ним вместе, упал под ноги навалившегося ревущего народа.
Одни били и рвали Верещагина, другие высокого малого. И крики задавленных людей и тех, которые старались спасти высокого малого, только возбуждали ярость толпы. Долго драгуны не могли освободить окровавленного, до полусмерти избитого фабричного. И долго, несмотря на всю горячечную поспешность, с которою толпа старалась довершить раз начатое дело, те люди, которые били, душили и рвали Верещагина, не могли убить его; но толпа давила их со всех сторон, с ними в середине, как одна масса, колыхалась из стороны в сторону и не давала им возможности ни добить, ни бросить его.
«Топором то бей, что ли?.. задавили… Изменщик, Христа продал!.. жив… живущ… по делам вору мука. Запором то!.. Али жив?»
Только когда уже перестала бороться жертва и вскрики ее заменились равномерным протяжным хрипеньем, толпа стала торопливо перемещаться около лежащего, окровавленного трупа. Каждый подходил, взглядывал на то, что было сделано, и с ужасом, упреком и удивлением теснился назад.
«О господи, народ то что зверь, где же живому быть!» – слышалось в толпе. – И малый то молодой… должно, из купцов, то то народ!.. сказывают, не тот… как же не тот… О господи… Другого избили, говорят, чуть жив… Эх, народ… Кто греха не боится… – говорили теперь те же люди, с болезненно жалостным выражением глядя на мертвое тело с посиневшим, измазанным кровью и пылью лицом и с разрубленной длинной тонкой шеей.
Полицейский старательный чиновник, найдя неприличным присутствие трупа на дворе его сиятельства, приказал драгунам вытащить тело на улицу. Два драгуна взялись за изуродованные ноги и поволокли тело. Окровавленная, измазанная в пыли, мертвая бритая голова на длинной шее, подворачиваясь, волочилась по земле. Народ жался прочь от трупа.
В то время как Верещагин упал и толпа с диким ревом стеснилась и заколыхалась над ним, Растопчин вдруг побледнел, и вместо того чтобы идти к заднему крыльцу, у которого ждали его лошади, он, сам не зная куда и зачем, опустив голову, быстрыми шагами пошел по коридору, ведущему в комнаты нижнего этажа. Лицо графа было бледно, и он не мог остановить трясущуюся, как в лихорадке, нижнюю челюсть.
– Ваше сиятельство, сюда… куда изволите?.. сюда пожалуйте, – проговорил сзади его дрожащий, испуганный голос. Граф Растопчин не в силах был ничего отвечать и, послушно повернувшись, пошел туда, куда ему указывали. У заднего крыльца стояла коляска. Далекий гул ревущей толпы слышался и здесь. Граф Растопчин торопливо сел в коляску и велел ехать в свой загородный дом в Сокольниках. Выехав на Мясницкую и не слыша больше криков толпы, граф стал раскаиваться. Он с неудовольствием вспомнил теперь волнение и испуг, которые он выказал перед своими подчиненными. «La populace est terrible, elle est hideuse, – думал он по французски. – Ils sont сошше les loups qu'on ne peut apaiser qu'avec de la chair. [Народная толпа страшна, она отвратительна. Они как волки: их ничем не удовлетворишь, кроме мяса.] „Граф! один бог над нами!“ – вдруг вспомнились ему слова Верещагина, и неприятное чувство холода пробежало по спине графа Растопчина. Но чувство это было мгновенно, и граф Растопчин презрительно улыбнулся сам над собою. „J'avais d'autres devoirs, – подумал он. – Il fallait apaiser le peuple. Bien d'autres victimes ont peri et perissent pour le bien publique“, [У меня были другие обязанности. Следовало удовлетворить народ. Много других жертв погибло и гибнет для общественного блага.] – и он стал думать о тех общих обязанностях, которые он имел в отношении своего семейства, своей (порученной ему) столице и о самом себе, – не как о Федоре Васильевиче Растопчине (он полагал, что Федор Васильевич Растопчин жертвует собою для bien publique [общественного блага]), но о себе как о главнокомандующем, о представителе власти и уполномоченном царя. „Ежели бы я был только Федор Васильевич, ma ligne de conduite aurait ete tout autrement tracee, [путь мой был бы совсем иначе начертан,] но я должен был сохранить и жизнь и достоинство главнокомандующего“.
Слегка покачиваясь на мягких рессорах экипажа и не слыша более страшных звуков толпы, Растопчин физически успокоился, и, как это всегда бывает, одновременно с физическим успокоением ум подделал для него и причины нравственного успокоения. Мысль, успокоившая Растопчина, была не новая. С тех пор как существует мир и люди убивают друг друга, никогда ни один человек не совершил преступления над себе подобным, не успокоивая себя этой самой мыслью. Мысль эта есть le bien publique [общественное благо], предполагаемое благо других людей.
Для человека, не одержимого страстью, благо это никогда не известно; но человек, совершающий преступление, всегда верно знает, в чем состоит это благо. И Растопчин теперь знал это.
Он не только в рассуждениях своих не упрекал себя в сделанном им поступке, но находил причины самодовольства в том, что он так удачно умел воспользоваться этим a propos [удобным случаем] – наказать преступника и вместе с тем успокоить толпу.
«Верещагин был судим и приговорен к смертной казни, – думал Растопчин (хотя Верещагин сенатом был только приговорен к каторжной работе). – Он был предатель и изменник; я не мог оставить его безнаказанным, и потом je faisais d'une pierre deux coups [одним камнем делал два удара]; я для успокоения отдавал жертву народу и казнил злодея».
Приехав в свой загородный дом и занявшись домашними распоряжениями, граф совершенно успокоился.
Через полчаса граф ехал на быстрых лошадях через Сокольничье поле, уже не вспоминая о том, что было, и думая и соображая только о том, что будет. Он ехал теперь к Яузскому мосту, где, ему сказали, был Кутузов. Граф Растопчин готовил в своем воображении те гневные в колкие упреки, которые он выскажет Кутузову за его обман. Он даст почувствовать этой старой придворной лисице, что ответственность за все несчастия, имеющие произойти от оставления столицы, от погибели России (как думал Растопчин), ляжет на одну его выжившую из ума старую голову. Обдумывая вперед то, что он скажет ему, Растопчин гневно поворачивался в коляске и сердито оглядывался по сторонам.