万物之中, 希望至美.

设计模式:解释器模式

2018.10.28

解释器模式用于为高级用户和领域专家提供一个类编程的框架,但没有暴露出编程语言那样的复杂性。这是通过实现一个DSL来达到目的的。

DSL是一种针对特定领域、表达能力有限的计算机语言。 DSL有两类,分别是内部DSL和外部DSL。内部DSL构建在一种宿主编程语言之上,依赖宿主编程语言,外部DSL则是从头实现,不依赖某种已有的编程语言。解释器模式仅与内部DSL相关。

例如:乐谱是一个非软件DSL的例子。音乐演奏者像一个解释器那样,使用乐谱演奏出音乐。

我们可以使用Pyparsing创建一种DSL来控制大门(PS:使用一个好的解析工具以模式匹配来解释结果更加简单)。示例如下:

from pyparsing import Word, OneOrMore, Optional, Group, Suppress, alphanums

class Gate:
    def __init__(self):
        self.is_open = False

    def __str__(self):
        return 'open' if self.is_open else 'closed'

    def open(self):
        print('opening the gate')
        self.is_open = True

    def close(self):
        print('closing the gate')
        self.is_open = False


def main():
    # 首先定义我们的DSL格式,我们这里最简单的控制语法就是   "open -> gate"
    word = Word(alphanums)
    command = Group(OneOrMore(word))
    token = Suppress("->")
    device = Group(OneOrMore(word))
    argument = Group(OneOrMore(word))
    event = command + token + device + Optional(token + argument)

    gate = Gate()
    cmds = ['open -> gate', 'close -> gate']    # 两个自定义的命令
    open_actions = {'gate': gate.open}
    close_actions = {'gate': gate.close}

    for cmd in cmds:
        print(event.parseString(cmd))    # [['open'], ['gate']]
        cmd, dev = event.parseString(cmd)
        cmd_str, dev_str = ' '.join(cmd), ' '.join(dev)
        print(cmd_str, dev_str)
        if 'open' in cmd_str:
            open_actions[dev_str]()
        elif 'close' in cmd_str:
            close_actions[dev_str]()

if __name__ == "__main__":
    main()

这样就实现了一个简单的大门控制语言,只是功能很弱。

comments powered by Disqus