【问题标题】:Stateful vs Stateless Service Grails有状态与无状态服务 Grails
【发布时间】:2014-07-04 10:36:44
【问题描述】:

我目前正在将业务逻辑从控制器方法转移到服务,当时我掉进了 grails 服务的兔子洞。我的服务中有以下方法:

Job closeJobOpportunity(Job op, Employee res) {
    op.chosenOne = res
    op.requisitionCanceledDate = new Date() 
    if(!op.chosenOne || !op.hrEffectiveDate){
        return null
    }
    else if(StringUtils.isEmpty(op.chosenOne.id)){
        return null
    }
    return op
}

我开始考虑这种方法可能导致同步问题的不同方式(因为 grails 使服务成为单例),并注意到 grails 文档提到只要您不使用,就应该将业务逻辑放入服务中'不存储状态

冒着听起来无知或不了解情况的风险,有人可以简单地提供 Grails 中的有状态服务和无状态服务之间的区别吗?上述方法是有状态的吗?然后它应该被控制器中的 try catch 包围吗?

【问题讨论】:

    标签: grails service groovy


    【解决方案1】:

    Grails 服务(或任何其他类的实例)中的有状态和无状态之间的区别取决于实例本身是否持有任何状态。

    首先,很难说您的示例中的服务是否是无状态的,但是您在该特定方法中的交互并不表明您正在对服务本身进行任何有状态的操作。这会让我相信服务将是无状态的。

    让我举一个有状态服务的例子,并解释为什么它是有状态的。

    class MyStatefulService {
      Long someNumber
      String someString
    
      void doSomething(Long addMe) {
        someNumber += addMe
      }
    
      void updateSomething(String newValue) {
        someString = newValue
      }
    }
    

    如您所见,上述服务有两个属性。如果此服务是作为单例创建的,那么对它的所有调用都将使用相同的单个实例。如您所见,服务上的两种方法会影响服务的属性或状态。这意味着,在当前的形式中,您不能确定在特定线程正在执行服务的一个或多个方法时状态不会改变。使其不可靠,以目前的形式。虽然这是一个非常简单的示例,但它确实演示了使服务有状态的原因。

    服务具有属性是可以的,而且通常情况下也是如此。它们可以是对其他服务甚至配置值的引用。关键概念是确保它们不会改变状态(这总是有例外,但它们是边缘情况)。

    完全可以将服务重写为有状态、同步等,以避免多线程访问和修改状态的陷阱,但这不是你应该做的事情。无状态服务更简单、更干净、更容易测试、更容易调试和更轻量级。

    简而言之,让您的服务无状态,免去您的烦恼。

    【讨论】:

      【解决方案2】:

      我同意上述具体详细说明有状态服务与无状态服务的答案。我也同意将业务逻辑移出控制器层并避免“胖控制器”反模式的过程。然而,要回答一个稍微不同的、可能是隐含的问题,我没有必要跳到把所有东西都塞进服务层。

      这确实取决于您的应用程序的复杂性。短期来看,服务层的业务逻辑很有吸引力,但我觉得从长期来看,它会导致程序化思维和难以扩展或重用的代码。如果您正在考虑实际的业务逻辑应该放在哪里,我建议您花 30 分钟观看本次演讲。

      https://skillsmatter.com/skillscasts/4037-all-hail-the-command-object-are-stateless-services-the-only-way

      【讨论】:

        猜你喜欢
        • 2020-02-29
        • 2011-02-05
        • 2011-07-16
        • 2018-11-10
        • 1970-01-01
        • 1970-01-01
        • 2021-04-27
        • 1970-01-01
        相关资源
        最近更新 更多