Java在特定类上改进构建器模式

Java在特定类上改进构建器模式,java,builder,Java,Builder,目前我有一个实现Builder模式的类,为了可读性,我选择省略一些方法,更准确地说,我只显示username的构建方法 package dao.constraint; import java.util.Arrays; public class AccountConstraint { private Constraint<Range<Integer>> accountIdConstraint; private Constraint<String&g

目前我有一个实现Builder模式的类,为了可读性,我选择省略一些方法,更准确地说,我只显示
username
的构建方法

package dao.constraint;

import java.util.Arrays;

public class AccountConstraint {
    private Constraint<Range<Integer>> accountIdConstraint;
    private Constraint<String> usernameConstraint;
    private Constraint<String> passwordConstraint;
    private Constraint<String> emailConstraint;

    private AccountConstraint(Builder builder) {
        this.accountIdConstraint = builder.accountIdConstraint;
        this.usernameConstraint = builder.usernameConstraint;
        this.passwordConstraint = builder.passwordConstraint;
        this.emailConstraint = builder.emailConstraint;
    }

    public Constraint<Range<Integer>> getAccountIdConstraint() {
        return accountIdConstraint;
    }

    public Constraint<String> getUsernameConstraint() {
        return usernameConstraint;
    }

    public Constraint<String> getPasswordConstraint() {
        return passwordConstraint;
    }

    public Constraint<String> getEmailConstraint() {
        return emailConstraint;
    }

    public Constraint[] getConstraints() {
        return Arrays.asList(this.getAccountIdConstraint(), this.getUsernameConstraint(), this.getPasswordConstraint(), this.getEmailConstraint()).toArray(new Constraint[4]);
    }

    public static class Builder {
        private Constraint<Range<Integer>> accountIdConstraint;
        private Constraint<String> usernameConstraint;
        private Constraint<String> passwordConstraint;
        private Constraint<String> emailConstraint;

        public Builder() {
            this.accountIdConstraint = null;
            this.usernameConstraint = null;
            this.passwordConstraint = null;
            this.emailConstraint = null;
        }

        public Builder username(final String username) {
            this.usernameConstraint = new Constraint<>(Operation.IS, true, username, "username");
            return this;
        }

        public Builder notUsername(final String username) {
            this.usernameConstraint = new Constraint<>(Operation.IS, false, username, "username");
            return this;
        }

        public Builder usernameLike(final String username) {
            this.usernameConstraint = new Constraint<>(Operation.LIKE, true, username, "username");
            return this;
        }

        public Builder usernameNotLike(final String username) {
            this.usernameConstraint = new Constraint<>(Operation.LIKE, false, username, "username");
            return this;
        }

        public AccountConstraint build() {
            return new AccountConstraint(this);
        }
    }
}
包dao.constraint;
导入java.util.array;
公共类AccountConstraint{
私有约束accountIdConstraint;
私有约束-用户名约束;
私有约束密码约束;
私人约束;
私人帐户约束(生成器){
this.accountIdConstraint=builder.accountIdConstraint;
this.usernamesconstraint=builder.usernamesconstraint;
this.passwordConstraint=builder.passwordConstraint;
this.emailConstraint=builder.emailConstraint;
}
公共约束getAccountIdConstraint(){
返回accountIdConstraint;
}
公共约束getUsernameConstraint(){
返回用户名约束;
}
公共约束getPasswordConstraint(){
返回密码约束;
}
公共约束getEmailConstraint(){
返回约束;
}
公共约束[]获取约束(){
返回Arrays.asList(this.getAccountIdConstraint()、this.getUsernameConstraint()、this.getPasswordConstraint()、this.getEmailConstraint()).toArray(新约束[4]);
}
公共静态类生成器{
私有约束accountIdConstraint;
私有约束-用户名约束;
私有约束密码约束;
私人约束;
公共建筑商(){
this.accountIdConstraint=null;
this.usernamesconstraint=null;
this.passwordConstraint=null;
this.emailConstraint=null;
}
公共生成器用户名(最终字符串用户名){
this.usernamesconstraint=新约束(Operation.IS,true,用户名,“username”);
归还这个;
}
公共生成器notUsername(最终字符串用户名){
this.usernamesconstraint=新约束(Operation.IS,false,username,“username”);
归还这个;
}
public Builder usernameLike(最终字符串用户名){
this.usernamesconstraint=新约束(Operation.LIKE,true,username,“username”);
归还这个;
}
公共生成器usernameNotLike(最终字符串用户名){
this.usernamesconstraint=新约束(Operation.LIKE,false,username,“username”);
归还这个;
}
公共帐户约束生成(){
返回新的AccountConstraint(此);
}
}
}
正如您所看到的,
AccountConstraint.Builder.username(字符串s)
AccountConstraint.Builder.notUsername(字符串s)
之间有着非常细微的区别

我希望能够编写类似于
newaccountconstraint.Builder().not(用户名))。但是,据我所知,如果调用Java类中未定义
username(String s)
,则这是无效的Java语法。我也不想再次重复整个
AccountConstraint.Builder()
,以达到
用户名(字符串)
部分。有什么解决办法吗

第二个问题:
AccountConstraint.getConstraints()
是否可以改进或编写得更简单


关于。

在这种情况下,我觉得非常优雅的是使用静态工厂方法编写一个实用程序类,如

public static Constraint userName(...) { ... }
导入静态blabla.Utility.username

然后,您可以用java编写几乎是声明性的人类可读查询。这与用于单元测试的hamcrest库非常相似,您可以在其中编写类似的内容

Assert.assertThat(blabla, is(equalTo(nullValue()));
在这种情况下,
Not
应该实现
Constraint
,并像这样否定嵌套(引用)约束:

public static Constraint not(Constraint negated) { return new Not(negated); }
这会产生类似代码的结果

PreparedStatement ps = new QueryBuilder()
 .select()
 .from(table("accounts")
 .where(not(username(equalTo("blabla")))
 .compile();
您可以为布尔组合添加静态工厂:

.where(and(
  .not(...),
  .not(or(...))

定义这样的约束(静态工厂方法,而不是将它们添加到构建器中)使它们易于组合。

在这种情况下,我发现非常优雅的是使用静态工厂方法编写一个实用程序类,如

public static Constraint userName(...) { ... }
导入静态blabla.Utility.username

然后,您可以用java编写几乎是声明性的人类可读查询。这与用于单元测试的hamcrest库非常相似,您可以在其中编写类似的内容

Assert.assertThat(blabla, is(equalTo(nullValue()));
在这种情况下,
Not
应该实现
Constraint
,并像这样否定嵌套(引用)约束:

public static Constraint not(Constraint negated) { return new Not(negated); }
这会产生类似代码的结果

PreparedStatement ps = new QueryBuilder()
 .select()
 .from(table("accounts")
 .where(not(username(equalTo("blabla")))
 .compile();
您可以为布尔组合添加静态工厂:

.where(and(
  .not(...),
  .not(or(...))

这样定义约束(静态工厂方法,而不是将它们添加到构建器中)使它们易于组合。

您可以将
而不是
作为构建器的方法,设置一个标志,然后否定下一个约束

private boolean negate = false;

public Builder not() {
    negate = true;
}

public Builder username(final String username) {
    this.usernameConstraint = new Constraint<>(Operation.IS, !negate, username, "username");
    negate = false;
    return this;
}
private boolean negate=false;
公共建筑商不(){
否定=正确;
}
公共生成器用户名(最终字符串用户名){
this.usernamesconstraint=新约束(Operation.IS,!negate,username,“username”);
否定=错误;
归还这个;
}

您可以将
not
作为构建器的一种方法,设置一个标志,然后否定下一个约束

private boolean negate = false;

public Builder not() {
    negate = true;
}

public Builder username(final String username) {
    this.usernameConstraint = new Constraint<>(Operation.IS, !negate, username, "username");
    negate = false;
    return this;
}
private boolean negate=false;
公共建筑商不(){
否定=正确;
}
公共生成器用户名(最终字符串用户名){
this.usernamesconstraint=新约束(Operation.IS,!negate,username,“username”);
否定=错误;
归还这个;
}

关于第二个问题:

   public Constraint[] getConstraints() {
        return Arrays.asList(this.getAccountIdConstraint(), 
            this.getUsernameConstraint(),
            this.getPasswordConstraint(),
            this.getEmailConstraint())
            .toArray(new Constraint[4]);
    }
可重新写入:

   public Constraint[] getConstraints() {
        return new Constraint[] {
            this.accountIdConstraint,
            this.usernameConstraint,
            this.passwordConstraint,
            this.emailConstraint
        };
    }

但是在我看来,返回
列表
集合
比返回数组要好。

关于第二个问题:

   public Constraint[] getConstraints() {
        return Arrays.asList(this.getAccountIdConstraint(), 
            this.getUsernameConstraint(),
            this.getPasswordConstraint(),
            this.getEmailConstraint())
            .toArray(new Constraint[4]);
    }
可重新写入:

   public Constraint[] getConstraints() {
        return new Constraint[] {
            this.accountIdConstraint,
            this.usernameConstraint,
            this.passwordConstraint,
            this.emailConstraint
        };
    }
但是在我看来,返回一个
列表
集合
比返回一个数组要好。

关键是我得到了一个