Java 设计模式-从不同类型的数据源创建对象

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 我

我一直在尝试为以下场景找到合适的设计模式(如果存在正式模式):

对象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


我仍然在学习很多关于设计模式的知识,所以这就是我问的原因。我可能把事情复杂化了,所以请随便说吧

我不确定,但也许您可以给它一个类型来指定要构建的内容。

正如您所意识到的,抽象工厂模式对于您的用例来说是多余的,因为您不需要多态性。尽管如此,这种设计模式的具体工厂部分还是有意义的。所以这看起来有点像:

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

}