【问题标题】:Design-pattern to use to access similar objects with different field names用于访问具有不同字段名称的相似对象的设计模式
【发布时间】:2014-01-30 15:09:42
【问题描述】:

哪种设计模式(如果有)最适合这种情况。

public class PersonFromDB1 {
  private String firstName;
  private String lastName;
  private String Car;
}

public class PersonFromDB2 {
  private String first_name;
  private String last_name;
  private String boat;
}

在这两种人类型中,我想处理的唯一数据是拳头和姓氏,而不管它在不同数据库中的字段名称如何。 firstName 和 first_name 代表相同的 - 个人/客户的姓名 - lastName 和 last-name 也是如此。在我的示例中,汽车和船字段完全不相关,因此应该被忽略。

使用,也许是多态性或适配器模式 (?),我想创建一个对象列表,其中包括来自 DB1 和 DB2 的人员在同一类型 - PersonInOurDB 下。

最后,我的目标是能够单独在 myClass 上调用 GSON 序列化/反序列化。

public class PersonInOurDB {
  private String firstname;
  private String lastname;
}

【问题讨论】:

  • A_1 和 B_1 是等价的吗?你是什​​么意思?既然他们在同一个班级,这有什么帮助?您可能是指 A_1 和 A_2 吗?您的示例中也没有字段 D(我假设您的意思是字段 E)。你能举例说明 TypeA 和 TypeB 的合并是什么意思吗?我可以猜测,但很难真正判断。
  • 您希望两个对象(TypeA 和 TypeB)在序列化为 json 时看起来相等吗?例如。 {"A":"StringValue","B":"StringValue"}
  • 里奇和勒内,我的错。我澄清了我的小例子。
  • 没错,我希望这些是平等的,所以让 gson 一次性处理这些

标签: java design-patterns polymorphism gson


【解决方案1】:

您真正需要的是基于类型的简单选择。这可以被认为是一种构建器模式,因为它只是初始化了一个新的 myClass 实例。

注意,这是粗略的伪代码。

FunctionName(SomeType instance)
{
  string aPostfix = "_1";
  string bPostfix = "_2";

  string selectedPostFix;

// This is your strategy selector
  switch(typeof(SomeType.Name)
  {
    case "TypeA":
      selectedPostFix = aPostFix;
    case "TypeB":
      selectedPostFix = bPostFix;
  } 

  return new myClass()
  {
    A = instance.GetProperty("A" + selectedPostfix).Value,
    B = instance.GetProperty("B" + selectedPostfix).Value,
    ...

  }
}

【讨论】:

    【解决方案2】:

    如果你想在java中为两个对象提供一个通用的访问api,那么引入一个接口,让两者都实现。

    如果您只希望两个对象(PersonFromDB1PersonFromDB2)通过 json 以相同的方式序列化,您可以:

    • 使用注释 - @SerializedName 注释与 @Expose 结合使用。
    • 使用FieldNamingStratgyExclusionStrategy

    使用注解控制序列化

    public class PersonFromDB1 {
    
        @Expose
        @SerializedName("firstName")
        private String firstName;
    
        @Expose
        @SerializedName("lastName")
        private String lastName;
    
        private String car;
    }
    
    public class PersonFromDB2 {
    
        @Expose
        @SerializedName("firstName")
        private String first_Name;
    
        @Expose
        @SerializedName("lastName")
        private String last_Name;
    
        private String boat;
    }
    

    然后你可以使用GsonBuilder

    Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
    PersonFromDB1 person1 = ...; // get the object
    PersonFromDB2 person2 = ...; // get the object
    
    System.out.println(gson.toJson(person1));
    System.out.println(gson.toJson(person2));
    

    使用FieldNamingStratgyExclusionStrategy控制序列化

    如果您不想修改 db 对象(您不能或不想添加注释),那么还有另一种方法。您可以使用FieldNamingStratgyExclusionStrategy

    class PersonFromDBNamingStrategy implements FieldNamingStrategy {
    
        Map<String, String> fieldMapping = new HashMap<String, String>();
    
        public PersonFromDBNamingStrategy() {
            fieldMapping.put("first_Name", "firstName");
            fieldMapping.put("last_Name", "lastName");
        }
    
        @Override
        public String translateName(Field f) {
            String name = f.getName();
            if(fieldMapping.contains(name)){
                 return fieldMapping.get(name);
            }
            return name;    
        }
    }
    

    还有ExclusionStrategy

    class PersonFromDExclusionStrategy implements ExclusionStrategy {
    
        List<String> validNames = Arrays.asList("car", "boat");
    
        @Override
        public boolean shouldSkipField(FieldAttributes f) {
            String name = f.getName();
            return !validNames.contains(name);
        }
    
        @Override
        public boolean shouldSkipClass(Class<?> clazz) {
            return false;
        }
    }
    

    然后像这样创建 Gson:

    GsonBuilder gsonBuilder = new GsonBuilder();
    sonBuilder.addSerializationExclusionStrategy(new PersonFromDExclusionStrategy());
    gsonBuilder.setFieldNamingStrategy(new PersonFromDBNamingStrategy());
    Gson gson = gsonBuilder.create();
    
    PersonFromDB1 person1 = ...; // get the object
    PersonFromDB2 person2 = ...; // get the object
    
    System.out.println(gson.toJson(person1));
    System.out.println(gson.toJson(person2));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-20
      • 1970-01-01
      • 2016-08-25
      • 1970-01-01
      相关资源
      最近更新 更多