在查询接口结果类设计中,有这么一种思路,即把查询的真实结果和结果码组合起来,形成一个结果类,当调用方使用该接口时,先判断结果是否是成功结果,然后进行相应的处理。
一个示例如下:
/**
* 列表查询结果。
* <p>
* 请在处理成功时[ isSuccess() == true; ]才使用查询结果对象。
* </p>
*
*/
public class QueryListResult {
private List<Book> resultObject;
private ResultCode resultCode;
public QueryListResult() {
}
public QueryListResult(ResultCode resultCode) {
this.resultCode = resultCode;
this.resultObject = null;
}
public QueryListResult(ResultCode resultCode, List<Book> bookList) {
this.resultCode = resultCode;
this.resultObject = bookList;
}
public boolean isSuccess() {
return ResultCode.SUCCESS == resultCode;
}
public List<Book> getResultObject() {
return resultObject;
}
public void setResultObject(List<Book> bookList) {
this.resultObject = bookList;
}
public ResultCode getResultCode() {
return resultCode;
}
public void setResultCode(ResultCode resultCode) {
this.resultCode = resultCode;
}
}
该实现的优点是简单。当需要构建一个失败结果的时候,调用单参数构造方法,当需要构建一个成功结果的时候,调用双参数构造方法。
该实现的缺点如下:
该类没有主动保持自己的不变量,完全依赖调用方对该类不变量的理解。从该类的设计思路,可以很快的推出,该类应该满足以下性质:
任何时刻,该类的结果码不为null。
当结果码为ResultCode.SUCCESS时,该结果为成功结果,调用方可以使用真实的结果对象resultObject。
当结果码不为ResultCode.SUCCESS时,该结果为失败结果,resultCode表明了失败的原因,结果对象resultObject无定义。
默认构造函数导致resultCode为null,单参数构造函数有可能误传null或者成功码,双参数构造函数有可能误传null或者失败码。
总而言之,该对象的不变量的保持,必须依赖调用方的正确使用。
在该类的实际使用中,遵循的标准是失败结果调用单参数构造函数,成功结果调用双参数构造函数,但是由于构造函数和类名同名,该语义没有清晰的表达出来。
因为所有的成功结果都是调用双参数构造函数,因此,在正确使用该类的情况下,传入的resultCode都是ResultCode.SUCCESS,这个实际上是一种重复和冗余的体现。
基于以上的分析,代码重构如下:
/**
* 列表查询结果。
* <p>
* 请在处理成功时[ isSuccess() == true; ]才使用查询结果对象。
* </p>
*
*/
public class QueryListResult {
private List<Book> resultObject;
private ResultCode resultCode = ResultCode.UNKNOWN_EXCEPTION;
public QueryListResult() {
}
public static QueryListResult createFailedResult(ResultCode resultCode) {
QueryListResult failedResult = new QueryListResult();
if (resultCode != ResultCode.SUCCESS && resultCode != null) {
failedResult.resultCode = resultCode;
}
return failedResult;
}
public static QueryListResult createSuccessfulResult(List<Book> bookList) {
QueryListResult successfulResult = new QueryListResult();
successfulResult.resultCode = ResultCode.SUCCESS;
if (bookList == null) {
successfulResult.resultObject = new ArrayList<Book>();
} else {
successfulResult.resultObject = bookList;
}
return successfulResult;
}
public boolean isSuccess() {
return ResultCode.SUCCESS == resultCode;
}
public List<Book> getResultObject() {
return resultObject;
}
public void setResultObject(List<Book> bookList) {
this.resultObject = bookList;
}
public ResultCode getResultCode() {
return resultCode;
}
public void setResultCode(ResultCode resultCode) {
this.resultCode = resultCode;
}
}
resultCode赋予一个默认值ResultCode.UNKNOWN_EXCEPTION,保证了即使使用默认构造函数,创建的对象也是一个合法的对象。
使用静态方法代替构造函数来构建对象,由于静态方法可以自定义方法名,可以明确的指明方法的使用场景。
在静态方法中,使用防御性编程,保持对象的不变量。该处也可以更为强硬的使用异常来指明参数错误。
回收对成功结果结果码的赋值,去除了调用方的对成功结果码的冗余重复使用。
Setter和Getter方法为系统框架使用,为了保持简单,没有加上防御性代码。
代码比重构前稍微复杂一点,但是考虑到该实现可以较好的保持对象的不变量,明确了方法的调用场景,以及去除了冗余代码,个人认为这样的实现优于原有实现。
分享到:
相关推荐
本书开创性地深入揭示了重构与模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式。本书不仅展示了一种应用模式和重构的创新方法,而且有助于读者结合...
中文版(共6个文件) ...如果代码已经编写,这两种情形都是重构,因为前者是通过重构使修改更容易,而后者则是通过重构在修改后进行整理。虽然模式是在程序中能够看到的东西,但是模式也是一种程序转换。
一共12个包,全下载解压 本书开创性地深入揭示了重构与模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式。本书不仅展示了一种应用模式和重构的创新...
一共12个包,全下载解压 本书开创性地深入揭示了重构与模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式。本书不仅展示了一种应用模式和重构的创新...
本书开创性地深入揭示了重构与模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式。本书不仅展示了一种应用模式和重构的创新方法,而且有助于读者结合...
中文版(共6个文件) ...如果代码已经编写,这两种情形都是重构,因为前者是通过重构使修改更容易,而后者则是通过重构在修改后进行整理。虽然模式是在程序中能够看到的东西,但是模式也是一种程序转换。
一共12个压缩包,全下载解压 本书开创性地深入揭示了重构与模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式。本书不仅展示了一种应用模式和重构的...
一共12个包,全下载解压 本书开创性地深入揭示了重构与模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式。本书不仅展示了一种应用模式和重构的创新...
一共12个包,全下载解压 本书开创性地深入揭示了重构与模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式。本书不仅展示了一种应用模式和重构的创新...
一共12个包,全下载解压 本书开创性地深入揭示了重构与模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式。本书不仅展示了一种应用模式和重构的创新...
一共12个包,全下载解压 本书开创性地深入揭示了重构与模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式。本书不仅展示了一种应用模式和重构的创新...
一共12个包,全下载解压 本书开创性地深入揭示了重构与模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式。本书不仅展示了一种应用模式和重构的创新...
一共12个包,全下载解压 本书开创性地深入揭示了重构与模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式。本书不仅展示了一种应用模式和重构的创新...
一共12个包,全下载后解压 本书开创性地深入揭示了重构与模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式。本书不仅展示了一种应用模式和重构的...
一共12个包,全下载解压,这是最后一个包 本书开创性地深入揭示了重构与模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式。本书不仅展示了一种应用...
“这《重构:改善既有代码的设计》之于重构就相当于韵谱之于作诗。一个翻着韵书作诗的诗人一定是蹩脚的,但好的诗人却要对那109个韵部了然于胸;... 此商品有两种印刷封面,随机发货! ·查看全部>>
司法实践中,适用兜底条款进行规制的做法本身存在严重弊端,只能作为权宜之计而不能从根本上解决问题。因此,必须对上述两项专有权利进行重构。在可能的三种选择方案中,扩张我国《著作权法》中"广播权"的定义使其能够...
所以对于该算法的重构特性以及这两种算法在空间声场变换中的优劣是人们一直普遍关注的问题。通过计算修正了该算法在Neumann边界条件下的计算参数,并通过数值仿真分析了实空间积分格林函数的相关特性,最后通过仿真...
, 全书共20章,分为四个部分:第一部分(第1~10章)首先通过测试后行和测试先行两种方法完成了一个名为“码农酒店”(世界时钟)的编程操练题目,然后对这两种方法进行对比,引出了烂代码的概念,读者能非常直观...
快无非是两种情况,一是架构师自身炉火纯青、天生慧眼,设计能力超强;二是原有业务模型已经很清晰,可以快速分析业务变化,形成架构设计,我们可以追求的是第二种,这也意味这首次建模,尤其是首次建设企业级模型,...