代码之家  ›  专栏  ›  技术社区  ›  Cesar

在Java中初始化子类参数的首选方法?

  •  1
  • Cesar  · 技术社区  · 15 年前

    我有一个接受一些输入并生成配置文件作为输出的应用程序。由于确切的输入或输出格式可能会随着时间而改变,我定义了两个接口:导入程序和导出程序。

    每个具体的导入者或导出者可以有不同的参数,这些参数需要初始化才能工作。例如,如果导入数据来自csv文件,则只需要该文件的路径,但如果数据来自数据库,则需要连接字符串、用户名、密码等。对于导出程序来说,这是一样的。

    我目前的实施是:

    public interface Importer {
        public void setup(Map<String,String> params);
        public List<ConfigEntry> getList();
    }
    
    public interface Exporter {
        public void setup(Map<String,String> params);
        public void writeDocument(List<ConfigEntry> entries) throws IOException;
    }
    

    需要先调用Setup方法,然后才能调用GetList()或WriteDocument()。我使用映射来保存参数,因为每个子类可以有不同的参数。

    使用JavaBean样式参数初始化是首选方法吗?这意味着,向每个子类添加setConnectionString()、setCSvFilePath()、setX()。

    这些方法的优点和缺点是什么?

    2 回复  |  直到 15 年前
        1
  •  1
  •   ChssPly76    15 年前

    基于地图的方法有两个明显的缺点:

    1. 缺少定义良好的参数名称。是的,您可以在某个地方将它们定义为常量,但仍然需要检查传递的参数名是否有效。
    2. 缺少定义良好的参数类型。更糟糕的是,如果我需要传递一个整数,我必须将它转换为字符串,然后您必须解析它(并处理可能的错误)。可以通过使用 Map<String,Object> 和自动绑定,但您仍然需要验证适当的类型。

    基于setter的方法只有一个缺点——它不能做到。也就是说,使用setter是不可靠的 独自 -你需要补充一些 init() afterPropertiesSet() 方法,该方法将在所有setter之后调用,并允许您执行其他(共同相关)验证和初始化步骤。

    而且,像这样的东西实际上需要某种 Dependency Injection 框架。喜欢 Spring 例如。

        2
  •  0
  •   Stephen C    15 年前

    我不会说在构造函数中传递一个映射(或属性)对象必然要优于子类特定的setter,反之亦然。哪种方法最好取决于您将如何实例化类。

    如果你要直接从Java实例化类,那么map方法趋向于更整洁,尤其是如果你有一个好的方法来组装地图。(例如,从属性文件加载属性对象。)“setters”方法强制您针对每个子类API编写代码。

    另一方面,如果要使用支持“连接”、“控制反转”等(例如Spring、PicoContainer、JavaBeans等)的容器框架来实例化类,则setter通常更好。框架通常负责实例化类和调用setter的时间和方式,使用引擎盖下的反射来完成工作。

    所以答案是…这取决于…