重构建议:映射到 POJO [英] Refactoring advice: maps to POJOs

查看:29
本文介绍了重构建议:映射到 POJO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前参与的项目有这样的界面:

I currently am part of a project where there is an interface like this:

public interface RepositoryOperation {

    public OperationResult execute(Map<RepOpParam, Object> params);  
}

这个接口有大约 100 个实现者.

This interface has about ~100 implementers.

要调用实施者,需要执行以下操作:

To call an implementer one needs to do the following:

final Map<RepOpParam, Object> opParams = new HashMap<RepOpParam, Object>();
opParams.put(ParamName.NAME1, val1);
opParams.put(ParamName.NAME2, val2);

现在我认为 泛型声明显然有问题.

Now I think that there is obviously something wrong with anything with a<Something, Object> generic declaration.

目前这导致 OperationImpl 的调用者必须实际阅读操作的代码才能知道如何构建参数映射.(这甚至还不是最糟糕的问题,但我不想一一列举,因为它们相当明显)

Currently this causes a caller of a OperationImpl to have to actually read the code of the operation in order to know how to build the argument map. (and this is not even the worst of the problems, but I don't want to cite them all since they are fairly obvious)

经过一些讨论,我说服了我的同事让我进行一些重构.

After some discussion I managed to convince my colleagues to let me do some refactoring.

在我看来,最简单的修复"就是像这样更改界面:

It seems to me that the simplest 'fix' would be to change the interface like so:

public interface RepositoryOperation {

    public OperationResult execute(OperationParam param);  
}

毕竟所有的具体操作都会定义(扩展)他们自己的 OperationParam 并且需要的参数对每个人都是可见的.(恕我直言,这是做这种事情的正常方式")

After all the concrete operations will define (extend) their own OperationParam and the needed arguments would be visible to everybody. (which is the 'normal way' to do things like that IMHO)

在我看来,由于接口实现者相当多,我有几个选择:

So as I see it since the interface implementers are quite numerous I have several choices:

  1. 尝试更改接口并重写所有操作调用以使用对象而不是映射.这看起来最干净,但我认为由于操作很多,因此在实践中可能会做太多工作.(大约需要 2 周的测试)

  1. Try to change the interface and rewrite all the Operation calls to use objects instead of maps. This seems the cleanest, but I think that since the operations are a lot it might be too much work in practice. (~2 weeks with tests probably)

向界面添加一个额外的方法,如下所示:

Add an additional method to the interface like so:

public interface RepositoryOperation {
    public OperationResult execute(Map<String, Object> params);
    public OperationResult execute(OperationParam params);  
}

并在我在功能实现过程中遇到地图调用时修复它们.

and fix the map calls whenever I come across them during functionality implementation.

忍受它(请不要!).

所以我的问题是.

有没有人看到更好的修复"地图的方法,如果你这样做了,你会用方法 1 或 2 修复它们还是根本不修复它们.

Does anyone see a better approach for 'fixing' the maps and if you do would you fix them with method 1 or 2 or not fix them at all.

谢谢你的好答案.如果可以的话,我会同时接受 Max 和 Riduidel 的答案,但由于我不能,所以我更倾向于 Riduidel.

Thanks for the great answers. I would accept both Max's and Riduidel's answers if I could, but since I can't I'm leaning a bit more towards Riduidel's.

推荐答案

我可以看到第三种方式.

I can see a third way.

您有一个由 组成的地图.如果我理解正确,那么困扰您的是没有类型检查的事实.显然,这并不理想.但是,可以将类型检查问题从整个参数(您的 OperationParam)转移到单个 RepOpParam.让我解释一下.

You have a map made of <RepOpParam, Object>. If I understand you correctly, what bothers you is the fact that there is no type checking. And obviously, it's not ideal. But, it is possible to move the type-checking issue from the whole parameter (your OperationParam) to individual RepOpParam. Let me explain it.

假设您的 RepOpParam 接口(目前看起来像一个 标记接口) 被修改为:

Suppose your RepOpParam interface (which currently seems like a tagging interface) is modified as it :

public interface RepOpParam<Value> {
    public Value getValue(Map<RepOpParam, Object> parameters);
}

然后您可以通过替换对

You can then update modern code by replacing old calls to

String myName = (String) params.get(ParamName.NAME1);

有新的调用

String myName = ParamName.NAME1.getValue(params);

明显的附带优势是,您现在可以为参数设置默认值,隐藏在其定义中.

The obvious collateral advantage being that you can now have a default value for your parameter, hidden in its very definition.

然而,我必须明确表示,这第三种方式只不过是将第二种方式的两个操作合并为一个的方式,尊重旧代码原型,同时在其中添加新功能.因此,我个人会采用第一种方式,使用现代对象重写所有东西"(此外,考虑查看配置库,这可能会导致您对这个问题产生有趣的答案).

I have however to make clear that this third way is nothing more than a way to merge your two operations of the second way into only one, respecting old code prototype, while adding new powers in it. As a consequence, I would personnally go the first way, and rewrite all that "stuff", using modern objects (besides, consider taking a look at configuration librarires, which may lead you to interesting anwsers to this problem).

这篇关于重构建议:映射到 POJO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆