我目前正在开发一个代码库,其中有几类变量,比如数据库路径,它们只是表示为字符串。这些(非)类型的大多数操作都在实用程序类中定义。
我创建了一个新类来表示数据库,其操作定义为实例方法,采用传统的OOP样式。但是,通过大型代码库并重构它以使用新类型是相当费力的。有没有人对如何快速有效地做到这一点有任何建议?
答案 0 :(得分:3)
迁移实用程序类以使用新类。然后实用程序类方法应该只包含两个语句。一个用于创建类,另一个用于调用类。之后,您可以内联实用程序类方法,从而无需使用它。
完成后,您需要寻找一种不反复实例化新类的方法。这应该通过将局部变量重构为在构造时初始化的实例字段来完成。
答案 1 :(得分:1)
数据库路径听起来应该是字符串给我。还有什么有意义的?它们应该在配置文件或数据库中进行外部化。这是你遇到的最少的问题。
持久性已经过了很多次(例如Hibernate,Spring JDBC,iBatis等),我想知道你怎么可能改进它们。如果你不得不去重构的麻烦 - 你必须 - 我建议你使用任何而不是你做过的事情。
如果你必须写一些东西,谷歌的“通用DAO”。你会得到这样的东西:
http://www.ibm.com/developerworks/java/library/j-genericdao/index.html
如果你的作品没有像这样的东西,请把它扔掉,重新思考。
答案 2 :(得分:1)
我在C#中使用的一种技术(并且刚刚移植到Java中 - 如果我犯了错误,我是Java的新手,则道歉)是创建StringlyTyped类,例如基类
public abstract class StringlyTyped {
private String value;
public StringlyTyped (String value){
if (value == null){
throw new IllegalArgumentException("value must not be null");
}
this.value = value;
}
public String getValue() { return value; }
@Override
public boolean equals(Object other){
if (other == this) {
return true;
}
if (other == null || !this.getClass().equals(other.getClass())){
return false;
}
StringlyTyped o = (StringlyTyped)other;
return o.getValue().equals(this.getValue());
}
@Override
public int hashCode(){ return this.getValue().hashCode(); }
@Override
public String toString() { return this.getValue(); }
}
然后派生类
public class ProviderName extends StringlyTyped {
public ProviderName(String value) {
super(value);
}
}
使用
public void Foo(ProviderName provider) {
}
当您拥有包含许多String参数的方法时,这是有意义的,例如:你可以避免
public void Foo(String username, String password, String db, String table, String constraint)
而是具有强类型的代码:
public void Foo(UserName username, Password password, DatabasePath db, TableName table...)
等等......
答案 3 :(得分:0)
我通常会尝试在应用程序/进程边界的极限处隔离字符串,例如从数据库中检索它们或通过Web操作接收它们。
在该应用程序/进程边界通常是将字符串映射/转换/反序列化为更合适的对象模型的理想位置,正如您使用的任何语言所支持的那样。
类似地,当对象模型退出应用程序/进程边界时,可以将对象模型映射/转换/序列化为字符串形式。
值得注意的是,这种字符串输入可能有点微妙。我经常看到xml侵入应用程序和域层。来自.NET空间的类似示例将无法在收到ADO.NET DataTables(及其字符串列名和无类型字段值)时将其映射到类/对象中。我毫不怀疑Java世界中有许多类似的等价物。 Stringly Typing并不仅限于日期值,就像笑话一样。