【问题标题】:How to design layer architecture for web application?如何为 Web 应用程序设计层架构?
【发布时间】:2013-12-29 01:47:52
【问题描述】:

我在实现 1 个简单的 Web 应用程序时遇到了设计问题。 我使用 struts2 web 控制器、spring 的 IOC 和 Hibernate 作为持久层。

因为这个网络应用程序在乞讨方面非常简单。所以我只有两层: 1 DAO 层,用于访问数据库。几乎每个表都有相关的 DAO。 2 动作层。用户struts2。 我对这种架构很满意,因为可以快速实现我的 Web 应用程序。 随着项目变得越来越大,我发现动作层变得庞大而复杂,并且很难重用。 我尝试创建服务层,解决复杂的业务逻辑很好,但我的应用程序仍然有很多简单的逻辑。例如:加载 1 个对象,保存 1 个对象,通过某种条件获取集合并显示到网页。如果给每个简单的数据库访问方法都有相应的服务方法。还是费了不少功夫。如何解决这个问题? 而且我认为,如果服务层存在,直接调用 DAO 层对我的应用程序来说仍然不是很好的设计。 这种小型网络应用有什么好的解决方案吗?

【问题讨论】:

    标签: java jakarta-ee architecture domain-driven-design layer


    【解决方案1】:

    在 Web 应用程序中规划不同层时,最好在不提供身份上下文的情况下明确保护模型中的属性和关联不被操纵。

    这是既不应该在 DAO 层也不应该在 Controller 中完成的事情。您应该将您的 DAO 层包装在服务层中,并让控制器只与服务而不是直接与 DAO 对话。

    保护您的模型免受不必要的操作意味着您将控制器和服务之间的数据结构中传递的信息量调整为您想要执行的实际操作。

    例如:从集合中添加或删除元素是服务中的显式操作,它不会通过将集合作为 DAO 对象的成员进行操作并将该 DAO 传回服务来隐式发生。

    相反,您的服务可能如下所示:

    + getAllCompanies(): CompanyType[*]
    + getAllEmployeesOfCompany(c: CompanyType) : EmployeeType[*]
    + addEmployeeToCompany(e: EmployeeType, c: CompanyType)
    + removeEmployeeFromCompany(e: EmployeeType, c: CompanyType)
    

    这种架构的额外好处是服务层可以作为交易的边界。使用控制器的方法作为事务的边界实际上是一个非常糟糕的习惯。你甚至可以称之为反模式。为什么?因为例如,这意味着当您的客户端挂断时,它会回滚您的事务。这在 99% 的情况下显然是不需要的。

    【讨论】:

    • 嗨,mwhs,谢谢你给我这么详细的建议。我完全同意大型或中型 Web 项目中的解决方案。但是对于我们的小型 Web 应用程序。虽然服务器层可以帮助解决一些重复使用的问题并使我的代码看起来不错。但是我还是花了很多时间来包装那些简单的 DAO 方法,甚至在服务器层给出有意义的名称。顺便说一句:我使用 OpenSessionInViewFilter,因为我的项目很小。
    • 如果时间是您最担心的问题,我建议您尝试生成一些代码而不是输入代码。通常,模型驱动方法 (MDA/MDSD) 会在重复性任务上为您节省大量时间。查看 Acceleo 项目。
    • 或者也许可以尝试其中一个域驱动的框架,例如 Apache ISIS,它会占用您大量的工作。
    【解决方案2】:

    正如@mwhs 评论的那样,Apache Isis 为您的应用分层提供了大量指导。要确定它是否符合您的要求,您可以浏览我在最近一次会议上提出的 tutorial

    【讨论】:

      猜你喜欢
      • 2013-12-08
      • 2014-06-20
      • 2011-09-30
      • 2019-12-23
      • 2021-06-02
      • 1970-01-01
      • 2018-08-27
      • 2010-10-06
      • 1970-01-01
      相关资源
      最近更新 更多