构造函数自动连接到不同参数的实现的设计模式



我有一个包含两个实现的接口,现在我必须添加更多的实现。每个实现接口在构造函数中都有不同的参数,构造函数将自动连接,bean将被注入。我需要编写一个通用的工厂方法,如果我传入一个客户端,它将返回特定类型的实现,并设置所有自动连接的属性。请告知如何操作?

Interface Example{
List<String> getData(String url);
boolean isCorrectData(String var1, String var2);
}

客户端1:

public class client1 implements Example{
final XclientConfig config;
final RestTemplate template;
@Autowired
public client1(XClientConfig config, @Qualifier(“template1”)  RestTemplate template){
this.config = config;
this.template = template;
}

客户端2:

public class client2 implements Example{
final YclientConfig config;
final RestTemplate template;
@Autowired
public client2(YClientConfig config, @Qualifier(“template2”)  RestTemplate template){
this.config = config;
this.template = template;
}

现在我正在尝试编写一个工厂类,在其中我传递客户端名称(客户端1或客户端2(,工厂将返回一个完整构造的Example实例,因此不应该有任何未完成的依赖项。我需要通过工厂方法注入所有的依赖项。你能给我建议吗。

概述

您应该尝试在Factory中使用反射。可以通过创建键值对的属性文件(只是一个名为properties.config的基本文本文件(来设置反射。这允许您更改文本文件中的实现。文本中这种格式的示例如下:

ClientConfiguration,Client1

其中ClientConfiguration是访问客户端配置的特定密钥。返回的值为字符串形式的"Client1"。如果要使用Client2,只需更改该值即可。

在特性文件上使用反射

下一步是使用反射将此字符串更改为实际的Client1类型。您不能直接转换为Client1,而是希望转换为客户端配置,因为它将是所有实现的父类型。为此,您需要一个properties对象。然后,您需要一个Input流对象来读取您的properties.config文件,并将该文件中的属性添加到新创建的属性对象中。不这样做将意味着您的属性对象将是空的,因此对您没有帮助。

Properties prop = new Properties()
InputStream input = new FileInputstream(//put your properties.config filename here)
prop.load(input)
Clientconfig clientconfig = prop.get(//input the key of the implementation you want here)

//对于本例,密钥将是ClientConfiguration,并确保字符串与文件上的//匹配

使用反射类类型创建具有正确格式数据的该对象的实例

现在您可以获得类类型了,可以调用构造函数并根据数据设置参数。我不知道数据的具体格式,但我建议使用类似CommaSeperatedValue的格式,其中文件包含Client1Client2"数据"的一些描述。然后你应该有这个划定的第一行是类的字段。例如:

//inside Foo.txt
config,template
config_a,template_a
config_b,template_b
...

使用数据和类类型创建任何类类型的实例,而不考虑字段数

以这种方式格式化数据可以构造这些Client对象,而无需像通常使用Client1 client1 = new Client1(arg1,arg2)那样在Factory类中调用它们的构造函数。相反,您可以制作一个Fieldmap(作为StringsFeild对象的字段名映射(

//get your file read and into an array of strings or something similar
Map<String,Field> fieldmap = new Hashmap
Constructor constructor = clientconfig.getConstructor
ClientConfig objectinstance = constructor.inkvoke(//fill in every argument with null here)
//put all the pairs in the fieldmap
for(String fieldname://insert first line of file here){
fieldmap.put(fieldname,Field)
}
//for each field in the object, retrieve the feild value from the feildmap and set it 
//in the object using the matching name
for(Field field:objectinstance){
field.set(objectinstance,fieldmap.get(field.getName))
}

现在您有了一个完全构建的类实例!如果你想更改实现,只需更改properties.config,其余的由Factory完成。当实际创建这些类的实例时,大多数代码都属于Factory,每个构造都是一样的。唯一改变的是什么类反映在其中,但假设数据的格式正确(如上所述(,您应该能够构造任何类型的实例。你甚至可以更进一步,把它变成一个通用的对象工厂,因为它基本上就是这样,构造任何类的实例。注意,我不保证复制粘贴这个,但这是我通常做的。

最新更新