创建可以像这样调用的java方法:foo.bar().baz().quux()

发布于 2024-09-10 09:11:17 字数 294 浏览 3 评论 0原文

我不确定它的确切名称是什么,但我想知道如何创建一个可以在一次调用中调用多个方法的类。例如,使用 android 类,但这并不重要,您可以一次调用所有类的方法:


AlertDialog.Builder().setItem().setTitle().setPositiveButton().setCancelable() ...etc

我认为这可行的唯一方法是每个方法都返回 this ,但这似乎会引起问题。我不知道如何,但看起来就是这样。

另外,这个技术有名字吗?

I'm not sure what it's called exactly, but I was wondering how you can create a class which you can call multiple methods on in one call. For example, using an android class but it doesn't really matter, you can call all of the class' methods at once:


AlertDialog.Builder().setItem().setTitle().setPositiveButton().setCancelable() ...etc

The only way I can think that this could work is if every method returned this, but that seems like it would cause problems. I'm not sure how, but it just seems like it would.

Also, does this technique have a name?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

狼亦尘 2024-09-17 09:11:17

这种技术称为方法链接,它的工作原理与您想象的完全一样。您只需让函数返回 this 而不是 void 即可。

This technique is called method chaining, and it works exactly as you've imagined. You simply have functions return this instead of void.

轮廓§ 2024-09-17 09:11:17

另外,您也可以使用双括号类实例化技巧和普通的 java 类,而不是构建始终返回“this”的类:

AlertDialog.Builder(){{
  setItem();
  setTitle();
  setPositiveButton();
  setCancelable();
   ...etc
}}

这是一个很好的参考 - http://www.c2.com/cgi/wiki?DoubleBraceInitialization

also, rather than building your class to always return "this", you could also just use the double brace class instantiation hack, with a normal java class:

AlertDialog.Builder(){{
  setItem();
  setTitle();
  setPositiveButton();
  setCancelable();
   ...etc
}}

here's a good reference -- http://www.c2.com/cgi/wiki?DoubleBraceInitialization

空城缀染半城烟沙 2024-09-17 09:11:17

这就是构建器模式
你正在有效地做的是:

AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setIcon(android.R.drawable.icon);
builder.setTitle(R.string.title);
builder.setMessage(R.string.message);
//etc.

That's the Builder Pattern.
What you are effectively doing is:

AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setIcon(android.R.drawable.icon);
builder.setTitle(R.string.title);
builder.setMessage(R.string.message);
//etc.
玉环 2024-09-17 09:11:17

它不会造成问题。返回 this 是实现此目的的标准做法。

Java StringBuilder 就是一个例子。 (查看源码

据说这样的类有一个流畅的界面

It won't cause problems. Returning this is the standard practice to achieve this.

Java StringBuilder is an example. (see source)

It is said that such classes have a fluent interface

秋凉 2024-09-17 09:11:17

这背后的想法是返回对 this 的引用。让我们看一个简单的示例:

class A{
    public A setStuffs(){
        return this;
    }
    public A setOtherStuffs(){
        return this;
    }
}

然后您可以这样做:

A a = new A().setStuffs().setOtherStuffs();

您将在使用 Builder 模式(如 AlertDialog.Builder)的类中看到这一点。但是,我通常在每堂课上都会这样做,因为它可以帮助我节省代码行。

The idea behind this is returning a reference to this. Let's look at a simple example:

class A{
    public A setStuffs(){
        return this;
    }
    public A setOtherStuffs(){
        return this;
    }
}

Then you can do:

A a = new A().setStuffs().setOtherStuffs();

You will see this in classes that use the Builder Pattern like AlertDialog.Builder. But, I usually do it in every class I do, because it help me save lines of code.

疯狂的代价 2024-09-17 09:11:17

我一直将这种对象称为“构建器”。

请注意,好的设计往往在最后有一个 .build() 调用来返回您正在构建的实例。

正如您所建议的,所有中间方法调用都会返回一个构建器对象。如果构建器对象是可变的并且方法调用正在修改某些内部构建器状态,则这可以是“this”。或者,如果构建器对象是不可变的,则每个调用都可以返回一个全新的不可变构建器对象。

I've always called this kind of object a "builder".

Note that the good designs tend have a .build() call at the end to return the instance that you are building.

As you suggest, all of the intermediate method calls return a builder object. This can be "this" if the builder object is mutable and the methods calls are modifying some internal builder state. Alternatively, if the builder object is immutable, the calls could each return a completely new immutable builder object.

空宴 2024-09-17 09:11:17

这称为方法链接,获得该效果的最简单方法是从每个方法返回对象的当前实例

class MyCoolChainingObject{

    public MyCoolChainingObject doSomething(){
        //TODO: Stuff
        return this;
    }

    public MyCoolChainingObject doSomethingElse(){
        //TODO: Stuff
        return this;
    }  
}

......

new MyCoolChainingObject().doSomething().doSomethingElse();

This is called method chaining and the easiest way to gain that effect is to return the current instance of the object from each method...

class MyCoolChainingObject{

    public MyCoolChainingObject doSomething(){
        //TODO: Stuff
        return this;
    }

    public MyCoolChainingObject doSomethingElse(){
        //TODO: Stuff
        return this;
    }  
}

....

new MyCoolChainingObject().doSomething().doSomethingElse();
时光磨忆 2024-09-17 09:11:17

每个描述方法链的人都举例说明了实现此目的的完全合理的方法,但前提是您的函数不需要返回某些内容。如果您想退货怎么办?

一个(尽管很糟糕)的解决方案是使用 ReturnThis 的布尔参数来重载所有方法,它调用该函数,然后返回 this。但是,我肯定会推荐构建器模式来代替它。

或者!一个函数,它接受按位参数来选择您想要执行的函数! (ZOMG,这是一个糟糕的解决方案!)

或者仍然!使用 C# 并创建一个方法,该方法采用委托参数数组(函数指针),然后循环遍历该数组并调用它们(更糟糕的是!)

这些是我能想到的唯一选项。如果您无法进行方法链接,请使用构建器,或者只是在自己的线路上调用它们。或者使用上述三个选项之一(但如果您执行此步骤,则确实会质疑您的要求的有效性)。

Every person who described method chaining exemplified a perfectly reasonable way to achieve this, but only whenever your functions don't need to return something. What if you wanted to return something?

A (albeit poor) solution is to overload all your methods with a boolean argument for ReturnThis, which calls the function, then returns this. However, I'd definitely recommend the builder pattern in lieu of this.

OR! A function that takes a bitwise argument selecting which functions you wish to execute! (ZOMG that's an awful solution!)

OR STILL! Use C# and create a method which takes a parameter array of delegates (function pointers), and loop over the array and call them all (Even worse still!)

These are the only options I could come up with. If you can't do method chaining, go for builder, or just call them all on their own line. Or use one of the three options above (but really call into question the validity of your requirements if you're on this step).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文