如何使这个程序更加"清洁"

4
这里是我的问题。
我有一堆需要通过Gson序列化的配置类,它们都位于同一个目录下,并且序列化/反序列化过程非常相似,因此我认为应该将代码移动到父类中。
最终我想出了以下解决方案(感觉非常勉强):
package com.bar.foo;

import java.io.File;
import java.io.IOException;

public interface FooConfiguration {
    /**
     * Saves the configuration object to disk
     * @param location the location to save the configuration
     */
    public void save(File location) throws IOException;
}

FooConfigurationAbstract.java:

package com.bar.foo;

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FileUtils;

import com.google.gson.Gson;

public abstract class FooConfigurationAbstract implements FooConfiguration {
    File location;
    Gson gson;

    @Override
    public void save(File location) throws IOException {
        FileUtils.writeStringToFile(location, gson.toJson(this), "utf-8");
    }
}

FooConfigurationImpl.java:

package com.bar.foo;

- snip imports -

public class FooConfigurationImpl extends FooConfigurationAbstract {

    /**
     * Whether or not the we should use the new Bar feature
     */
    @Expose
    public Boolean useBar = false;

    - snip more configuration values -
}

FooConfigurationFactory.java:

package com.bar.foo;

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FileUtils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class FooConfigurationFactory<T extends FooConfiguration> {
    public static Gson gson = new GsonBuilder()
            .setPrettyPrinting()
            .excludeFieldsWithoutExposeAnnotation()
            .create();
    public Class<T> clazz;
    public File basePath;

    public FooConfigurationFactory(File basePath, Class<T> clazz) {
        this.basePath = basePath;
        this.clazz = clazz;
    }

    public T load(String location) throws IOException {
        return this.load(location, FooConfigurationFactory.gson);
    }

    public T load(String location, Gson gson) throws IOException {
        return gson.fromJson(
                FileUtils.readFileToString(
                    new File(this.basePath, location), "utf-8"),
                this.clazz);
    }
}

用例示例:

this.config = new FooConfigurationFactory<FooConfigurationImpl>(this.configDir, FooConfigurationImpl.class).load("config.json");

我觉得这是我一生中见过的最丑陋的东西。我的方法是错误的吗?还是有更好的方法可以做到呢?


1
我个人认为这是非常整洁和正确的代码。我觉得它看起来不错 :/ - Craig White
我必须问一下,你的配置是否是包含大量非Latin-1字符的复杂JSON?如果不是,你是否尝试过使用标准的.properties文件?只是说上面的代码看起来很好,但如果已经存在标准方法,那么可能是不必要的 :-) - andyb
@Craig 或许只是我自己的问题。 :) @andyb:我必须处理一堆UTF8字符和复杂结构,所以不幸的是我不能使用.properties文件。 - Jonathan Chan
1个回答

1
  • 您可以通过将save移动到单独的类中来简化层次结构。(我认为将配置保存到磁盘上不是配置本身的职责。)
  • 您真的需要通用配置工厂吗?您可以使用通用方法而不是通用类来简化使用语法。

.

public class FooConfigurationService {
    ...
    public void save(File location, FooConfiguration configuration) { ... }    
    public <T extends FooConfiguration> T load(File location, Class<? extends T> clazz) { ... }
}

...

FooConfigurationFactory factory = ...;
this.config = factory.load(location, FooConfigurationImpl);    

谢谢,我同意将保存移动到单独的类中。我会研究一下。 - Jonathan Chan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接