如何重构“字符串类型”代码?

时间:2013-02-25 10:42:40

标签: java string oop types refactoring

我目前正在开发一个代码库,其中有几类变量,比如数据库路径,它们只是表示为字符串。这些(非)类型的大多数操作都在实用程序类中定义。

我创建了一个新类来表示数据库,其操作定义为实例方法,采用传统的OOP样式。但是,通过大型代码库并重构它以使用新类型是相当费力的。有没有人对如何快速有效地做到这一点有任何建议?

4 个答案:

答案 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并不仅限于日期值,就像笑话一样。