在这个大型的遗留项目中,有一个核心类MyObject,它具有ID属性,该属性已编码为String。在项目的任何地方都可以访问该ID。
public class MyObject {
private String id;
public String getId(){
return id;
}
}
我正在研究使用以下方法将此String属性重构为类型类ID的可能性:
class Id implements Comparable<Id> {
String value
Id(String value)
String getValue()
int hashCode()
boolean equals(Object obj)
int compareTo(Id o)
String toString()
}
重构时,我需要牢记,尽管我可以以任何方式重构我们自己的项目,但仍有一些客户使用该项目的API,并且更改最好是向后兼容的。内部字符串ID的当前用法是:
equals()
和有时用equalsIgnoreCase()
比较对象ID和字符串值(例如用户输入)具体地说,我想做的是:
String
重构为Id
String getId()
重构为Id getUniqueID()
id.equals("String")
或id.equalsIgnoreCase("String")
将ID与字符串进行比较时,将其更改为id.equals(new Id("String"))
String getId()
,该方法将返回getUniqueID().getValue()
。这是为了与依赖旧字符串ID的客户代码向后兼容。当然,我可以列出该属性的所有用法,其getter和setter并手动替换它们。有时,我也许可以摆脱使用正则表达式的困扰,但这并不是一个好主意。此外,它令人生畏,因为在包括子类在内的几十个类中有500多种用法可供编辑。
我已经看过IDEA的重构:类型迁移函数,但似乎无法做到这一点。我通常不会在IDEA中工作,所以我可能做错了什么,但是它告诉我有几百个冲突,并且无法转换的内容很长。
看起来我无法提供旧的吸气剂getId()
到新的getUniqueID().getValue()
的映射,例如
myObject.getId().equalsIgnoreCase("test")
需要映射到
myObject.getUniqueID().getValue().equals(new Id("test"))
我认为这种重构应该会很流行,但是到目前为止,我似乎将不得不手动完成并进行搜索+替换。
是否有自动化的方法?也许,某些重构工具将允许指定旧的使用模式将如何映射到新的使用模式?
答案 0 :(得分:1)
一个简单的解决方案,用于向后兼容,不需要大量的重构:
@Deprecated
String getId() { return getUniqueID().getValue(); }
ID getUniqueID() {
//TODO
}
仅在必不可少且明显受益的地方手动编辑getId().getValue().equals("test")
个事件。
答案 1 :(得分:0)
我认为提出的问题的普遍答案确实是使用IntelliJ IDEA的功能:重构→类型迁移。
挑战在于,它可能会将许多其他变量迁移到新类型,而不仅仅是我想迁移的变量。
例如,我们还有另一个类NameDescription,它使用两个String参数作为名称和描述,有时用作new NameDescription(myObject.getId(), "Some description")
。在这种情况下,IDEA认为它可能也需要将NameDescription.name
从String更改为Id,这实际上是错误的。
为了避免这种情况,需要在请求类型迁移后预览使用情况,并手动排除这种情况以及其他不应该迁移的情况。
此外,IDEA的另一个功能可用于修改代码中的模式:Search / Replace从结构上讲,它允许使用变量定义搜索模式,并且比自己编写许多正则表达式更容易使用。>
为了向后兼容,如@ c0der所建议,旧的getter将返回newIdObject.getValue()