这是我的旧代码,我决定重构它以使垃圾更容易,但现在我想知道它是否可以做得更简单。
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,其帐号为Integer
或Range<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
。
答案 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();