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