设计模式学习(二十七)————解释器模式

解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子

当一个语言需要解释执行,并且你可将该语言的句子表示为一个抽象语法树时,可使用解释器模式

使用音乐解释为汉字的例子:

#ifndef PLAYCONTEXT_H
#define PLAYCONTEXT_H

#include <QString>
#include <QDebug>

class PlayContext   //演奏内容类
{
public:
    QString GetPlayText()
    {
        return _text;
    }
    void SetPlayText(QString text)
    {
        _text = text;
    }
private:
    QString _text;
};

class Expression   //表达式类
{
public:
    void Interpret(PlayContext* context)
    {
        if(context->GetPlayText().length() == 0)
            return;
        else
        {
            QString playKey = context->GetPlayText().section(' ',0,0);
            int playValue = context->GetPlayText().section(' ',1,1).toInt();
            context->SetPlayText(context->GetPlayText().section(' ',2,-1));
//            qDebug()<<context->GetPlayText();
            Excute(playKey,playValue);
        }
    }
    virtual void Excute(QString,int) = 0;
};

class Note final : public Expression   //音符类
{
public:
    void Excute(QString key,int value) override
    {
        Q_UNUSED(value);
        QString note;
        if(key == "C")
            note = '1';
        else if(key == "D")
            note = '2';
        else if(key == "E")
            note = '3';
        else if(key == "F")
            note = '4';
        else if(key == "G")
            note = '5';
        else if(key == "A")
            note = '6';
        else if(key == "B")
            note = '7';

        qDebug()<<note;
    }
};

class Scale final : public Expression   //音阶类
{
public:
    void Excute(QString key,int value) override
    {
        Q_UNUSED(key);
        QString scale;

        switch (value) {
        case 1:
            scale = "低音";
            break;
        case 2:
            scale = "中音";
            break;
        case 3:
            scale = "高音";
            break;
        default:
            break;
        }

        qDebug()<<scale;
    }
};

class Speed final : public Expression  //音速类
{
public:
    void Excute(QString key,int value) override
    {
        Q_UNUSED(key);
        QString speed;

        if(value < 500)
            speed = "快速";
        else if(value >= 1000)
            speed = "慢速";
        else
            speed = "中速";

        qDebug()<<speed;
    }
};

#endif // PLAYCONTEXT_H

有了音符、音阶和音速类,我们就可以在mian函数中把音乐翻译成对应的声音了

#include "playcontext.h"

int main()
{
    PlayContext* context = new PlayContext;
    //音乐————上海滩
    context->SetPlayText("T 500 O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3");
    Expression* expression = nullptr;
    try
    {
        while(context->GetPlayText().length()>0)
        {
            QString str = context->GetPlayText().section(' ',0,0);
            if(str == "O")
                expression = new Scale;
            else if(str == "T")
                expression = new Speed;
            else
                expression = new Note;
            expression->Interpret(context);
        }
    }
    catch(...)
    {}
//        qDebug()<<"解释时遇到问题";

    return 0;
}

由程序可以看出,使用解释器模式,可以很容易地改变和扩张文法,因为该模式使用类来表示文法规则,如例子中的:音符类、音阶类和音速类。同时,解释器模式也容易实现文法,因为定义抽象语法树中各个节点的类的实现大体类似。这些类都易于直接编写。

最后放上源码地址:https://github.com/Dongzhixiao/designMode_qt/tree/master/BossHeart_Interpreter_pattern_27

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值