【问题标题】:Best way for implement method chaining (fluent interface) with model class [closed]使用模型类实现方法链接(流利的接口)的最佳方法[关闭]
【发布时间】:2016-01-14 10:46:59
【问题描述】:

如何在web应用中实现模型类的方法链?

我有干净的 POJO 模型类:

public class MyModel {
    private String property;

    public String getFirstProperty() {
        return property;
    }

    public void setFirstProperty(String firstProperty) {
        this.property = firstProperty + "blah blah";
    }

}

我想添加两个方法。我应该在哪里添加它们?

public MyModel doSomething(String something) {
    property += something + "blah";
    return this;
}

public MyModel doAntyhing(String antyhing) {
    property += antyhing + "blah blah";
    return this;
}

我想像这样使用它们:

MyModel myModel = new MyModel();
myModel.doAntyhing("blah").doAntyhing("blah blah");


在我可怜的、丑陋的解决方案之下。如何做得更好?

第一种方法。简单的方法,但对于模型类来说非常丑陋(它们应该是干净的,没有逻辑应用程序):

public class MyModel {
    private String property;

    public String getFirstProperty() {
        return property;
    }

    public void setFirstProperty(String firstProperty) {
        this.property = firstProperty;
    }

    public MyModel doSomething(String something) {
        property += something + "blah";
        return this;
    }

    public MyModel doAntyhing(String antyhing) {
        property += antyhing;
        return this;
    }
}

我想把这两个方法移到其他类。

public class LogicForMyModel {
    public MyModel doSomething(String something) {
        property += something + "blah";
        return this;
    }

    public MyModel doAntyhing(String antyhing) {
        property += antyhing + "blah blah";
        return this;
    }
}

但是如何连接这两个类呢?也许我应该使用继承或接口?怎么样?

interface ILogicModel {
    public MyModel doSomethingLogic(String something);
    public MyModel doAntyhingLogic(String antyhing);
}

第二种方式。使用“builder”(基于this的解决方案)。

public class MyModel {
    protected String property;

    public String getFirstProperty() {
        return property;
    }

    public void setFirstProperty(String firstProperty) {
        this.property = firstProperty;
    }

    public BuilderMyModel build() {
        return new BuilderMyModel(this);
    }

}

public class BuilderMyModel {
    private MyModel myModel;

    public BuilderMyModel(MyModel myModel) {
        this.myModel = myModel;
    }

    public BuilderMyModel doSomething(String something) {
        myModel.property += something + "blah";
        return this;
    }

    public BuilderMyModel doAntyhing(String antyhing) {
        myModel.property += antyhing + "blah blah";
        return this;
    }
}

然后我可以使用这个(可能 build() 就像 Java 8 中的 stream()):

MyModel myModel = new MyModel();
myModel.build().doAntyhing("blah").doAntyhing("blah blah");

这比第一个更好。但我必须使用方法 build()。我想为 MyModel 而不是 Builder 调用方法(如 C# 中的 LINQ)。

这是做得更好的方法吗?


第三。使用库fluent-interface-proxy。但我不想每天都使用外部库。否则,我必须使用第二种方式的构建方法。

【问题讨论】:

  • 只有当这些方法实际上用于构建模型对象时,才应该使用builder。也许你应该给我们更多关于这些方法会做什么的背景信息。它是具有模型属性之一的简单操作吗?是业务逻辑吗?
  • 我看不出有什么值得讨论的。在一种情况下,您在一个类中实现了某种逻辑,在第二种情况下,您将相同的逻辑分布在两个类中。逻辑没有改变,所以没有一个变体比另一个更好。如果您真的认为,一个类中的方法数量很重要(比类的数量多),那么将方法分布在两个或更多类上。如果没有,好吧,随心所欲。没有真正的区别。

标签: java model-view-controller java-8 fluent-interface method-chaining


【解决方案1】:

您还可以创建如下的函数式接口:

interface ModelModifier {
    void apply(MyModel model);
}

然后,实现一些你需要的修饰符:

static ModelModifier doSomething(String something) {
    return model -> model.setProperty(something + "blah");
}

static ModelModifier doAntyhing(String anything) {
    return model -> model.setAnything(anything);
}

并在某处添加一个应用修饰符的方法,可能直接在 MyModel 类中,如下所示:

void applyModifiers( ModelModifier ... modifiers) {
    Stream.of( modifiers ).forEach( m -> m.apply(this) );
}

现在,你可以打电话了

mymodel.applyModifiers( doSomething( "blah" ), doAnything( "blahblah") );

不完全是方法链,但可以代替方法链使用

【讨论】:

  • doSomething/doAnything 方法应该是静态的才能像这样使用(使用静态导入)。此外,return null 应该被删除,因为您的 apply() 方法具有 void 返回类型。
  • @DidierL 你说得对,我已经解决了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-13
  • 2018-05-17
  • 2021-02-03
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多