设计模式 十六、Interpreter 解释器(行为模式)

动机(Motivation)

件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。

种情况下,特定的领域的问题表达式为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。

意图(Intent)

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

interpreter 模式的几个要点

    • Interpreter模式的应用场合是interpreter模式应用中的难点,只有满足“业务规则频繁的变化”,且类似的模式不断重复出现,并且容易抽象为语法规则的问题才适合使用interpreter模式。

    • 使用Interpreter模式来表示文法规则,从而可以使用面向对象技巧开方便地“扩展”文法。
    • Interpreter模式比较适合简单的文法表示,对于复杂的文法表示,Interpreter模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具。

类图

Code

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatterns
{
    class Program
    {
        static void Main(string[] args)
        {
            string roman = "三百六十万六千四百五十二";//6452
            Context context = new Context(roman);
            ArrayList tree = new ArrayList();
            tree.Add(new GeExpression());
            tree.Add(new ShiExpression());
            tree.Add(new BaiExpression());
            tree.Add(new QiaExpression());
            tree.Add(new WanExpression());
            foreach (Expresion exp in tree)
            {
                exp.Interpret(context);
            }
            Console.WriteLine("{0}=={1}",roman,context.Data);
            Console.ReadLine();
        }
    }
    public class Context
    {
        private string statement;
        private int data;

        public Context(string statement)
        {
            this.statement = statement;
        }
        public string Statement
        {
            get { return statement; }
            set { statement = value; }
        }

        public int Data
        {
            get { return data; }
            set { data = value; }
        }
    }

    public abstract class Expresion
    {
        protected Dictionary<string, int> table = new Dictionary<string, int>(9);
        public Expresion()
        {
            table.Add("一", 1);
            table.Add("二", 2);
            table.Add("三", 3);
            table.Add("四", 4);
            table.Add("五", 5);
            table.Add("六", 6);
            table.Add("七", 7);
            table.Add("八", 8);
            table.Add("九", 9);
        }
        public virtual void Interpret(Context context)
        {
            if (context.Statement.Length == 0)
            {
                return;
            }
            foreach (string key in table.Keys)
            {
                int value = table[key];
                if (context.Statement.EndsWith(key + GetPostfix()))
                {
                    context.Data += value * this.Multiplier();
                    context.Statement = context.Statement.Substring(0,context.Statement.Length-this.GetLength());
                }
                if (context.Statement.EndsWith("零"))
                {
                    context.Statement = context.Statement.Substring(0,context.Statement.Length-1);
                }
            }

        }
        public abstract string GetPostfix();
        public abstract int Multiplier();
        public virtual int GetLength()
        {
            return this.GetPostfix().Length + 1;
        }

    }

    public class WanExpression : Expresion
    {
        public override string GetPostfix()
        {
            return "万";
        }
        public override int Multiplier()
        {
            return 10000;
        }
        public override int GetLength()
        {
            return 1;
        }
        public override void Interpret(Context context)

        {
            if (context.Statement.Length == 0) return;
            ArrayList tree = new ArrayList();
            tree.Add(new GeExpression());
            tree.Add(new ShiExpression());
            tree.Add(new BaiExpression());
            tree.Add(new QiaExpression());
            foreach(string key in table.Keys)
            {
                if (context.Statement.EndsWith(this.GetPostfix()))
                {
                    int temp = context.Data;
                    context.Data = 0;
                    context.Statement = context.Statement.Substring(0,context.Statement.Length-this.GetLength());
                    foreach (Expresion exp in tree)
                    {
                        exp.Interpret(context);
                    }
                    context.Data = temp + this.Multiplier() * context.Data;
                }
            }
        }
    }
    public class QiaExpression : Expresion
    {
        public override string GetPostfix()
        {
            return "千";
        }
        public override int Multiplier()
        {
            return 1000;
        }
    }
    public class BaiExpression : Expresion
    {
        public override string GetPostfix()
        {
            return "百";
        }
        public override int Multiplier()
        {
            return 100;
        }
    }
    public class ShiExpression : Expresion
    {
        public override string GetPostfix()
        {
            return "十";
        }
        public override int Multiplier()
        {
            return 10;
        }
    }
    public class GeExpression : Expresion
    {
        public override string GetPostfix()
        {
            return "";
        }
        public override int Multiplier()
        {
            return 1;
        }
        public override int GetLength()
        {
            return 1;
        }
    }
}
时间: 2024-10-13 02:05:28

设计模式 十六、Interpreter 解释器(行为模式)的相关文章

设计模式 ( 十六 ): Mediator中介者模式 -- 行为型

1.概述 在面向对象的软件设计与开发过程中,根据“单一职责原则”,我们应该尽量将对象细化,使其只负责或呈现单一的职责,即将行为分布到各个对象中. 对于一个模块或者系统,可能由很多对象构成,而且这些对象之间可能存在相互的引用,在最坏的情况下,每一个对象都知道其他所有的对象,这无疑复杂化了对象之间的联系.虽然将一个系统分割成许多对象通常可以增强可复用性,但是对象间相互连接的激增又会降低其可复用性,大量的相互连接使得一个对象似乎不太可能在没有其他对象的支持下工作,系统表现为一个不可分割的整体,而且对系

设计模式 ( 十九 ):Strategy策略模式 -- 行为型

设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查找.排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法:当然也可以将这些查找算法封装在一个统一的方法中,通过if…else…或者case等条件判断语句来进行选择.这

设计模式 ( 十八 ):State状态模式 -- 行为型

1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ellse语句来做状态判断来进行不同情况的处理.但是对复杂状态的判断就显得“力不从心了”.随着增加新的状态或者修改一个状体(if else(或switch case)语句的增多或者修改)可能会引起很大的修改,而程序的可读性,扩展性也会变得很弱.维护也会很麻烦.那么我就考虑只修改自身状态的模式. 例子1:按钮来控制一个电梯的状态,一个电梯开们,关门,停,

设计模式15:Interpreter 解释器模式(行为型模式)

Interpreter 解释器模式(行为型模式) 动机(Motivation) 在软件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化. 在这种情况下,将特定领域的问题表达为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的. 意图(Intent) 给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器用来解释语言中的句子.——<设计模式>GoF 中文数字转换为阿拉伯数字 public

浅析设计模式(六)——创建型模式之Abstract-Factory(抽象工厂模式)

抽象工厂模式Abstract-Factory 本文的套路: 抽象工厂模式的定义 抽象工厂模式的参与者及其角色 抽象工厂模式的类图 抽象工厂模式的示例 参考 抽象工厂模式的定义 提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类. 前面[浅析设计模式(四)--创建型模式之Simple-Factory(简单工厂方法,非设计模式)]中介绍的简单工厂方法,虽然已经对变化的部分进行了封装,但是这里只由一个对象负责所有的具体类的实例化,因此每次有新增对象类型时,都需要改变工厂的源码进行扩展.

云计算设计模式(十六)——优先级队列模式

优先发送到服务,以便具有较高优先级的请求被接收和高于一个较低优先级的更快速地处理请求.这种模式是在应用程序是有用的,它提供不同的服务级别保证或者针对独立客户. 背景和问题 应用程序可以委托给其他服务的具体任务;例如,为了执行后台处理或与其他应用程序或服务的整合.在云中,消息队列通常用于将任务委派给后台处理.在许多情况下,请求由服务接收的顺序是不重要的.然而,在某些情况下,可能需要优先考虑的具体要求.这些要求必须早于较低优先级的其他可能先前已发送由应用程序进行处理. 解决方案 队列通常是先入先出(

设计模式(十六):建造者模式

一.概述 建造者模式很容易让人想到建房子,不管建刚需房.改善房还是别墅,它们都离不开地基.柱子.层面和墙体这些组成部分,建筑工人就是把这些组成部分一个个建起来,最后连成一体建出一栋栋楼房. 来看看建造者模式的定义,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.建房子的过程都是相似的,但可以建出形形色色的房子. 二.结构类图 三.应用实例 我们用制造自行车为例子讲解建造者模式,自行车由车架.轮胎.脚踏等部件组成,如下图所示.自行车制造公司就是把这些零部件组装起来. 自行

设计模式C#实现(十六)——中介者模式

意图 0 适用性 1 结构 2 实现 3 效果 4 参考 5 意图 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变他们之间的交互. 适用性 一组对象以定义良好但是复杂的方式进行通信.产生的相互依赖关系结构混乱且难以理解. 一个对象引用其他很多对象并且之间 想定制一个分布在多个类中的行为,而又不想生成太多子类. 结构 实现 在未来的智能家居中,家里的各种电器相互关联,假设这样三种电器:闹钟,日历和咖啡壶.现在有这样两个任务: 当按下闹

设计模式(十六)中介者模式(Mediator)-行为型

中介者模式Mediator 中介者模式又称作调停模式. 所谓中介,在我们生活中很是常见,我们买房子可以有中介公司,找兼职也可以有中介公司.以买房子为例.中介者把所有的买房人.卖房人的需求和特点都结合到一起,把适合的房子提供给合适的人. 首先我们要理解中介者模式的定义:用一个中介者对象来封装一系列对象的交互.中介者使得各对象不需要显式地相互引用,从而解耦合,独立改变他们之间的交互. 实现原理图 中介者模式的实现原理图 比较 门面模式PK中介者模式: 1.门面模式是结构型模式,中介者模式是行为型模式