服务层方法应该期望实例还是id?

And*_*nti 7 grails design-patterns web-applications code-design service-layer

这个问题源自我在Grails应用程序上的工作,但它适用于几乎所有在层中开发的Web应用程序.这是一个简单的例子:

class OrderService {

    // Option 1
    def shipOrder(Order order) {
        order.status = OrderStatus.SHIPPED
        emailService.sendShipmentEmail(order)
        // ...
    }

    // Option 2
    def shipOrder(long orderId) {
        def order = Order.get(orderId)
        order.status = OrderStatus.SHIPPED
        emailService.sendShipmentEmail(order)
        // ...
    }

}
Run Code Online (Sandbox Code Playgroud)

这些选项中的任何一个都记录为比另一个更好吗?

Bur*_*ith 9

我倾向于选择IDS,因为你有时要使用悲观锁,然后很容易改变Order.get(orderId)Order.lock(orderId).锁定必须在事务中发生,因此使用您在读取后锁定的第一种方法,在中间运行较小的更新风险.

有时需要在服务之外加载实例,例如测试控制器中是否存在,因此第二种方法可能会感觉它浪费了数据库调用.但是你可以改变get()对一个exists()调用的调用,只检查是否存在id,而不是加载整个实例只是为了看它是否存在.

请注意,您应该long orderId在方法签名中使用,因为允许null id没有意义.