如何在Java中实现方法链?

2022-08-31 16:51:08

我想在Java中实现方法链接。

我怎样才能实现它?

也让我知道什么时候使用它。

public class Dialog {

     public Dialog() {

     }

     public void setTitle(String title) {

         //Logic to set title in dialog
     }

     public void setMessage(String message) {

         //Logic to set message
     }     

     public void setPositiveButton() {

         //Logic to send button
     }
}   

我想创建可以按如下方式使用的方法链接:

new Dialog().setTitle("Title1").setMessage("sample message").setPositiveButton();

或类似

new Dialog().setTitle("Title1").setMessage("sample message");

或类似

new Dialog().setTitle("Title1").setPositiveButton();

答案 1

让你的方法返回如下:this

public Dialog setMessage(String message)
{
    //logic to set message
    return this;
}

这样,在每次调用其中一个方法后,您将获得返回的相同对象,以便您可以调用另一个方法。

当您想要在对象上调用一系列方法时,此技术很有用:它减少了实现该目标所需的代码量,并允许您在方法链之后具有单个返回值。

减少显示对话框所需的代码量的示例如下:

// Your Dialog has a method show() 
// You could show a dialog like this:
new Dialog().setMessage("some message").setTitle("some title")).show();

使用单个返回值的示例如下:

// In another class, you have a method showDialog(Dialog)
// Thus you can do:
showDialog(new Dialog().setMessage("some message").setTitle("some title"));

使用 Builder 模式的示例,Dennis 在对您的问题的评论中提到的示例:

new DialogBuilder().setMessage("some message").setTitle("some title").build().show();

生成器模式允许您在构建对象之前为类的新实例设置所有参数(考虑具有字段的类,或者一些对象,在构建对象后为其设置值比在构造对象时设置值的成本更高)。final

在上面的示例中:,属于该类并返回它们被调用的相同实例;该方法属于该类,但返回一个对象,该方法属于该类。setMessage(String)setTitle(String)DialogBuilderDialogBuilderbuild()DialogBuilderDialogshow()Dialog

额外

这可能与您的问题无关,但它可能会对您和遇到此问题的其他人有所帮助。

这适用于大多数用例:所有不涉及继承的用例和一些涉及继承的特定用例,当派生类不添加您要链接在一起的新方法并且您对使用(不强制转换)方法链的结果作为派生的对象不感兴趣时。

如果希望对基类中没有方法的派生类的对象使用方法链接,或者希望方法链将对象作为派生类的引用返回,则可以查看此问题的答案


答案 2

只需添加一个静态生成器方法,然后创建另一组 setter 方法。例如

class Model {
   private Object FieldA;

   private Object FieldB;

   public static Model create() {
       return new Model();
   }

   public Model withFieldA(Object value) {
       setFieldA(value);
       return this;
   }

   public Model withFieldB(Object value) {
       setFieldB(value);
       return this;
   }
}

...

并像这样使用它

 Model m = Model.create().withFieldA("AAAA").withFieldB(1234);