设计一个具有延迟加载特性的javapojo 请考虑下面的例子:
web应用程序为每个登录的用户创建一个用户对象。此对象具有简单的设计一个具有延迟加载特性的javapojo 请考虑下面的例子:,java,session,design-patterns,Java,Session,Design Patterns,web应用程序为每个登录的用户创建一个用户对象。此对象具有简单的String属性,用于firstName,lastName 每个用户也可以拥有一辆汽车。考虑到获取用户 Cub/COD>非常昂贵,所以当用户登录时,我们不喜欢设置用户车。相反,我们希望在用例需要时得到汽车 为了实现这一点,我们将用户pojo创建为: public class User() { private String FirstName; private String LastName; private Car
String
属性,用于firstName
,lastName
每个用户也可以拥有一辆汽车。考虑到获取用户<代码> Cub/COD>非常昂贵,所以当用户登录时,我们不喜欢设置用户车。相反,我们希望在用例需要时得到汽车
为了实现这一点,我们将用户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()
然而,有人认为这样一来,我的用户对象就不再是一个简单的pojo了,这不是一个好方法
我如何才能更好地实现这一要求
我一直认为,以这种方式,我的用户对象不是一个简单的pojo
为了回答你的问题,我想先回顾一下历史
Pojo是一个普通的旧java对象,意味着您只使用“标准”java。这个术语是在J2EE大肆宣传的时候创建的。此时,开发人员在企业bean中编码业务逻辑,而这个EJB需要大量的基础结构代码。这一事实将业务逻辑与实现技术相结合。因此,Rebecca Parsons、Josh MacKenzie和Martin Fowler得出结论,如果只使用标准java,业务逻辑将更易于重用和测试。因此他们创造了这个术语,因为开发者喜欢花哨的名字
您的用户
类只依赖于标准java,因此它是一个pojo
一些开发人员认为pojo不应该包含任何逻辑。这些开发者更喜欢贫血模型。另一些人说,丰富的模式是更好的方法。我属于那些喜欢丰富模型而不是贫乏模型的开发人员
如果要从User
类中删除CarServices
依赖项,可以实现Car
延迟加载代理,就像hibernate或jpa实现一样
至少以下是我对bean、pojo、贫血和富领域模型的一些想法
希望它能帮助您与其他开发人员进行讨论。您可以使用对汽车供应商对象的引用,而不是对汽车供应商对象的引用,该对象的实现可以缓存获得的第一个结果(请参见Guava的供应商和备忘录供应商类)。通过这样做,您可以向用户
对象隐藏其car在实例化时可能存在或不存在的事实,从而使其实现更简单(getter方法中没有更多逻辑)
此解决方案的另一个优点是打破User
和CarServices
类之间的耦合(不再需要CarServices
属性)。一个可以注入一个供应商,其实现将返回对已经可用的Car
对象的引用,而另一个可以传递一个实现,将调用转发给CarServices
服务
但是,它不会使用户
类更像POJO(如上面第一个答案所解释的),但是,与您的解决方案争论过的人可能更喜欢这个解决方案,因为它更简单,耦合更少。您将Car
声明为cars
,但后来使用Car
作为变量,它是一个打字错误吗?如果是,请更正它。如果用户类必须封装获取汽车的方式,那么您拥有的代码就是方法。如果获取汽车是用户不应该知道的事情,那么使用经典的setCar/getCar范例。然后,合同是让用户客户端在获得汽车之前设置汽车,客户端必须处理空的getCar响应。-此外,POJO用户和UserWithCar子类可能是一种方法-取决于您的总体设计,您是否愿意这样做。