Что это за идиома «Исполнить вокруг» (или похожая), о которой я слышал? Почему я могу использовать это, и почему я не хочу использовать это?
java
language-agnostic
design-patterns
idioms
Том Хотин - Tackline
источник
источник
Ответы:
По сути, это шаблон, в котором вы пишете метод, который делает вещи, которые всегда требуются, например, выделение ресурсов и очистка, и заставляет вызывающего передать «то, что мы хотим сделать с ресурсом». Например:
Код вызова не должен беспокоиться об открытии / очистке - об этом позаботится
executeWithFile
.Это было откровенно болезненно в Java, потому что замыкания были настолько многословными, начиная с лямбда-выражений Java 8 можно реализовать, как и во многих других языках (например, лямбда-выражения C # или Groovy), и этот особый случай обрабатывается, поскольку Java 7 с
try-with-resources
иAutoClosable
потоков.Хотя типичным примером является «выделение и очистка», существует множество других возможных примеров - обработка транзакций, ведение журнала, выполнение некоторого кода с большим количеством привилегий и т. Д. Это в основном немного похоже на шаблонный шаблон, но без наследования.
источник
Идиома «Выполнить вокруг» используется, когда вам приходится делать что-то вроде этого:
Чтобы избежать повторения всего этого избыточного кода, который всегда выполняется «вокруг» ваших реальных задач, вы должны создать класс, который позаботится об этом автоматически:
Эта идиома перемещает весь сложный избыточный код в одно место и делает вашу основную программу намного более читаемой (и поддерживаемой!)
Взгляните на этот пост для примера C #, и эту статью для примера C ++.
источник
Выполнить Around метод , где вы передаете произвольный код метода, который может выполнять настройку и / или Teardown код и выполнить код между ними.
Ява - не тот язык, на котором я бы выбрал это. Более стильно передать закрытие (или лямбда-выражение) в качестве аргумента. Хотя объекты, возможно, эквивалентны замыканиям .
Мне кажется, что метод Execute Around похож на инверсию контроля (Dependency Injection), который вы можете изменять ad hoc каждый раз, когда вызываете метод.
Но это также может быть истолковано как пример Control Control Coupling (указав метод, что делать по его аргументу, буквально в данном случае).
источник
Я вижу, у вас есть тег Java, поэтому я буду использовать Java в качестве примера, хотя шаблон не зависит от платформы.
Идея состоит в том, что иногда у вас есть код, который всегда включает в себя один и тот же шаблон, прежде чем запускать код и после запуска кода. Хороший пример - JDBC. Вы всегда захватываете соединение и создаете оператор (или подготовленный оператор) перед выполнением фактического запроса и обработкой результирующего набора, а затем всегда выполняете одну и ту же процедуру очистки в конце - закрывая оператор и соединение.
Идея с циклическим выполнением состоит в том, что было бы лучше, если бы вы могли выделить исходный код. Это экономит время при наборе текста, но причина кроется глубже. Здесь принцип «не повторяйся сам» («СУХОЙ») - вы изолируете код в одном месте, поэтому, если есть ошибка, или вам нужно ее изменить, или вы просто хотите ее понять, все это в одном месте.
С этим факторингом немного сложно справиться с тем, что у вас есть ссылки, которые должны видеть и части «до», и «после». В примере JDBC это будет включать в себя оператор соединения и (подготовленный). Таким образом, чтобы справиться с этим, вы, по сути, «оборачиваете» свой целевой код стандартным кодом.
Вы можете быть знакомы с некоторыми распространенными случаями в Java. Один из них - фильтры сервлетов. Другой АОП вокруг совета. Третье - это различные классы xxxTemplate в Spring. В каждом случае у вас есть какой-нибудь объект-обертка, в который вставляется ваш «интересный» код (скажем, JDBC-запрос и обработка набора результатов). Объект-обертка выполняет часть «до», вызывает интересный код, а затем выполняет часть «после».
источник
См. Также Code Sandwiches , который рассматривает эту конструкцию во многих языках программирования и предлагает некоторые интересные исследовательские идеи. Что касается конкретного вопроса о том, почему его можно использовать, в приведенной выше статье предлагается несколько конкретных примеров:
И позже:
В статье не рассматривается, почему не следует использовать эту идиому, но в ней описывается, почему идиома легко ошибиться без помощи уровня языка:
источник
Я постараюсь объяснить, как и четырехлетнему ребенку:
Пример 1
Санта идет в город. Его эльфы кодируют все, что хотят, за его спиной, и если они не меняют вещи, они становятся немного повторяющимися:
Или это:
.... до тошноты миллион раз с миллионом разных подарков: обратите внимание, что единственное отличие - это шаг 2. Если шаг два - это единственное, что отличается, то почему Санта дублирует код, то есть почему он дублирует шаги 1 и 3 миллиона раз? Миллион подарков означает, что он без необходимости повторяет шаги 1 и 3 миллион раз.
Выполнить вокруг помогает решить эту проблему. и помогает устранить код. Шаги 1 и 3 в основном постоянны, что позволяет шагу 2 быть единственной частью, которая изменяется.
Пример № 2
Если вы все еще не получаете его, вот еще один пример: подумайте о сэндвиче: хлеб снаружи всегда один и тот же, но то, что внутри, меняется в зависимости от типа сэндвича, который вы выбираете (например, ветчина, сыр, варенье, арахисовое масло и т. д.). Хлеб всегда снаружи, и вам не нужно повторять это миллиард раз для каждого типа песка, который вы создаете.
Теперь, если вы прочитаете приведенные выше объяснения, возможно, вам будет легче понять. Я надеюсь, что это объяснение помогло вам.
источник
Это напоминает мне шаблон дизайна стратегии . Обратите внимание, что ссылка, на которую я указал, содержит код Java для шаблона.
Очевидно, что можно выполнить «Execute Around», выполнив код инициализации и очистки и просто передав стратегию, которая затем всегда будет заключена в код инициализации и очистки.
Как и в случае любой техники, используемой для уменьшения повторения кода, вы не должны использовать ее, пока у вас не будет хотя бы 2 случаев, когда вам это нужно, возможно, даже 3 (а-ля принцип YAGNI). Имейте в виду, что удаление повторения кода уменьшает обслуживание (меньшее количество копий кода означает меньшее время, затрачиваемое на копирование исправлений для каждой копии), но также увеличивает обслуживание (больше всего кода). Таким образом, цена этого трюка заключается в том, что вы добавляете больше кода.
Этот тип техники полезен не только для инициализации и очистки. Это также хорошо, когда вы хотите упростить вызов своих функций (например, вы можете использовать его в мастере, чтобы кнопки «следующий» и «предыдущий» не нуждались в гигантских операторах case, чтобы решить, что делать, чтобы перейти к следующая / предыдущая страница
источник
Если вы хотите отличные идиомы, вот они:
источник