Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
创建可以这样调用的java方法:foo.bar().baz().qux()_Java_Android_Methods_Class Design - Fatal编程技术网

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

创建可以这样调用的java方法:foo.bar().baz().qux(),java,android,methods,class-design,Java,Android,Methods,Class Design,我不确定它确切的调用了什么,但我想知道如何创建一个可以在一次调用中调用多个方法的类。例如,使用android类但这并不重要,您可以一次调用该类的所有方法: AlertDialog.Builder().setItem().setTitle().setPositiveButton().setCancelable() ...etc 我认为这可能有效的唯一方法是,如果每个方法都返回this,但这似乎会导致问题。我不知道怎么做,但似乎会 另外,这项技术有名字吗?这项技术被称为,它的工作原理和你想象的完

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


AlertDialog.Builder().setItem().setTitle().setPositiveButton().setCancelable() ...etc
我认为这可能有效的唯一方法是,如果每个方法都返回
this
,但这似乎会导致问题。我不知道怎么做,但似乎会


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

这项技术被称为,它的工作原理和你想象的完全一样。您只需让函数返回
,而不是
无效

,它不会引起问题。返回
是实现此目的的标准做法

Java
StringBuilder
就是一个例子。()


据说这样的类有一个

,其背后的思想是返回对
this
的引用。让我们看一个简单的例子:

class A{
    public A setStuffs(){
        return this;
    }
    public A setOtherStuffs(){
        return this;
    }
}
然后你可以做:

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

在使用生成器模式的类中,如
AlertDialog.Builder
,您将看到这一点。但是,我通常在我做的每一个类中都这样做,因为它帮助我保存代码行。

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

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

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

class MyCoolChainingObject{

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

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


我一直称这种物体为“建筑者”

请注意,好的设计往往在末尾有一个.build()调用,以返回您正在构建的实例


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

每个描述方法链接的人都举例说明了实现这一点的完全合理的方法,但仅当您的函数不需要返回某些内容时。如果你想退货怎么办

一个(尽管很糟糕)的解决方案是使用ReturnThis的布尔参数重载所有方法,该参数调用函数,然后返回这个。但是,我绝对推荐使用builder模式来代替此模式

或者!采用按位参数选择要执行的函数的函数!(这是一个糟糕的解决方案!)

还是这样!使用C#并创建一个方法,该方法接受委托(函数指针)的参数数组,并在数组上循环并调用它们(甚至更糟!)


这些是我唯一能想到的选择。如果您不能进行方法链接,那么可以选择builder,或者直接在自己的行中调用它们。或者使用上面三个选项中的一个(但如果你在这一步上,确实会对你的需求的有效性产生疑问)。

此外,你也可以使用双括号类实例化hack,使用普通java类,而不是构建总是返回“this”:

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

这里有一个很好的参考--

p.s.如果您正在设计这样的API,我建议您使builder对象不可变。。。。从长远来看,当用户开始传递构建器对象并在不同的线程中使用它们时,它可以节省大量的痛苦。通过将备份数据存储在持久性数据结构的某些类型中,并在末尾添加一个
.create()
AlertDialog=AlertDialog.Builder(){…}.create()我一直使用双括号实例化hack来测试代码。对于生产代码,我避免使用它。。。因为每次您这样做(您正在子类化)时,它都会创建一个新类。这是我宁愿避免的代价。你是第一个,回答的字符数最少=]
AlertDialog.Builder(){{
  setItem();
  setTitle();
  setPositiveButton();
  setCancelable();
   ...etc
}}