设计具有延迟加载属性的

时间:2015-11-22 05:44:59

标签: java session design-patterns

请考虑以下示例:

Web应用程序为每个登录用户创建一个用户对象。此对象具有StringfirstName ...

的简单lastName属性

每个用户也可以拥有car。考虑到提取用户car非常昂贵,因此我们不希望在用户登录时设置用户汽车。相反,我们希望在用例需要时获取汽车。

为了实现这一点,我们创建了一个用户pojo:

public class User() {
  private String FirstName;
  private String LastName;   
  private Car car;
  //Here we have the service object, this could be injected with spring or JEE
  private CarServices carServices;

  public Car getCar() {
    //If the car is not fetched yet, go on and get it from your service
    if (car == null) {
      car = carServices.getCarFromDB(...)
    }
    return car;
  }

}

登录后的初始用户:

User newUser = new User();
newUser.setFirstName("foo");
newUser.setLastName("bar");
//We just let user have service, so he can use this service latter
newUser.setCarServices( new CarServices() );

每个需要用户车的用例都可以轻松搞定:

newUser.getCar()

然而,我一直认为,通过这种方式,我的User对象不再是一个简单的pojo,这不是一个好方法。

如何以更好的方式达到此要求。

2 个答案:

答案 0 :(得分:3)

  

我一直认为,通过这种方式,我的User对象不是简单的pojo

为了回答你的问题,我首先想回顾一下历史。

Pojo是一个普通的旧java对象,意味着你只使用"标准" java的。该术语是在J2EE受到炒作的时候创建的。此时,开发人员在企业bean中编写业务逻辑,这些EJB需要大量的基础架构代码。这一事实将商务逻辑与实施技术相结合。因此,Rebecca Parsons,Josh MacKenzie和Martin Fowler得出的结论是,如果您只使用标准java,业务逻辑将更易于重用并且更容易测试。因此他们创建了术语pojo,因为开发人员喜欢花哨的名字。

您的 User 类只取决于标准的java,因此它是一个pojo

一些开发人员认为pojo不应包含任何逻辑。这些开发人员更喜欢贫血模型。其他人说丰富的模式是更好的方法。我属于那些喜欢丰富模型而不是贫血模型的开发人员。

如果您要从CarServices类中删除User依赖项,您可以实现 Car延迟加载代理,就像hibernate或jpa实现一样。

至少我对豆类,pojos,贫血和丰富的领域模型有一些想法。

希望在与其他开发人员讨论时帮助您。

答案 1 :(得分:1)

您可以使用对汽车供应商对象的引用,而不是对汽车的引用,该对象的实现可以缓存获得的第一个结果(请参阅番石榴的SupplierMemoizingSupplier类)。通过这样做,您可以在User对象中隐藏它的汽车在实例化时可能存在或不存在的事实,从而使其实现更简单(在getter方法中不再有逻辑)。

此解决方案的另一个优点是打破UserCarServices类之间的耦合(不再需要carServices属性)。可以注入一个供应商,其实现将返回对已经可用的Car对象的引用,而另一个可以通过将该调用转发给CarServices服务的实现。

虽然不会让User类更多地成为POJO(正如上面的第一个答案中所解释的那样),但是那些与你的解决方案争论的人可能会更喜欢这个更好的因为它更简单并且紧密耦合。