Вопрос

Что это за идиома "Выполнить по кругу" (или аналогичная) О которой я слышал?Почему я могу им воспользоваться и почему я могу не захотеть им пользоваться?

Это было полезно?

Решение

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

родовое слово

Вызывающему коду не нужно беспокоиться об открытии / очистке - об этом позаботится executeWithFile.

Это было откровенно болезненно в Java, потому что замыкания были такими многословными, начиная с Java 8 лямбда-выражения могут быть реализованы, как и во многих других языках (например, лямбда-выражения C # или Groovy), и этот особый случай обрабатывается, начиная с Java 7 с помощью try-with-resources и генерировать потоки кодовых кодов.

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

Другие советы

Идиома Execute Around используется, когда вам нужно сделать что-то вроде этого:

родовое слово

Чтобы избежать повторения всего этого избыточного кода, который всегда выполняется «вокруг» ваших реальных задач, вы должны создать класс, который позаботится об этом автоматически:

родовое слово

Эта идиома перемещает весь сложный избыточный код в одно место и делает вашу основную программу более читаемой (и поддерживаемой!)

Прочтите этот пост для примера C # и эту статью дляпример C ++.

Метод Execute Around - это когда вы передаете произвольный код методу, который может выполнять настройкуи / или фрагмент кода и выполнить свой код между ними.

Java - не тот язык, на котором я бы хотел это сделать. Более стильно передать в качестве аргумента замыкание (или лямбда-выражение).Хотя объекты, возможно, эквивалентны замыканиям .

Мне кажется, что метод Execute Around в некотором роде похож на инверсию управления (зависимостьИнъекция), которую вы можете изменять при каждом вызове метода.

Но это также можно интерпретировать как пример Control Coupling (в данном случае буквально сообщая методу, что делать с помощью его аргумента).

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

Идея состоит в том, что иногда у вас есть код, который всегда включает один и тот же шаблон, до запуска кода и после запуска кода. Хороший пример - JDBC. Вы всегда захватываете соединение и создаете оператор (или подготовленный оператор) перед выполнением фактического запроса и обработкой набора результатов, а затем всегда выполняете ту же самую шаблонную очистку в конце - закрывая оператор и соединение.

Идея автономного выполнения состоит в том, что лучше исключить шаблонный код. Это сэкономит вам время на вводе текста, но причина глубже. Здесь используется принцип «не повторяйся» (DRY) - вы изолируете код в одном месте, поэтому, если есть ошибка, или вам нужно ее изменить, или вы просто хотите понять ее, все в одном месте.

Однако при таком факторинге возникает небольшая сложность в том, что у вас есть ссылки, которые необходимо видеть как в частях «до», так и «после». В примере JDBC это будет включать в себя соединение и (подготовленный) оператор. Таким образом, чтобы справиться с этим, вы по существу "оборачиваете" свой целевой код стандартным кодом.

Возможно, вы знакомы с некоторыми типичными случаями использования Java. Один из них - фильтры сервлетов. Другой - АОП вокруг советов. Третий - это различные классы xxxTemplate в Spring. В каждом случае у вас есть некоторый объект-оболочка, в который внедряется ваш «интересный» код (скажем, запрос JDBC и обработка набора результатов). Объект-оболочка выполняет часть «до», вызывает интересующий код, а затем выполняет часть «после».

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

Такие ситуации возникают всякий раз, когда программа манипулирует общими ресурсами.API-интерфейсы для блокировок, сокетов, файлов или подключений к базе данных могут потребовать от программы явного закрытия или освобождения ресурса, который она ранее приобрела.На языке без сборки мусора программист отвечает за выделение памяти до ее использования и освобождение после ее использования.Как правило, различные задачи программирования требуют, чтобы программа внесла изменение, действовала в контексте этого изменения, а затем отменила изменение.Мы называем такие ситуации бутербродами с кодом.

И позже:

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

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

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

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

Это напоминает мне шаблон разработки стратегии . Обратите внимание, что ссылка, на которую я указал, включает код Java для шаблона.

Очевидно, что можно было бы выполнить "Execute Around", создав код инициализации и очистки и просто передав стратегию, которая затем всегда будет заключена в код инициализации и очистки.

Как и любой другой метод, используемый для уменьшения повторения кода, вы не должны использовать его до тех пор, пока у вас не будет хотя бы 2 случаев, когда он вам нужен, возможно, даже 3 (по принципу YAGNI). Помните, что удаление повторения кода сокращает обслуживание (меньшее количество копий кода означает меньше времени, затрачиваемого на копирование исправлений для каждой копии), но также увеличивает объем обслуживания (больше общего кода). Таким образом, цена этого трюка состоит в том, что вы добавляете больше кода.

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

Попробую объяснить, как четырехлетнему ребенку:

Пример 1

Санта едет в город. Его эльфы кодируют все, что хотят, за его спиной, и если они не изменят ситуацию, ситуация становится немного повторяющейся:

  1. Приобретите оберточную бумагу.
  2. Купите Super Nintendo .
  3. Заверните.

Или так:

  1. Приобретите оберточную бумагу.
  2. Купите куклу Барби .
  3. Заверните.

.... до тошноты миллион раз с миллионом разных подарков: обратите внимание, что отличается только шаг 2. Если второй шаг - единственное, что отличается, то почему Санта дублирует код, т.е. почему он продублировал шаги 1 и 3 миллион раз? Миллион подарков означает, что он без нужды повторяет шаги 1 и 3 миллион раз.

Выполнение действий помогает решить эту проблему. и помогает устранить код. Шаги 1 и 3 в основном постоянны, поэтому изменяется только шаг 2.

Пример 2

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

Теперь, если вы прочитаете приведенные выше объяснения, возможно, вам будет легче понять. Надеюсь, это объяснение вам помогло.

Если вам нужны классные идиомы, вот они:

родовое слово
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top