我正在尝试编写一个将由外部用户使用的库,我仍然坚持一些基本的设计决策。
我正在编写一个简单的POJO类,它将保存有关OAuth2令牌的一些信息。
本课程需要满足以下条件:
这是我到目前为止:
public TokenInformation(String token, Date expirationDate, String refreshToken) {
Objects.requireNonNull(token, "token parameter cannot be null.");
this.token = token;
if ((expirationDate != null) && (refreshToken != null)) {
this.expiresIn = expiresIn;
this.refreshToken = refreshToken;
isPermanentToken = false;
} else if ((expirationDate == null) && (refreshToken == null)) {
this.expiresIn = null;
this.refreshToken = null;
isPermanentToken = true;
} else {
// throw some exception here
}
}
说实话,我对代码的外观并不完全满意。
但我确实有以下想法:
我认为第二个想法可能是最好的方法。例如,我想不出任何要求我们传递null的Java API,这可能暗示我粘贴的代码是个坏主意。另外,Java使用了很多工厂方法,因此对于我的库用户来说,这不是一个陌生的模式。
我想要其他人的意见。如果您需要任何其他信息,请告诉我。
我宁愿将永久和临时令牌行为封装到各自的域中,因此您的库的任何用户都清楚地知道实例化了哪种令牌
我认为建议的课程:
/**
* The base class encapsulates the behavior of generic token
*/
public class AbstractToken {
protected String token;
// other properties that exist very closely with token
public String getToken() {
return token;
}
}
永久令牌的域名
/**
* The domain encapsulates the behaviour of Permanent token - token that never expires
*/
public class PermanentToken extends AbstractToken {
// more attributes that makes general token as Parmament token
/**
* Instantiates a new Permanent token - this token never expires
*
* @param token the token
*/
public PermanentToken(String token) {
this.token = token;
}
}
临时令牌的域名:
/**
* The domain for Temporary token.
*/
public class TemporaryToken extends AbstractToken {
private Date expirationDate;
private String refreshToken;
// more attributes that makes general token as temporary token
/**
* Instantiates a new Temporary token with token expiry date and refresh token
*
* @param token the token
* @param expirationDate the expiration date
* @param refreshToken the refresh token
*/
public TemporaryToken(String token, Date expirationDate, String refreshToken) {
this.token = token;
this.expirationDate = expirationDate;
this.refreshToken = refreshToken;
}
}
现在,您图书馆的用户清楚地知道他/她想要实例化和使用的令牌类型。
附: - 我想您可以为您的域名保留更好的名称,并深入了解您的图书馆业务。
基于上面的代码,我认为多重构造方法比工厂更合适。这是一个非常常见的Java设计模式,具有多个构造函数,用户可以在其中传递信息,只包含他们拥有数据的字段。构造函数不会重复代码,而是相互调用默认值。
public TokenInformation(String token) {
this(token, null, null);
}
public TokenInformation(String token, Date expirationDate, String refreshToken) {
Objects.requireNonNull(token, "token parameter cannot be null.");
this.token = token;
if ((expirationDate != null) && (refreshToken != null)) {
this.expiresIn = expiresIn;
this.refreshToken = refreshToken;
isPermanentToken = false;
} else if ((expirationDate == null) && (refreshToken == null)) {
this.expiresIn = null;
this.refreshToken = null;
isPermanentToken = true;
} else {
// throw some exception here
}
}
由于您没有创建多种不同类型的TokenInformation
对象,因此我找不到符合您需求的工厂模式。如果你要使用一个模式,我会选择Builder而不是工厂。
编辑:我应该更好地阅读你的代码。我会在这里留下我的答案,因为我认为如果你不想改变你的课程我的解决方案仍然适用,但是,我认为@DHRUV BANSAL有更好的整体方法,因为你的代币实际上代表不同的东西