我目前正在开发一个代码库,其中有几类变量,例如数据库路径,它们简单地表示为字符串。这些(非)类型的大多数操作都在实用程序类中定义。
我创建了一个新类来表示数据库,操作定义为实例方法,采用传统的 OOP 风格。然而,通过大型代码库并对其进行重构以使用新类型是相当费力的。有人对如何快速有效地做到这一点有任何建议吗?
我目前正在开发一个代码库,其中有几类变量,例如数据库路径,它们简单地表示为字符串。这些(非)类型的大多数操作都在实用程序类中定义。
我创建了一个新类来表示数据库,操作定义为实例方法,采用传统的 OOP 风格。然而,通过大型代码库并对其进行重构以使用新类型是相当费力的。有人对如何快速有效地做到这一点有任何建议吗?
迁移实用程序类以使用您的新类。那么实用程序类方法应该只包含两个语句。一个用于创建您的课程,另一个用于调用您的课程。之后,您可以内联实用程序类方法,从而消除对它的需要。
完成后,您需要寻找一种方法来不一遍又一遍地实例化您的新类。这应该通过将局部变量重构为在构造时初始化的实例字段来完成。
数据库路径听起来对我来说应该是字符串。还有什么意义?它们应该被外部化,无论是在配置文件中还是在数据库中。这是你的问题中最少的。
持久性已经出现了很多次(例如 Hibernate、Spring JDBC、iBatis 等),我想知道您如何改进它们。如果你不得不去重构的麻烦 - 你必须 - 我建议使用你所做的以外的任何东西。
如果你必须写一些东西,谷歌搜索“通用 DAO”。你会得到这样的东西:
http://www.ibm.com/developerworks/java/library/j-genericdao/index.html
如果你的作品没有像这样的东西,把它扔掉,重新思考。
我在 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) {
}
当您有具有许多字符串参数的方法时,这是有道理的,例如,您可以避免
public void Foo(String username, String password, String db, String table, String constraint)
而是有这样的强类型代码:
public void Foo(UserName username, Password password, DatabasePath db, TableName table...)
ETC...
我通常会尝试在应用程序/进程边界的限制处隔离字符串,例如当它们从数据库中检索或通过 Web 操作接收时。
在那个应用程序/进程边界处,通常是将字符串映射/转换/反序列化为更合适的对象模型的理想位置,无论您使用什么语言都支持。
类似地,对象模型可以在退出应用程序/进程边界时被映射/转换/序列化回字符串形式。
值得注意的是,这种字符串类型可能有些微妙。我经常看到 xml 侵入应用程序和域层。来自 .NET 领域的一个类似示例将无法在收到 ADO.NET 数据表(及其字符串列名和无类型字段值)后立即将它们映射到类/对象中。我毫不怀疑在 Java 世界中有许多类似的等价物。正如笑话所说,Stringly Typing 不仅限于日期值。