默认情况下,Grails Service
是否可以访问会话对象?正如能够做到的那样:
session.putSomeValueNeededLater
我在问,因为我需要存储一个变量作为一种服务方法的结果,而另一种服务方法(在同一服务中)可能需要稍后,我试图通过服务中的全局变量来避免这样做因为我有一种被认为是糟糕设计的感觉。所以我认为会议可能是一种替代方法。感谢。
编辑:在我的服务中我遇到这种情况:
masterMethod() {
call method1()
call method2()
//Check if either method 1 or 2 set some variable that indicates whether method 3 needs to be called.
if (condition == true) { call method3 } // Is it a good idea to store the condition in the session?
}
method 1() { //if some condition, masterMethod() needs to call method 3. Where to store this? In session? }
method 2() { //if some condition, masterMethod() needs to call method 3. Where to store this? In session? }
method 3() {...}
答案 0 :(得分:3)
如果您想编写出色且可扩展的功能,则必须使用设计模式。 在您的情况下,如果您有一个依赖于某些条件事件或由流程控制的操作列表,则正确的方法是使用Chain of Responsability模式。 我也在grails应用程序中使用它。我会告诉你我的解决方案
第一步是创建一个不是Service的接口,是一个可以存储在Source / groovy中的标准groovy类:
public interface MyMasterHandler {
public void setNext(MyMasterHandler handler)
public void handleRequest(Operation operation)
}
正如您所看到的,我们只有两种方法:setNext,您将用于创建链和handleRequest,您将在其中放置一个单一责任链的逻辑
因此,您将创建一些处理程序,一个用于处理范围,另一个用于共享信息:
对象:
public class Operation {
Boolean callmethod3 = false
}
Mthod1处理程序:
class Method1 implements MyMasterHandler {
private MyMasterHandler next
@Override
void setNext(MyMasterHandler handler) {
next = handler
}
@Override
void handleRequest(Operation operation) throws SomeExceptionIfYouWant {
if (some.condition || operation.some.condition )
{
operation.callmethod3 = true
}
next.handleRequest(operation)
}
}
Mthod2处理程序:
class Method2 implements MyMasterHandler {
private MyMasterHandler next
@Override
void setNext(MyMasterHandler handler) {
next = handler
}
@Override
void handleRequest(Operation operation) throws SomeExceptionIfYouWant {
if (operation.callmethod3 == true )
{
next.handleRequest(operation)
}
}
}
Mthod3处理程序:
class Method1 implements MyMasterHandler {
private MyMasterHandler next
@Override
void setNext(MyMasterHandler handler) {
next = handler
}
@Override
void handleRequest(Operation operation) throws SomeExceptionIfYouWant {
do stuff of method3
}
}
之后在yuou服务/控制器中,你只需要从会话中初始化一个oject类(在这个例子中是Operation),或者你想要的并创建一个链:
class MyController(){
def test(){
Operation op = new Operation(params) //or session, here we use grails marshalling, if you have params.callmethod3 the object will auto initialized
MyMasterHandler one = new Method1()
MyMasterHandler two = new Method2()
MyMasterHandler three = new Method3()
one.setNext(two)
two.setNext(three)
one.handleRequest(op)
}
}
所以好处是业务登录在您的处理程序中被拆分,并且在将来如果您想要添加新链,您必须只创建一个新的处理程序。 如果需要,可以将对象操作存储在控制器的会话中,然后将其传递给服务或创建和启动链。 在链中,如果你想要你可以抛出特定的异常,所以在服务/控制器中你可以处理抛出的异常,并做你想要的那样。
答案 1 :(得分:1)
您可以使用
从Grails应用中的任意位置访问该会话def session = WebUtils.retrieveGrailsWebRequest().session
即使这将在服务中起作用,您也应该只从Web层(控制器,GSP,标记库等)访问会话。但是,对于您上面描述的特定情况,我根本不知道为什么您需要使用会话,您可以这样做吗?
def masterMethod() {
def method1Result = method1()
def method2Result = method2()
method3(method1Result, method2Result)
}
def method3(method1Result, method2Result) {
// decide what to do based on the results of methods 1 and 2
}