Java类在一个构造函数中接受同一参数上的不同对象

时间:2013-06-28 13:19:20

标签: java

这是我的旧代码,我决定重构它以使垃圾更容易,但现在我想知道它是否可以做得更简单。

public class AccountConstraint {
    private Range<Integer> accountId;
    private String username;
    private String password;
    private String email;

    public AccountConstraint(Object accountId, final String username, final String password, final String email) {
        if (accountId instanceof Integer) {
            accountId = new Range<>(accountId);
        }
        this.accountId = (Range<Integer>)accountId;
        this.username = username;
        this.password = password;
        this.email = email;
    }
}

public class Range<T> {
    private T min;
    private T max;

    public Range(T min, T max) {
        this.min = min;
        this.max = max;
    }

    public Range(T value) {
        this.min = value;
        this.max = value;
    }

    public T getMin() {
        return min;
    }

    public T getMax() {
        return max;
    }

    @Override
    public String toString() {
        return "[" + min + ", " + max + "]";
    }
}

使用此功能,您可以创建一个AccountConstraint,其帐号为IntegerRange<Integer>,并确保始终保存为Range<Integer>

此处的背景信息是,您应该只需输入5之类的整数,然后它就会自动存储为Range(5) = Range(5, 5)

代码工作正常,但似乎有点乱。所以我提出了以下改进:

新构造函数:

public AccountConstraint(Object accountId, final String username, final String password, final String email) {
    this.accountId = Range.<Integer>getRange(accountId, Integer.class);
    this.username = username;
    this.password = password;
    this.email = email;
}

新方法:

public static <T> Range<T> getRange(Object object, Class<? extends T> clazz) {
    if (clazz.isInstance(object)) {
        object = new Range<>((T)object);
    }
    return (Range<T>)object;
}

它也有效,在我看来似乎更好,因为它现在可以作为一个单行,但它甚至可以做得更好吗?更具体地说,可以遗漏Class<? exends T>吗?

还有一个小问题:它应该是Class<T> clazz还是Class? extends T> clazz

问候。

编辑:按照建议实现了构建器模式,因为有可能会有更多可以重载的参数。新代码:

package dao.constraint;

public class AccountConstraint {
    private Range<Integer> accountId;
    private String username;
    private String password;
    private String email;

    private AccountConstraint(Builder builder) {
        this.accountId = builder.accountId;
        this.username = builder.username;
        this.password = builder.password;
        this.email = builder.email;
    }

    public Range<Integer> getAccountId() {
        return accountId;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public String getEmail() {
        return email;
    }

    public static class Builder {
        private Range<Integer> accountId;
        private String username;
        private String password;
        private String email;

        public Builder() {
            this.accountId = null;
            this.username = null;
            this.password = null;
            this.email = null;
        }

        public Builder accountId(final int accountId) {
            this.accountId = new Range<>(accountId);
            return this;
        }

        public Builder accountId(final Range<Integer> accountId) {
            this.accountId = accountId;
            return this;
        }

        public Builder username(final String username) {
            this.username = username;
            return this;
        }

        public Builder password(final String password) {
            this.password = password;
            return this;
        }

        public Builder email(final String email) {
            this.email = email;
            return this;
        }

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

现在一个非常好的功能是,非强制性字段不再需要填充,因为它们的默认值为null

2 个答案:

答案 0 :(得分:6)

两者都没有,请使用重载...

public AccountConstraint(Integer accountId, final String username, 
         final String password, final String email) {
    this(new Range<Integer>(accountId), username, password, email);
}

public AccountConstraint(Range<Integer> accountId, final String username, 
         final String password, final String email) {
    this.accountId = accountId;
    this.username = username;
    this.password = password;
    this.email = email;
}

答案 1 :(得分:1)

一种可能性是使用构建器,如此(要改进的代码):

public final class AccountConstraintBuilder
{
    private Range<Integer> accountId;
    private String username;
    private String password;
    private String email;

    public AccountConstraintsBuilder()
    {
    }

    public AccountConstraintsBuilder withUsername(final String username)
    {
        this.username = username;
        return this;
    }

    // password, email...

    public AccountConstraintsBuilder withUniqueValue(final int value)
    {
        return withRange(value, value);    
    }

    public AccountConstraintsBuilder withRange(final int min, final int max)
    {
        accountId = new Range<Integer>(min, max);
        return this;
    }

    public AccountConstraint build()
    {
        return new AccountConstraint(accountId, username, password, email);
    }
}

这样就可以在AccountConstraint上只有一个构造函数:一个以Range作为参数的构造函数。此外,构建器是强制执行约束的好地方:您的实例构造函数无关,只能“盲目地”接受它的参数。

注意:我想AccountConstraint中的实例参数也可能是最终的。

注2:这可能是AccountConstraint的静态内部类;并且可以创建一个静态工厂方法,以便您可以:

AccountConstraint.newBuilder().withUsername().etc().etc().build();