逛洛阳

2016/10/4 聚会

Posted by WangXiaoDong on October 4, 2016

时间:2016年10月4日 天气:晴:sunny:


Author:冬之晓:angry:
Email: 347916416@qq.com

    今天一早,妈妈就拉我起来去锻炼,回来后,吃了点饭,就和妈妈还有郭凯一起去古墓博物馆。我们首先来到汽车站,然后坐上83路公交车。
    来到了古墓博物馆后,发现古墓博物馆里面真的是很古朴。走入地下,周围都是一个又一个坑道,里面陈列着古代洛阳十三朝的各种古物。
    在这些古文物中畅游,感受洛阳的美好,非常舒适!
    
    下午,和郭凯玩了会游戏,不知不觉就到了晚上。然后我就去新都汇和马宁与姬鸿鹏汇合。晚上我们一起吃了个饭,一起聊了聊未来的打算,
    感觉很好!之后玩了会电玩,没想到洛阳的电玩完全免费……等到10点多的时候,我又去了老城北大街,和腾飞晨辰聚会,
    在老城的酒吧中感受洛阳的魅力,真的想在这美丽的城市中一直生活下去!

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

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

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

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

#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