有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

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

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


共 (3) 个答案

  1. # 1 楼答案

    我会考虑使用泛型2种不同的方法。 例如,客户端将只处理一个公共结果对象,该对象可能是final。 无论您的数据源是什么,都可以减少对客户机的影响

    方法1

    示例

    public interface DataSourceExtractor<T> {
         public DataSourceExtractResult extract(T source);
    }
    
    public final ResultSetExtractor implements DataSourceExtractor<ResultSet>{
         public DataSourceExtractResult extract(ResulSet source) {
           //CODE HERE        
           return null;
         }
    }
    
    public final ResultSetExtractor implements DataSourceExtractor<JsonNode>{
         public DataSourceExtractResult extract(JsonNode source) {
           //CODE HERE
           return null;
         }
    }
    

    但您也可以满足抽象类和接口的优点。 优点是客户端将继承常用方法,或者您甚至可以实现模板方法

    示例

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

    方法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;
       }
    
    }
    
  2. # 2 楼答案

    我不确定,但是您可以给它一个类型来指定要构建什么

  3. # 3 楼答案

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

    Datasource ds1 = ...;
    Datasource ds2 = ...;
    
    MyObject objectA = ...;
    
    DatasourceBasedFactory factory1 = new DatasourceBasedFactory(ds1);
    objectA.doSomething(factory1.create());
    

    了解更多关于你真正想做的事情可能有助于给你一个更好的答案。您当前的问题描述非常抽象。。。如果你能给我们一些关于你的域名的更多细节,那将有助于给你一个更好的答案