如何从对象的构造函数中提取此变量的初始化?

我正在写我的第一个Go程序,一个SMTP服务器,我认为使用FSM来表示网络协议的状态转换会很不错。我真的很喜欢这个haskell SMTP FSM示例,因此在此之后我对其进行了宽松的建模。


我创建了一个简单的FSM类型,该类型将一个过渡表作为其构造函数参数,并具有一个Run方法,该方法接受一个事件,并将在状态表中调用与之匹配的相应处理函数。然后,我有一个“会话”类型,该类型是在处理从其连接传入的SMTP命令之后需要利用FSM的。


以下是FSM过渡的外观:


type Transition struct {

    from    State

    event   Event

    to      State

    handler func() string

}

然后,在我的Session对象中,我被迫在其构造函数中定义转换表,以便可以访问其用于转换动作的方法:


func (s *SmtpSession) NewSession() {

    transitions := []Transition{    

        {Initial, Rset, Initial, sayOk},

        {HaveHelo, Rset, HaveHelo, sayOk},

        {AnyState, Rset, HaveHelo, resetState},


         ...


        {Initial, Data, Initial, needHeloFirst},

        {HaveHelo, Data, HaveHelo, needMailFromFirst},

        {HaveMailFrom, Data, HaveMailFrom, needRcptToFirst},

        {HaveRcptTo, Data, HaveData, startData},

    }

    smtpFsm = StateMachine.NewMachine(transitions)

}

当所有会话实质上具有相同的FSM时,必须在每个会话中创建此FSM的实例,这似乎很浪费。我宁愿只拥有某种“静态” FSM,可以为其提供一个过渡表,然后Run方法将获取当前状态和一个事件,并返回结果“ action”函数。


但是,那是我遇到麻烦的地方。因为所有处理程序函数实际上都是Session对象的方法,所以我必须在Session中定义它。我想不出一种方法,我只能为所有会话定义一次此过渡表,并且仍然可以适当访问我需要的会话处理程序函数。


如果我以直接的程序风格编写该程序,那么我将不会遇到任何这些问题。FSM可以直接访问所有处理程序功能。


我唯一能想到的就是更改我的FSM,使其不返回函数指针,而是返回一些任意常量,然后Session将这些常量映射到适当的函数:


var transitions = []Transition{

    {Initial, Rset, Initial, "sayOk"},

    {HaveHelo, Rset, HaveHelo, "sayOk"},

    {AnyState, Rset, HaveHelo, "resetState"},

    ...

}


var smtpFsm = NewStateMachine(transitions)


func (s *Session) handleInput(cmd string) {

    event := findEvent(cmd)

    handler := findHandler(smtpFsm.Run(s.currentState, event))

    handler(cmd)   

}


func (s *Session) findHandler(handlerKey string) {

    switch handlerKey {

    case "sayOk":

        return sayOk

    case "resetState":

        return resetState

    }

}

这将解决必须为每个会话重新初始化新的FSM的问题,但同时也会感到有些骇人听闻。有人对我如何避免此问题有任何建议吗?这是一个指向不完整的Session.go的链接,该链接演示了此问题。


波斯汪
浏览 179回答 2
2回答

慕村9548890

这整个事情变得这样容易,如果你没有你的处理程序是方法,而而不是把实例作为参数的功能。这大致是同一回事,但是您可以进行某种type State func(Session) State设置,并且可以更轻松地考虑它。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go