简体   繁体   English

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

[英]Preferred method for initializing a child class parameters in Java?

I have an application that takes some input and generates configuration files as output. 我有一个需要一些输入并生成配置文件作为输出的应用程序。 Since the exact input or output format could change over time, I defined two interfaces: Importer and Exporter. 由于确切的输入或输出格式可能会随时间变化,因此我定义了两个接口:Importer和Exporter。

Each concrete importer or exporter could have different parameters that need to be initialized to work. 每个具体的进口商或出口商可能有不同的参数,需要对其进行初始化才能起作用。 For example, if the import data is coming from a CSV file you only need the path of the file, but if the data is coming from a database then you need a connection string, username, password, etc. Same thing for exporters. 例如,如果导入数据来自CSV文件,则仅需要文件的路径,但是如果数据来自数据库,则需要连接字符串,用户名,密码等。

My implementation currently is: 我目前的实现是:

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;
}

The setup method needs to be called before getList() or writeDocument() can be called. 需要先调用setup方法,然后才能调用getList()或writeDocument()。 I use a Map to keep parameters because each child class can have different parameters. 我使用Map来保留参数,因为每个子类可以具有不同的参数。

Is using JavaBean style parameter initialization a preferred way? 使用JavaBean样式参数初始化是首选方法吗? That means, adding setConnnectionString(), setCSVFilePath(), setX() to each child class. 这意味着将setConnnectionString(),setCSVFilePath(),setX()添加到每个子类。

What are the advantages, disadvantages of these approaches? 这些方法的优点和缺点是什么?

There are two obvious downsides to map-based approach: 基于地图的方法有两个明显的缺点:

  1. Absence of well-defined parameter names. 缺少定义明确的参数名称。 Yes, you could define them as constants somewhere but you'd still need to check that parameter name is valid as passed. 是的,您可以在某处将它们定义为常量,但是您仍然需要检查参数名称在传递时是否有效。
  2. Absence of well-defined parameter types. 缺少明确定义的参数类型。 Even worse then above - if I need to pass an integer I'd have to convert it to String and you'll have to parse it (and deal with possible errors). 甚至比上面更糟糕的是-如果我需要传递一个整数,则必须将其转换为String,然后您必须解析它(并处理可能的错误)。 Can be somewhat mitigated by using Map<String,Object> and auto-bounding but then you'd still need to validate appropriate types. 通过使用Map<String,Object>和自动绑定可以在某种程度上缓解这种情况,但是您仍然需要验证适当的类型。

Setter-based approach has only one downside - it can't be done. 基于Setter的方法只有一个缺点-无法做到。 That is, it can't be reliably done by using setters ALONE - you need to supplement it with some kind of init() or afterPropertiesSet() method that will be called after all setters and will allow you to perform additional (co-dependent) validation and initialization steps. 也就是说,它无法通过制定者单独做可靠的-你需要某种形式来补充它init()afterPropertiesSet()方法,将所有setter方法之后被调用,将允许您执行额外的(互相依赖)验证和初始化步骤。

Also, something like this practically begs for some kind of Dependency Injection framework. 同样,类似这样的东西实际上是某种依赖注入框架的乞求。 Like Spring , for example. 例如,像Spring

I wouldn't say that passing a Map (or Properties) object in the constructor is necessarily preferred over child class specific setter, or vice versa. 我不会说与子类特定的setter相比,在构造函数中传递Map(或Properties)对象一定是首选,反之亦然。 Which approach is best depends on how you are going to instantiate the classes. 哪种方法最好取决于您如何实例化这些类。

If you are going to instantiate the classes directly from Java then the Map approach tends to be neater, especially if you have a good way to assemble the maps. 如果要直接从Java实例化类,则Map方法趋于整洁,尤其是如果您有汇编这些Map的好方法时。 (For example, loading a Properties object from a property file.) The 'setters' approach forces you to write code against each of the child class APIs. (例如,从属性文件加载Properties对象。)“ setters”方法迫使您针对每个子类API编写代码。

On the other hand, if you are going to instantiate the classes using some container framework that supports "wiring", "inversion of control" or the like (eg Spring, PicoContainer, JavaBeans, etc), then setters are generally better. 另一方面,如果要使用一些支持“接线”,“控制反转”之类的容器框架(例如Spring,PicoContainer,JavaBeans等)实例化类,则设置方法通常会更好。 The framework typically takes care of when and how to instantiate the classes and call the setters, using reflection under the hood to do the work. 该框架通常会在何时以及如何实例化类并调用setter的情况下进行处理,使用幕后的思考来完成工作。

So the answer is ... it depends ... 所以答案是...这取决于...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM