代码之家  ›  专栏  ›  技术社区  ›  Jacob Mattison

SpringMVC表单支持对象树初始化的最佳实践

  •  7
  • Jacob Mattison  · 技术社区  · 17 年前

    如果我有一个表单支持对象,它有一个复杂的对象树——比如一个人有一个联系人信息对象,这个对象有一个地址对象,这个地址对象有一堆字符串——那么在绑定到这个对象之前,这个对象似乎需要完全填充组件对象。因此,如果我正在创建一个新的Person,我需要确保它已经填充了所有的组件对象,如果我正在从数据库检索Person,我需要确保没有从数据库填充的任何对象都填充了空对象。

    其次,初始化对象的最佳方式是什么。我可以想出几种方法。一种是在声明时初始化所有成员对象:

    public class Person {
         String name;
         ContactInfo contactInfo = new ContactInfo();
         //getters, setters, etc.
    }
    
    public class ContactInfo {
         String phone;
         Address homeAddress = new Address();
    }
    

    另一种方法是使用PersonFactory初始化所有内容(或者使用factory方法Person.getInstance初始化所有内容)。

    在从数据库中检索一个人的情况下,第一种方法将解决这个问题(即,如果这个特定的人在数据库中没有地址,那么该对象仍将有一个地址),但这将意味着每个对象创建两次。不知道如何处理这个问题,除非使DAO显式地填充所有内容,即使没有从数据库中检索到任何内容。或者给工厂一个方法来遍历对象并“填充”缺少的任何内容。

    建议?

    4 回复  |  直到 17 年前
        1
  •  4
  •   Jacob Mattison    17 年前

    如果您愿意,可以称之为overkill,但实际上我们最终做的是创建一个通用工厂,它将接受任何对象并使用反射(递归地)查找所有空属性并实例化正确类型的对象。我是用ApacheCommonsBeanutils做的。

    通过这种方式,您可以获取从各种来源(DAO、XML反序列化等)获得的对象,将其传递到此工厂,并将其用作表单支持对象,而无需担心绑定所需的内容可能为空。

    诚然,这意味着实例化我们可能不需要的属性,但在我们的例子中,这通常不适用。

        2
  •  3
  •   Nick Holt    17 年前

    我通常会确保对象被完全初始化——这使使用对象变得更加简单,并避免在代码中分散空检查。

    在这里给出的例子中,我可能会将初始化放在getter中,这样子对象只有在实际使用时才被实例化,即:调用getter时,然后仅当它为null时。

    就从数据库加载一对一关系而言,我通常会进行连接并加载批次。性能影响通常是最小的,但您应该知道可能有一个。

    当涉及到一对多关系时,我通常会选择延迟加载。Hibernate将为您解决这一问题,但如果您正在运行自己的,那么您只需要一个自定义的List实现,当调用与其内容相关的任何方法时,该实现将调用相应的DAO。

        3
  •  1
  •   Olivier    17 年前

    < form:input path="person.contactInfo.homeAddress.street"/> ?

    1) 是的,当你写作的时候 person.contactInfo.homeAddress.street person.getContactInfo().getHomeAddress().getStreet()

    2) 我通常在声明时初始化成员对象,就像在代码段中一样。如果初始化值是非条件的,则看不到factory类执行此任务的好处。 我不清楚你被迫两次创造一个人的问题。。。但是我可能累了;)

        4
  •  1
  •   bpapa    17 年前

    我采用了工厂方法(不喜欢为它使用单独的类,对我来说,将它放在一个静态方法中更合理,所以它都在一个地方)。我有点像-

    public static Person getInstanceForContactInfoForm() {
          ContactInfo contactInfo = ContactInfo.getInstanceForContactInfoForm();
    
          Person person = new Person(contactInfo);
          // set whatever other properties you need for Person
          // just enough to 1-render the form and 2-avoid any exceptions
          return person;
    }
    

    如果我从数据库中加载Person,Person类中有一个名为“initializeForContentActinFoForm”之类的方法。从数据库加载Person之后,我将在服务层调用这个方法,该方法由SpringMVC方法调用,该方法返回表单备份对象。

    我不认为这是一个真正的惯例,这只是我自己制定的一种方法。我真的不知道有什么缺点,所以如果有人不同意,请让我知道。。。