什么是 "环绕执行 "的成语?[英] What is the "Execute Around" idiom?

本文是小编为大家收集整理的关于什么是 "环绕执行 "的成语?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我一直在听到的"围绕"(或类似)的"执行"是什么? 我为什么要使用它,为什么我不想使用它?

推荐答案

基本上,这是您编写一种方法来执行始终需要的事情的模式,例如资源分配和清理,并使呼叫者通过"我们要使用资源来做的事情".例如:

public interface InputStreamAction
{
    void useStream(InputStream stream) throws IOException;
}

// Somewhere else    

public void executeWithFile(String filename, InputStreamAction action)
    throws IOException
{
    InputStream stream = new FileInputStream(filename);
    try {
        action.useStream(stream);
    } finally {
        stream.close();
    }
}

// Calling it
executeWithFile("filename.txt", new InputStreamAction()
{
    public void useStream(InputStream stream) throws IOException
    {
        // Code to use the stream goes here
    }
});

// Calling it with Java 8 Lambda Expression:
executeWithFile("filename.txt", s -> System.out.println(s.read()));

// Or with Java 8 Method reference:
executeWithFile("filename.txt", ClassName::methodName);

通话代码不必担心打开/清理方面 - 它将通过executeWithFile来照顾.

坦率地说,这在Java中很痛苦,因为封闭是如此W rangy,从Java 8 Lambda表达式开始,就像在许多其他语言中一样(例如C#c#lambda表达式或Groovy),并且自Java 7带有Java 7带有<

尽管"分配和清理"是给出的典型示例,但还有许多其他可能的示例 - 交易处理,记录,执行一些具有更多特权的代码等.它基本上有点像模板方法模式但是没有继承.

其他推荐答案

当您发现自己必须做这样的事情时,使用习惯的执行方式:

//... chunk of init/preparation code ...
task A
//... chunk of cleanup/finishing code ...

//... chunk of identical init/preparation code ...
task B
//... chunk of identical cleanup/finishing code ...

//... chunk of identical init/preparation code ...
task C
//... chunk of identical cleanup/finishing code ...

//... and so on.

为了避免重复始终"围绕"实际任务执行的所有冗余代码,您将创建一个自动照顾它的类:

//pseudo-code:
class DoTask()
{
    do(task T)
    {
        // .. chunk of prep code
        // execute task T
        // .. chunk of cleanup code
    }
};

DoTask.do(task A)
DoTask.do(task B)
DoTask.do(task C)

这个习语将所有复杂的冗余代码移至一个地方,使您的主程序更加可读(和可维护!)

看看这篇文章为c#示例和本文一个C ++示例.

其他推荐答案

an 围绕方法执行是您将任意代码传递给方法的地方,哪个方法可以执行设置和/或拆卸代码,并在之间执行您的代码.

java不是我选择这样做的语言.通过封闭(或lambda表达式)作为参数更为时尚.尽管对象可以说是等同于闭合.

在我看来,围绕方法的执行方式像 control (依赖关系)注射)您每次调用该方法时都可以改变临时.

但也可以将其解释为控制耦合的一个示例(在这种情况下,告诉方法是通过其参数做什么).

本文地址:https://www.itbaoku.cn/post/627452.html

问题描述

What is this "Execute Around" idiom (or similar) I've been hearing about? Why might I use it, and why might I not want to use it?

推荐答案

Basically it's the pattern where you write a method to do things which are always required, e.g. resource allocation and clean-up, and make the caller pass in "what we want to do with the resource". For example:

public interface InputStreamAction
{
    void useStream(InputStream stream) throws IOException;
}

// Somewhere else    

public void executeWithFile(String filename, InputStreamAction action)
    throws IOException
{
    InputStream stream = new FileInputStream(filename);
    try {
        action.useStream(stream);
    } finally {
        stream.close();
    }
}

// Calling it
executeWithFile("filename.txt", new InputStreamAction()
{
    public void useStream(InputStream stream) throws IOException
    {
        // Code to use the stream goes here
    }
});

// Calling it with Java 8 Lambda Expression:
executeWithFile("filename.txt", s -> System.out.println(s.read()));

// Or with Java 8 Method reference:
executeWithFile("filename.txt", ClassName::methodName);

The calling code doesn't need to worry about the open/clean-up side - it will be taken care of by executeWithFile.

This was frankly painful in Java because closures were so wordy, starting with Java 8 lambda expressions can be implemented like in many other languages (e.g. C# lambda expressions, or Groovy), and this special case is handled since Java 7 with try-with-resources and AutoClosable streams.

Although "allocate and clean-up" is the typical example given, there are plenty of other possible examples - transaction handling, logging, executing some code with more privileges etc. It's basically a bit like the template method pattern but without inheritance.

其他推荐答案

The Execute Around idiom is used when you find yourself having to do something like this:

//... chunk of init/preparation code ...
task A
//... chunk of cleanup/finishing code ...

//... chunk of identical init/preparation code ...
task B
//... chunk of identical cleanup/finishing code ...

//... chunk of identical init/preparation code ...
task C
//... chunk of identical cleanup/finishing code ...

//... and so on.

In order to avoid repeating all of this redundant code that is always executed "around" your actual tasks, you would create a class that takes care of it automatically:

//pseudo-code:
class DoTask()
{
    do(task T)
    {
        // .. chunk of prep code
        // execute task T
        // .. chunk of cleanup code
    }
};

DoTask.do(task A)
DoTask.do(task B)
DoTask.do(task C)

This idiom moves all of the complicated redundant code into one place, and leaves your main program much more readable (and maintainable!)

Take a look at this post for a C# example, and this article for a C++ example.

其他推荐答案

An Execute Around Method is where you pass arbitrary code to a method, which may perform setup and/or teardown code and execute your code in between.

Java isn't the language I'd choose to do this in. It's more stylish to pass a closure (or lambda expression) as the argument. Though objects are arguably equivalent to closures.

It seems to me that the Execute Around Method is sort of like Inversion of Control (Dependency Injection) that you can vary ad hoc, every time you call the method.

But it could also be interpreted as an example of Control Coupling (telling a method what to do by its argument, literally in this case).