Java 重构建议:映射到POJO
我目前是一个项目的一部分,该项目有如下界面:Java 重构建议:映射到POJO,java,dictionary,architecture,refactoring,Java,Dictionary,Architecture,Refactoring,我目前是一个项目的一部分,该项目有如下界面: public interface RepositoryOperation { public OperationResult execute(Map<RepOpParam, Object> params); } 在所有具体操作之后,将定义(扩展)它们自己的OperationParam,并且所需的参数将对每个人可见。(这是IMHO做这种事情的“正常方式”) 因此,在我看来,由于接口实现者众多,我有几种选择: 尝试更改接口并重写
public interface RepositoryOperation {
public OperationResult execute(Map<RepOpParam, Object> params);
}
在所有具体操作之后,将定义(扩展)它们自己的OperationParam,并且所需的参数将对每个人可见。(这是IMHO做这种事情的“正常方式”)
因此,在我看来,由于接口实现者众多,我有几种选择:
public interface RepositoryOperation {
public OperationResult execute(OperationParam param);
}
public interface RepositoryOperation {
public OperationResult execute(Map<String, Object> params);
public OperationResult execute(OperationParam params);
}
公共接口存储操作{
公共操作结果执行(映射参数);
公共操作结果执行(操作参数参数);
}
并在功能实现过程中,每当遇到map调用时修复它们
组成的地图。如果我没弄错的话,困扰你的是没有类型检查。显然,这并不理想。但是,可以将类型检查问题从整个参数(您的OperationParam
)移动到单个repoparam
。让我解释一下
假设您的RepOpParam
接口(当前看起来像a)被修改为:
public interface RepOpParam<Value> {
public Value getValue(Map<RepOpParam, Object> parameters);
}
有新的要求
String myName = ParamName.NAME1.getValue(params);
明显的附带优势是,现在可以为参数设置一个默认值,隐藏在其定义中
不过,我必须明确指出,第三种方法只不过是将第二种方法的两个操作合并为一个操作,尊重旧的代码原型,同时在其中添加新的功能。因此,我会亲自走第一步,用现代对象重写所有的“东西”(另外,考虑一下配置库,这可能会导致你对这个问题感兴趣)。 < P>听起来你有一个不必要的和错误的抽象。每当我看到一个包含一个方法的接口时,我都会考虑策略模式或操作模式,这取决于您是否在运行时做出决策 清理代码的一种方法是让每个RepositoryOperation实现都有一个构造函数,该构造函数接受正确运行execute方法所需的特定参数。这样,地图中的对象值就不会出现混乱的转换
如果希望保留execute方法签名,可以使用泛型对映射的值进行更严格的限制。首先,我认为接口并不完美。您可以添加一些泛型,使其更美观:
public interface RepositoryOperation<P extends OperationParam, R extends OperationResult> {
public R execute(T params);
}
public class DeleteOperation implements RepositoryOperation<DeleteParam, DeleteResult> {
public DeleteResult execute(DeleteParam param) {
database.delete(param.getID());
...
}
}
公共接口存储操作{
公共R执行(T参数);
}
现在,我们需要一些向后兼容的代码。我同意这一点:
//We are using basic types for deprecated operations
public abstract class DeprecatedRepositoryOperation implements RepositoryOperation<OperationParam, OperationResult> {
//Each of our operations will need to implement this method
public abstract OperationResult execute(Map<String, Object> params);
//This will be the method that we can call from the outside
public OperationResult execute(OperationParam params) {
Map<String, Object> paramMap = getMapFromObj(params);
return execute(paramMap);
}
}
//我们正在对不推荐使用的操作使用基本类型
公共抽象类DeprecatedRepositoryOperation实现RepositoryOperation{
//我们的每个操作都需要实现此方法
公共抽象操作结果执行(映射参数);
//这将是我们可以从外部调用的方法
公共操作结果执行(操作参数参数){
Map paramMap=getMapFromObj(params);
返回执行(paramMap);
}
}
以下是旧操作的外观:
public class SomeOldOperation extends DeprecatedRepositoryOperation {
public OperationResult execute(Map<String, Object> params) {
//Same old code as was here before. Nothing changes
}
}
public类SomeOldOperation扩展了DeprecatedRepositoryOperation{
公共操作结果执行(映射参数){
//和以前的代码一样,没有任何变化
}
}
新操作将更美观:
public interface RepositoryOperation<P extends OperationParam, R extends OperationResult> {
public R execute(T params);
}
public class DeleteOperation implements RepositoryOperation<DeleteParam, DeleteResult> {
public DeleteResult execute(DeleteParam param) {
database.delete(param.getID());
...
}
}
public类DeleteOperation实现RepositoryOperation{
公共DeleteResult执行(DeleteParam-param){
delete(param.getID());
...
}
}
但是调用代码现在可以使用这两个函数(代码示例):
String operationName=getOperationName()//=“删除”
映射操作Map=getOperations()//=所有操作的列表
OperationParam param=getParam()//=删除参数
operationMap.execute(参数);
如果该操作是旧操作,则将使用DeprecatedRepositoryOperation中的转换器方法。
如果操作是新的,它将使用新的
public R execute(T params)
函数。非常感谢您的绝妙解决方案。我会让这个问题在我的脑海里“萦绕”几个小时:)这不是一种方法。我只发布了与问题相关的内容。我发布了一个非常“精简”的界面版本。我大体上同意你的建议,但这仍然无助于旧的运作。我需要一种快速使它们更漂亮的方法:)并且不要花2周的时间进行重构。新操作当然将使用“新方法”,不管是什么:)我提出的方法允许您简单地将所有旧操作扩展为DeprecatedRepositoryOperation,它们将被代理为“新”操作语法。但是,向其中提供参数的方式可能很复杂。但我不认为有什么方法可以加快这一部分的重构。如果您以映射形式接收参数,则需要将其转换为对象,或将其作为映射进一步传递。同意。。。我也开始认为可能根本就没有捷径。
String operationName = getOperationName(); //="Delete"
Map<String, RepositoryOperation> operationMap = getOperations(); //=List of all operations
OperationParam param = getParam(); //=DeleteParam
operationMap.execute(param);