分离模型,视图和控制器的最佳方法

时间:2010-06-21 14:43:55

标签: java model-view-controller architecture data-structures

我正在考虑将模型视图和Controller-for Java分离并使用Eclipse的最佳方法,如果它有所不同。

我曾经将每个类型的MVC分离到自己的包中,但我开始认为这不是最好的方法:

  • com.company.client(controler)
  • com.company.client.model
  • com.company.client.view

  • com.company.another(controler)

  • com.company.another.model
  • com.company.another.view

  • com.company.yetAnother(controler)

  • com.company.yetAnother.model
  • com.company.yetAnother.view

(假设有很多不同的包,每个包都有自己的视图和模型)

我想过使用:

  • com.company.client
  • com.company.another
  • com.company.yetAnother

  • com.company.model.client

  • com.company.model.another
  • com.company.model.yetAnother

  • com.company.view.client

  • com.company.view.another
  • com.company.view.yetAnother

我甚至考虑过将控制器,模型和视图放在不同的项目中。也许它会更加模块化,我会更加确定视图不使用控制器,例如(因为控制器项目将包含视图,但不是相反)。

那么分离M,V和C的最佳方法是什么?

(考虑网络和桌面应用,而不仅仅是网络)

6 个答案:

答案 0 :(得分:5)

Graal Quest!你有二维矩阵与垂直(MVC)和水平(业务规则)层......

  • 我没有找到严格的答案
  • 您的第一种方法看起来不错,因为模块化导向(可能是非预期的)
  • 对于一个小应用程序,你的第二个虽然可以接受

对我来说,回复是一个词:依赖
继续搜索“包装设计/策略”; “粒度”

一些阅读

我强烈推荐这一个:

好运!

答案 1 :(得分:3)

假设您必须处理一个非常重要的项目,我认为您的问题有两个方面可以共同考虑设置架构和代码质量:

  • 命名
  • 模块化

对于命名,我尝试在每个命名空间中具有最高的内聚力,并遵循Common Closure PrincipleCommon Reuse Principle

对于模块化,我尝试将一个模块用于项目的每个架构主要问题,并方便地命名其包。

MVC是一种表示模块模式,旨在分离表示模块如何控制流,基于什么模型的数据以及与视图相关的逻辑。

在我的java IDE(例如Eclipse)中,我为每个模块使用一个项目,因此web模块将是一个项目,而桌面模块将是另一个项目。例如,在Web项目中,我有一个共同的前缀,例如:

com.mycompany.app.web

在其中我有一个 .controllers (或动作)后代,一个 .models 后代,依此类推。

com.mycompany.app.web.models
com.mycompany.app.web.actions

如果我使用数据库,我依赖DAO模块,另一个项目。 DAO模块没有演示文稿,因此它没有MVC方法。它持久化Domain对象,因此它可能依赖于Domain模块。在这些模块中,我使用如下的前缀:

com.mycompany.app.domain
com.mycompany.app.dao

我尽量不要将MVC中的模型与应用混淆;他们不是一回事。

另一个常见错误是将控制器业务逻辑混淆;业务逻辑应放置在一个模块中,并在表示模块之间共享,控制器位于表示模块(Web或桌面)的命名空间中。

模型(在MVC中,视图模型)是视图用来向用户显示内容的对象:它可能包含一个,域<的组合或集合/ strong>对象。 控制器使用可用模块(DAO等)构建视图模型,然后将其传递给视图

查看然后只能依赖其模型(只有一个,由控制器明确创建)并仅向控制器询问模型(唯一能够构建模型的模型) )。 查看,尤其是对于网络演示文稿,通​​常采用多种语言编码,因此部分代码可能不在命名约定范围内。

答案 2 :(得分:1)

您是否只关注“分离”模型,视图和控制器,就命名和包而言?这似乎是你要问的全部。

我倾向于如此布置我的包裹:

  • com.company.app.domain - 应用程序的域模型类,只是Java bean(仅限getter和setter,如果有任何逻辑则很少)。这在整个应用程序中用作“模型”,并由我的应用程序的每一层使用。
  • com.company.app.service - 应用程序的服务级别类,包含业务逻辑。
  • com.company.app.web.controllers - 我的webapp的控制器类。其他特定于Web的类放在web
  • 的各种其他子包中
  • com.company.app.dao - 用于访问域模型类的DAO接口 - 即从数据库中检索用户等。

在每个软件包中,软件包有时会按应用程序的区域细分,或根据功能细分为较小的组,无论看起来是什么。

答案 3 :(得分:1)

我认为考虑如何最终利用您在代码库中分解单独模块的事实也很重要。 I.E.除了基本代码质量之外,您还在考虑根据您的打包方案进行开发。

我使用的大多数应用程序都遵循以下打包结构:* .domain,* .service.subservice,* .dao,* .web.controllers。这很好地用于跟踪代码库中的循环依赖性和/或以错误方式流动的依赖性(控制器在没有服务间接的情况下命中dao)。它还提供了一种非常简单的包装结构,它是有用且无负担的。

然而,在查看自动依赖性影响评估时会出现这种情况。我目前使用DependencyFinder和一些自定义代码来比较QA之前的两个jar文件。 DependencyFinder将提取所有已修改的方法及其关联的第一级依赖项。自定义代码必须启动以将修改的方法/类映射到业务函数,并吐出graphviz语法文件,以呈现基于业务功能的变更集,QA的依赖图。我们目前正尝试将该工具的结果用于智能回归测试计划,特别是针对生产缺陷,这些缺陷在没有完整的多周回归测试的情况下转向生产。

您建议的目录结构将使第二种情况更容易。但是,我还发现我的大多数开发团队根本不关心依赖关系,因此自动依赖检查器的实用程序可能会有所不同:)

答案 4 :(得分:1)

以下是使用分层架构设计的示例,其中包含三个层( application,domain,ui ):

在模型 - 视图 - 控制器(MVC)中,模型将位于较低层,例如com.company.myapp.domain。所有其他图层都可以访问模型。然后,视图和控制器将位于com.company.myapp.ui中。这意味着Controller类始终与View位于同一层中。 不要将MVC-Controller与提供应用程序逻辑并驻留在应用程序层中的其他控制器类混淆。例如SalesController中的com.company.myapp.application,它提供处理销售的系统操作。

您现在可以想象SalesController更改模型中的某些数据(更新销售),然后模型会通知MVC控制器更新视图。

注意:所有模型都在domain图层中。所有视图和MVC控制器都在ui层中。业务逻辑控制器位于application层。如果您有许多具有不同关注点的类,您当然可以进一步细分这三个层。

我希望这会有所帮助。

答案 5 :(得分:1)

想想你是如何发展的。你是按照Controller / Model / View开发的吗?或者你是按照模块开发的。您可能在模块上而不是在MVC层上开发。因此,我认为你的答案就在于此。尽量让你的软件包名称与你的系统所代表的模块保持一致(我猜你已经在做了)。无需向您显示包名称中的架构选择。

在您的软件包中显示模块名称和域问题,创建一个可维护且一致的代码库。