首先是一些背景:
我已经实现了一个Result类,用于携带结果信息。它们是专门针对故障实施的,成功结果通常不会提供额外信息。我在我的一个项目中的核心API外部的公共方法中使用它们,或者在一两层深的方法中使用它们,我需要将详细信息备份到公共API。这个API在容器和命令行客户端中使用,并且之前已经非常快速地检查了异常。另一种方法是将这种失败上下文信息添加到异常中,并添加几个不同的异常类,它们不属于它们。我想这反映了我的一般方法:
http://blogs.atlassian.com/2011/05/exceptions_are_bad
结果有一个支持枚举和界面:
Result为状态提供静态工厂方法,构建其他关键字段的构建器方法是不可变的。以下是构建结果的结果:
Result.success().withCode( ResultCode ).withMessage( "" );
评估返回的结果:
result.isSuccessful();
result.hasCode( ResultCode );
result.getMessage();
我的问题:
这种方法非常成功,特别是使功能测试变得轻而易举,但是我有一个主要的差距:在大多数情况下我只关心结果,在一些关键区域我需要返回一个值与结果。
我对第一次尝试不满意:ResultPair<T>
包含结果和值,其中T是值的类型。除非我复制所有Result方法,否则使用该类是冗长且笨拙的:获取结果,将其添加到ResultPair,并在评估之前捕获结果和值。乍一看,由于构建器模式,继承将无法工作,我无法想到一种方法可以获得结果允许的清晰,干净的代码,而无需完全复制Result类。
理想情况下,该方法允许Result可选地返回一个值,但我想不出一种以类型安全的方式执行它的方法,以确保方法签名清楚地指示值的类型,但避免无意义通用参数到处都没有返回值。
我真的不介意有两个类,并且复制结果构建器和评估代码并不是世界末日,它只是感觉错误而我觉得缺乏经验我更好,我错过了一个(明显的或不那么明显的)解决方案。我正在使用Guava并且我想以友好的方式禁止空值,因此可能另外将所有值包装在Optional中,但我仍然需要泛型参数(并将其组合到类中以避免result.value( ).get()......好的,我现在正在大声思考。我应该问一个问题......)。
有没有办法满足这些明显相互排斥的要求?
答案 0 :(得分:2)
您可以将ResultPair<T>
创建为 void 结果类的基类:
public class Result extends ResultPair<Void> { ... }
所有相关方法都将在ResultPair<T>
中声明。
<强>更新强>:
更好的是,只有一种类型Result<T>
,并且只要您不想拥有返回值,就使用Result<Void>
。或者更确切地说,如果使用Void
作为类型参数看起来很奇怪,创建一个新的不可实例化(或单例)类型,意味着“没有结果”,并使用它代替:Result<Unit>
。