2

是,在一个MVC架构的职责分离Web应用程序的另外一个问题“数据/对象模型” - 我认为这其中有一个细微的差别不过......“过程模型” VS在MVC

我现有的实施看起来像这样:

  • 控制器:非常'薄';除拨打&模型视图,路由&演示逻辑仅
  • 型号:非常'厚';所有业务逻辑
  • 观看次数:非常“稀”;除了内容&标记,代码被限制在环路&数据格式化

另外,项目利用一个ORM作为一个抽象层数据库上述和“连接器”作为包装类的外部服务。

我的问题涉及模型之间责任的分离。大多数情况下,我们的模型模仿我们系统中的'事物' - '用户','产品','订单'等。

我发现这对于提供简单的数据检索请求非常有效 - 控制器实例化合适的型号&调用相关的“吸气剂”。

当启动更复杂的过程如“PlaceOrder”或“RegisterUser”时,会出现此问题。有时候这些过程可以在一个模型中实现,有时候这些过程需要模型之间的沟通或协调来实现。

现在,模型直接在这些情况下相互沟通,而不是由控制器管理的过程。保持模型内的流程看起来是正确的(控制器不需要知道“RegisterUser”的业务规则需要发送确认电子邮件)。

我与这个实施寻找什么是它让我担心有些两个问题:

  1. 模式似乎经常知道太多关于其他模型 - 模型似乎太在此实现紧密耦合。
  2. 模型中的方法有两种常见类型:'getters/setters'和我调用'Process Methods'的方法,管理进程的方法,适当调用模型或其他模型中的其他方法 - 这些由于缺乏更好的描述,方法看起来像'非模型'。

是否适合实施两种模型 - '数据/对象模型'(主要是'getters/setters'和可能简单的'流程方法',它们是内部的和'流程模型' ('数据/对象')模型的协作需要'处理方法'?

在这个实现中,我们有模型表示'用户','产品','订单'以及'注册','订购'等。

想法?

回答

0

Martin Fow在他的“重构”一书中,Ler似乎认为由数据,访问器组成的“数据”模型是另一类重构的好选择。他在代码中的“糟糕的气味”库中称它为“数据类”。

这表明它可能是更好看简化不同进程之间的相互作用,但允许处理被紧密地耦合到它自己的数据

例如PlaceOrder和OrderData可以紧密结合,但PlaceOrder与客户进程之间的交互最少包括AddOrderToCustomerRecord。

1

这个问题的解决方案是在模型的顶部有一个单独的图层,一个薄层。该层有时称为服务层或应用层。这个层不是太多的状态,而是调用各种模型方法和数据访问方法。

例如,您可能有一个管理订单的服务类。

class OrderService { 

placeOrder(Order order) { 
    order.doModelStuff(); 
    orderDao.save(order); 

} 

removeOrder(order){ 
    order.cancel(); 
    orderDao.delete(order); 

... 
} 

class UserService { 

registerUser(User user) { 
    if(userDao.userExists(user)) { 
     throw exception: user exists; 
    } 
    user.doRegistrationStuff(); 
    userDao.save(user); 
} 

在服务层的方法并不局限于操纵单个实体。一般来说,他们可以访问和操作多个模型。例如,

placeOrder(Customer customer, Order order) { 
    customer.placeOrder(order); 
    save customer, if necessary. 
    save order, if necessary 
    customer.sendEmail(); 
    Shipper shipper = new shipper; 
    shipper.ship(order, customer.getAddress()); 
    ... 

} 

该层的想法是,它的方法做一个工作单元(通常对应于一个用例)。实际上这更多是程序性的。您可以从Martin Fowler等人那里了解更多关于这一层的内容。

注:我的观点是显示业务/应用层是什么,不显示实现的顺序,客户等

0

在设计模式方面,分离模型对象为简单对象(与getter和setter )和过程对象(使用过程逻辑)将使您的域模型变为具有事务脚本的贫血域模型。

你不想这样做。模型对象告诉对方做事情(你的过程方法)很好。这种耦合优于使用getter和setter的耦合类型。

对象必须互相交互,所以必须有一定程度的耦合。如果您将这种耦合限制为暴露于外部世界的方法(如果您愿意的话,可以使用对象的API),您可以更改对象的实现而不产生副作用。

一旦你公开实现细节(getter和setter公开对象内部,这是实现特定的),你不能改变没有副作用的实现。这是不好的耦合。有关更详细的解释,请参阅Getters and Setters Are Evil

回到你的过程方法和过度耦合,有办法减少模型对象之间的耦合。请检查Law of Demeter了解什么是合理的以及应该是什么样的红旗。

另请参阅Domain Driven Design了解降低耦合的模式。像聚合根可以减少耦合和复杂性。

tl; dr版本:不分开你的数据和方法,隐藏你的数据,只暴露你的API。