Читаем Чистый код. Создание, анализ и рефакторинг полностью

                e.printStackTrace();

            }

        }

    };

    Thread clientConnection = new Thread(clientHandler);

    clientConnection.start();

}

Допустим, в результате внесенных изменений тест проходит[78]; задача решена, верно?

<p>Анализ серверного кода</p>

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

Сколько потоков может создать наш сервер? Код не устанавливает ограничений, поэтому сервер вполне может столкнуться с ограничениями, установленными виртуальной машиной Java ( JVM). Для многих простых систем этого достаточно. А если система обслуживает огромное количество пользователей в общедоступной сети? При одновременном подключении слишком многих пользователей система «заглохнет».

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

• Управление подключением к сокетам.

• Обработка клиентских запросов.

• Политика многопоточности.

• Политика завершения работы сервера.

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

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

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

public void run() {

  while (keepProcessing) {

   try {

    ClientConnection clientConnection = connectionManager.awaitClient();

    ClientRequestProcessor requestProcessor

      = new ClientRequestProcessor(clientConnection);

    clientScheduler.schedule(requestProcessor);

    } catch (Exception e) {

      e.printStackTrace();

    }

  }

  connectionManager.shutdown();

}

Все аспекты, относящиеся к многопоточности, теперь собраны в объекте clientScheduler. Если в приложении возникнут многопоточные проблемы, искать придется только в одном месте:

public interface ClientScheduler {

    void schedule(ClientRequestProcessor requestProcessor);

}

Текущая политика реализуется легко:

public class ThreadPerRequestScheduler implements ClientScheduler {

    public void schedule(final ClientRequestProcessor requestProcessor) {

        Runnable runnable = new Runnable() {

            public void run() {

                requestProcessor.process();

            }

        };

       Thread thread = new Thread(runnable);

       thread.start();

    }

}

Изоляция всего многопоточного кода существенно упрощает внесение любых изменений в политику управления потоками. Например, чтобы перейти на инфраструктуру Java 5 Executor, достаточно написать новый класс и подключить его к существующему коду (листинг А.1).

Листинг А.1. ExecutorClientScheduler.java

import java.util.concurrent.Executor;

import java.util.concurrent.Executors;

public class ExecutorClientScheduler implements ClientScheduler {

    Executor executor;

    public ExecutorClientScheduler(int availableThreads) {

        executor = Executors.newFixedThreadPool(availableThreads);

    }

    public void schedule(final ClientRequestProcessor requestProcessor) {

Перейти на страницу:

Все книги серии Библиотека программиста

Программист-фанатик
Программист-фанатик

В этой книге вы не найдете описания конкретных технологий, алгоритмов и языков программирования — ценность ее не в этом. Она представляет собой сборник практических советов и рекомендаций, касающихся ситуаций, с которыми порой сталкивается любой разработчик: отсутствие мотивации, выбор приоритетов, психология программирования, отношения с руководством и коллегами и многие другие. Подобные знания обычно приходят лишь в результате многолетнего опыта реальной работы. По большому счету перед вами — ярко и увлекательно написанное руководство, которое поможет быстро сделать карьеру в индустрии разработки ПО любому, кто поставил себе такую цель. Конечно, опытные программисты могут найти некоторые идеи автора достаточно очевидными, но и для таких найдутся темы, которые позволят пересмотреть устоявшиеся взгляды и выйти на новый уровень мастерства. Для тех же, кто только в самом начале своего пути как разработчика, чтение данной книги, несомненно, откроет широчайшие перспективы. Издательство выражает благодарность Шувалову А. В. и Курышеву А. И. за помощь в работе над книгой.

Чед Фаулер

Программирование, программы, базы данных / Программирование / Книги по IT

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных