对于典型的 Web 3 层应用程序,您在以下设计中看到了哪些缺陷(以及您理想的架构建议)?
我目前的蓝图方法是非常粗略的(假设 Java、Spring、Hibernate、JSP)
控制器
无状态,可能用只读事务包装(以避免惰性初始化异常),仅通过服务从持久存储中获取实体,将它们作为模型传递给视图。对它们进行业务逻辑(BL应该只在服务层吗?),如果需要,传递回服务层进行持久化。
优点:对于只读事务包装 - 只有一个连接,同一个持久实体没有冗余命中,更好地利用查询缓存,服务层不应该“知道”请求参数或所需的初始化图跨度,避免惰性初始化异常。
缺点:只读事务方法可能有风险,控制器不是理想的业务逻辑悬挂场所......很难做 JUnits(你的输入是一个请求......)
看法
非事务性(访问非惰性集合/成员将导致惰性初始化异常)
优点:
视图作者不应仅仅通过点符号来影响应用程序的性能(例如,由于延迟初始化大型集合而导致 N+1 选择。
同样在断开连接的客户端(Flex 或其他富客户端)中,远程延迟初始化要么不受支持,要么不明智
缺点:控制器/服务/DAO 必须为视图仔细准备正确的实体图,并且可能会过冲(性能)/下冲(惰性初始化异常)。无数的服务器端方法可能会导致混乱,因为对于可以初始化实体图的排列数量存在笛卡尔积
模型
按原样使用持久对象(无数据传输对象),状态保存在会话中。
优点:无需重写 POJO,重用现有实体,会话状态比隐藏字段状态处理更安全。
缺点:对断开连接的框架不利,保存陈旧断开连接对象的风险,锁定问题的风险,覆盖其他数据,有时需要乐观锁定。
服务
事务性的,不知道请求范围,调用 DAO 层进行实际的持久化存储访问。这是 BL 通常应该在的地方,但似乎 BL 一遍又一遍地泄漏到控制器端。
道
包含原子持久化存储门面,不知道 BL,或任何上下文
最后,问题:
你会在上述架构中修复什么?
您是否(像我一样)认为这是一种相当普遍的方法(有一些细微差别,例如开放会话等)?或者这是您第一次看到它并且我正在做一些非常错误(或正确)的事情?
你如何在你的应用程序中解决它?您是否也将实体 POJO 用于您的模型和视图?还是将其连接到更简单的 UI bean(全部已完全初始化且安全)?
这可能是一个主观问题,但我确信有明确的最佳实践设计模式可以聚集到最多一个、两个或三个一般“宗教”。