Java 设计模式-从不同类型的数据源创建对象
我一直在尝试为以下场景找到合适的设计模式(如果存在正式模式): 对象A需要一个对象B。现在,可以使用来自不同来源的数据创建对象B,例如S_1或S_2。我不希望A必须关心创建B,它应该被赋予并继续。那么,有没有一种干净的方法来创建B呢?我已经考虑过工厂类型模式,但我没有多态性。我的想法是:Java 设计模式-从不同类型的数据源创建对象,java,design-patterns,Java,Design Patterns,我一直在尝试为以下场景找到合适的设计模式(如果存在正式模式): 对象A需要一个对象B。现在,可以使用来自不同来源的数据创建对象B,例如S_1或S_2。我不希望A必须关心创建B,它应该被赋予并继续。那么,有没有一种干净的方法来创建B呢?我已经考虑过工厂类型模式,但我没有多态性。我的想法是: B obj_b = B.createInstance(type_S_1); obj_A.doSomething(obj_B); 其中,我为静态方法createInstance()提供了数据类型soruce 我
B obj_b = B.createInstance(type_S_1);
obj_A.doSomething(obj_B);
其中,我为静态方法createInstance()提供了数据类型soruce
我仍然在学习很多关于设计模式的知识,所以这就是我问的原因。我可能把事情复杂化了,所以请随便说吧 我不确定,但也许您可以给它一个类型来指定要构建的内容。正如您所意识到的,抽象工厂模式对于您的用例来说是多余的,因为您不需要多态性。尽管如此,这种设计模式的具体工厂部分还是有意义的。所以这看起来有点像:
Datasource ds1 = ...;
Datasource ds2 = ...;
MyObject objectA = ...;
DatasourceBasedFactory factory1 = new DatasourceBasedFactory(ds1);
objectA.doSomething(factory1.create());
了解更多关于你真正想做的事情可能有助于给你一个更好的答案。您当前的问题描述非常抽象。。。如果你能给我们更多关于你的领域的细节,这将有助于给你一个更好的答案。 < P>我会考虑使用泛型的2种不同的方法。 例如,客户端将只处理可能是final的公共结果对象。 无论您的数据源是什么,都可以减少对客户机的影响 方法1 范例
公共接口数据源提取器{
公共数据源提取结果提取(T源);
}
公共最终结果文本提取器实现DataSourceExtractor{
公共数据源提取结果提取(结果集源){
//代码在这里
返回null;
}
}
公共最终结果文本提取器实现DataSourceExtractor{
公共数据源提取结果提取(JsonNode源){
//代码在这里
返回null;
}
}
但您也可以满足抽象类和接口的优点。
优点是客户端将继承常用方法,或者您甚至可以实现模板方法
范例
公共AbstractDataSourceExtractor实现DataSourceExtractor{
公共静态最终SomeObject commonMethod(DataSourceExtractResult结果){
//代码在这里
返回null;
}
}
公共最终结果文本提取器扩展了AbstractDataSourceExtractor{
公共数据源提取结果提取(结果集源){
//代码在这里
返回null;
}
}
公共最终结果文本提取器扩展了AbstractDataSourceExtractor{
公共数据源提取结果提取(JsonNode源){
//代码在这里
返回null;
}
}
方法2
范例
如果需要为实例的构造设置许多元素,也可以考虑使用通用抽象生成器。
该解决方案的advatange是,您可以设置一个默认值,必要时提供对客户端隐藏的内部实现
public abstract class AbstractDataSourceExtractResultBuilder<T>{
private T _source;
public AbstractDataSourceExtractResultBuilder(T source) {
_source = source;
}
public abstract DataSourceExtractResult build();
}
public final class JsonDataSourceExtractBuilder extends AbstractDataSourceExtractResultBuilder<JsonNode> {
private String _name;
private Charset _charset;
public JsonDataSourceExtractBuilder(JsonNode source, String name){
//GUARD CODE
super(source);
_name = name;
_charset = Charset.defaultCharset();
}
public JsonDataSourceExtractBuilder useCharset(Charset charset){
if(charset == null){
throw new IllegalStateException("The charset is null");
}
_charset = charset;
return this;
}
//etc...
public DataSourceExtractResult build(){
//CODE HERE
return null;
}
}
公共抽象类AbstractDataSourceExtractResultBuilder{
私人T_来源,;
公共抽象数据源ExtractResultBuilder(T源){
_来源=来源;
}
公共抽象数据源ExtractResult build();
}
公共最终类JsonDataSourceExtractBuilder扩展了AbstractDataSourceExtractResultBuilder{
私有字符串\u名称;
私有字符集;
公共JsonDataSourceExtractBuilder(JsonNode源,字符串名称){
//保护码
超级(来源);
_名称=名称;
_charset=charset.defaultCharset();
}
公共JsonDataSourceExtractBuilder使用字符集(字符集字符集){
if(字符集==null){
抛出新的IllegalStateException(“字符集为null”);
}
_字符集=字符集;
归还这个;
}
//等等。。。
公共数据源ExtractResult生成(){
//代码在这里
返回null;
}
}
Builder意味着一个内置的对象和一个控制构建过程的控制器。可能与这个用例不完全匹配。B总是属于同一个类?当createInstance()
被赋予不同的源时,B是如何变化的?B总是相同的。唯一的区别是用于构建它的数据源。数据源是什么?哪些类型的简单数据或类?谁决定哪种来源适用?A班?是设计中预期的唯一来源,还是将来将添加更多?如果你描述我们更好的设计可以帮助你。从你告诉我们的,也许不值得寻找一个模式。有时候简单更好。
public AbstractDataSourceExtractor<T> implements DataSourceExtractor<T> {
public static final SomeObject commonMethod(DataSourceExtractResult result) {
//CODE HERE
return null;
}
}
public final ResultSetExtractor extends AbstractDataSourceExtractor<ResultSet>{
public DataSourceExtractResult extract(ResulSet source) {
//CODE HERE
return null;
}
}
public final ResultSetExtractor extends AbstractDataSourceExtractor<JsonNode>{
public DataSourceExtractResult extract(JsonNode source) {
//CODE HERE
return null;
}
}
public abstract class AbstractDataSourceExtractResultBuilder<T>{
private T _source;
public AbstractDataSourceExtractResultBuilder(T source) {
_source = source;
}
public abstract DataSourceExtractResult build();
}
public final class JsonDataSourceExtractBuilder extends AbstractDataSourceExtractResultBuilder<JsonNode> {
private String _name;
private Charset _charset;
public JsonDataSourceExtractBuilder(JsonNode source, String name){
//GUARD CODE
super(source);
_name = name;
_charset = Charset.defaultCharset();
}
public JsonDataSourceExtractBuilder useCharset(Charset charset){
if(charset == null){
throw new IllegalStateException("The charset is null");
}
_charset = charset;
return this;
}
//etc...
public DataSourceExtractResult build(){
//CODE HERE
return null;
}
}