分享

设计模式16:Interpreter Pattern(解释者模式)

 Java技术馆 2011-10-13

设计模式16:Interpreter Pattern(解释者模式)

分类: 设计模式 177人阅读 评论(0) 收藏 举报

本文翻译自:http://www./Patterns/PatternInterpreter.aspx

Define:Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.

一、解释者模式概念

针对某一编程语言,为其语法定义一定的描述语言和解释器,解释器利用描述语言去解释该编程语言中的所有语法。

二、UML类图

 
UML

三、参与者

该模式的类/对象参与者包括:

  • AbstractExpression  (描述)
    • 为执行operation()声明一个接口
  • TerminalExpression  ( ThousandExpression, HundredExpression, TenExpression, OneExpression )
    • 在语法中使用终止符实现一个operation解释器
    • 在语句中要求所有终止符需要一个实例
  • NonterminalExpression  ( 不使用 )
    • one such class is required for every rule R ::= R1R2...Rn in the grammar
    • maintains instance variables of type AbstractExpression for each of the symbols R1 through Rn.
    • implements an Interpret operation for nonterminal symbols in the grammar. Interpret typically calls itself recursively on the variables representing R1 through Rn.
  • Context  (Context)
    • 所有全局解释器的内容信息
  • Client  (InterpreterApp)
    • builds (or is given) an abstract syntax tree representing a particular sentence in the language that the grammar defines. The abstract syntax tree is assembled from instances of the NonterminalExpression and TerminalExpression classes
    • invokes the Interpret operation

    四、示例代码

    以下结构性的代码描述解释器模式,即利用一个定义好的语法,为进程解析声明提供解释器。

     

    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5. using System.Collections;  
    6.   
    7. namespace Interpreter_Pattern  
    8. {  
    9.     /// <summary>  
    10.   
    11.     /// MainApp startup class for Structural   
    12.   
    13.     /// Interpreter Design Pattern.  
    14.   
    15.     /// </summary>  
    16.   
    17.     class MainApp  
    18.     {  
    19.   
    20.         /// <summary>  
    21.   
    22.         /// Entry point into console application.  
    23.   
    24.         /// </summary>  
    25.   
    26.         static void Main()  
    27.         {  
    28.   
    29.             Context context = new Context();  
    30.   
    31.             // Usually a tree   
    32.   
    33.             ArrayList list = new ArrayList();  
    34.   
    35.   
    36.             // Populate 'abstract syntax tree'   
    37.   
    38.             list.Add(new TerminalExpression());  
    39.   
    40.             list.Add(new NonterminalExpression());  
    41.   
    42.             list.Add(new TerminalExpression());  
    43.   
    44.             list.Add(new TerminalExpression());  
    45.   
    46.   
    47.   
    48.             // Interpret  
    49.   
    50.             foreach (AbstractExpression exp in list)  
    51.             {  
    52.   
    53.                 exp.Interpret(context);  
    54.   
    55.             }  
    56.   
    57.   
    58.   
    59.             // Wait for user  
    60.   
    61.             Console.ReadKey();  
    62.   
    63.         }  
    64.   
    65.     }  
    66.   
    67.   
    68.   
    69.     /// <summary>  
    70.   
    71.     /// The 'Context' class  
    72.   
    73.     /// </summary>  
    74.   
    75.     class Context  
    76.     {  
    77.   
    78.     }  
    79.   
    80.   
    81.   
    82.     /// <summary>  
    83.   
    84.     /// The 'AbstractExpression' abstract class  
    85.   
    86.     /// </summary>  
    87.   
    88.     abstract class AbstractExpression  
    89.     {  
    90.   
    91.         public abstract void Interpret(Context context);  
    92.   
    93.     }  
    94.   
    95.   
    96.   
    97.     /// <summary>  
    98.   
    99.     /// The 'TerminalExpression' class  
    100.   
    101.     /// </summary>  
    102.   
    103.     class TerminalExpression : AbstractExpression  
    104.     {  
    105.   
    106.         public override void Interpret(Context context)  
    107.         {  
    108.   
    109.             Console.WriteLine("Called Terminal.Interpret()");  
    110.   
    111.         }  
    112.   
    113.     }  
    114.   
    115.   
    116.   
    117.     /// <summary>  
    118.   
    119.     /// The 'NonterminalExpression' class  
    120.   
    121.     /// </summary>  
    122.   
    123.     class NonterminalExpression : AbstractExpression  
    124.     {  
    125.   
    126.         public override void Interpret(Context context)  
    127.         {  
    128.   
    129.             Console.WriteLine("Called Nonterminal.Interpret()");  
    130.   
    131.         }  
    132.   
    133.     }  
    134. }  

    另外一个实例即利用解释器模式来实现如何将罗马数字跟十进制的转换,代码如下:

    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5. using System.Collections;  
    6.   
    7. namespace Interpreter_Pattern  
    8. {  
    9.     class MainApp  
    10.     {  
    11.   
    12.         /// <summary>  
    13.   
    14.         /// Entry point into console application.  
    15.   
    16.         /// </summary>  
    17.   
    18.         static void Main()  
    19.         {  
    20.   
    21.             string roman = "MCMXXVIII";  
    22.   
    23.             Context context = new Context(roman);  
    24.   
    25.   
    26.   
    27.             // Build the 'parse tree'  
    28.   
    29.             List<Expression> tree = new List<Expression>();  
    30.   
    31.             tree.Add(new ThousandExpression());  
    32.   
    33.             tree.Add(new HundredExpression());  
    34.   
    35.             tree.Add(new TenExpression());  
    36.   
    37.             tree.Add(new OneExpression());  
    38.   
    39.   
    40.   
    41.             // Interpret  
    42.   
    43.             foreach (Expression exp in tree)  
    44.             {  
    45.   
    46.                 exp.Interpret(context);  
    47.   
    48.             }  
    49.   
    50.   
    51.   
    52.             Console.WriteLine("{0} = {1}",  
    53.   
    54.               roman, context.Output);  
    55.   
    56.   
    57.   
    58.             // Wait for user  
    59.   
    60.             Console.ReadKey();  
    61.   
    62.         }  
    63.   
    64.     }  
    65.   
    66.   
    67.   
    68.     /// <summary>  
    69.   
    70.     /// The 'Context' class  
    71.   
    72.     /// </summary>  
    73.   
    74.     class Context  
    75.     {  
    76.   
    77.         private string _input;  
    78.   
    79.         private int _output;  
    80.   
    81.   
    82.   
    83.         // Constructor  
    84.   
    85.         public Context(string input)  
    86.         {  
    87.   
    88.             this._input = input;  
    89.   
    90.         }  
    91.   
    92.   
    93.   
    94.         // Gets or sets input  
    95.   
    96.         public string Input  
    97.         {  
    98.   
    99.             get { return _input; }  
    100.   
    101.             set { _input = value; }  
    102.   
    103.         }  
    104.   
    105.   
    106.   
    107.         // Gets or sets output  
    108.   
    109.         public int Output  
    110.         {  
    111.   
    112.             get { return _output; }  
    113.   
    114.             set { _output = value; }  
    115.   
    116.         }  
    117.   
    118.     }  
    119.   
    120.   
    121.   
    122.     /// <summary>  
    123.   
    124.     /// The 'AbstractExpression' class  
    125.   
    126.     /// </summary>  
    127.   
    128.     abstract class Expression  
    129.     {  
    130.   
    131.         public void Interpret(Context context)  
    132.         {  
    133.   
    134.             if (context.Input.Length == 0)  
    135.   
    136.                 return;  
    137.   
    138.   
    139.   
    140.             if (context.Input.StartsWith(Nine()))  
    141.             {  
    142.   
    143.                 context.Output += (9 * Multiplier());  
    144.   
    145.                 context.Input = context.Input.Substring(2);  
    146.   
    147.             }  
    148.   
    149.             else if (context.Input.StartsWith(Four()))  
    150.             {  
    151.   
    152.                 context.Output += (4 * Multiplier());  
    153.   
    154.                 context.Input = context.Input.Substring(2);  
    155.   
    156.             }  
    157.   
    158.             else if (context.Input.StartsWith(Five()))  
    159.             {  
    160.   
    161.                 context.Output += (5 * Multiplier());  
    162.   
    163.                 context.Input = context.Input.Substring(1);  
    164.   
    165.             }  
    166.   
    167.   
    168.   
    169.             while (context.Input.StartsWith(One()))  
    170.             {  
    171.   
    172.                 context.Output += (1 * Multiplier());  
    173.   
    174.                 context.Input = context.Input.Substring(1);  
    175.   
    176.             }  
    177.   
    178.         }  
    179.   
    180.   
    181.   
    182.         public abstract string One();  
    183.   
    184.         public abstract string Four();  
    185.   
    186.         public abstract string Five();  
    187.   
    188.         public abstract string Nine();  
    189.   
    190.         public abstract int Multiplier();  
    191.   
    192.     }  
    193.   
    194.   
    195.   
    196.     /// <summary>  
    197.   
    198.     /// A 'TerminalExpression' class  
    199.   
    200.     /// <remarks>  
    201.   
    202.     /// Thousand checks for the Roman Numeral M   
    203.   
    204.     /// </remarks>  
    205.   
    206.     /// </summary>  
    207.   
    208.     class ThousandExpression : Expression  
    209.     {  
    210.   
    211.         public override string One() { return "M"; }  
    212.   
    213.         public override string Four() { return " "; }  
    214.   
    215.         public override string Five() { return " "; }  
    216.   
    217.         public override string Nine() { return " "; }  
    218.   
    219.         public override int Multiplier() { return 1000; }  
    220.   
    221.     }  
    222.   
    223.   
    224.   
    225.     /// <summary>  
    226.   
    227.     /// A 'TerminalExpression' class  
    228.   
    229.     /// <remarks>  
    230.   
    231.     /// Hundred checks C, CD, D or CM  
    232.   
    233.     /// </remarks>  
    234.   
    235.     /// </summary>  
    236.   
    237.     class HundredExpression : Expression  
    238.     {  
    239.   
    240.         public override string One() { return "C"; }  
    241.   
    242.         public override string Four() { return "CD"; }  
    243.   
    244.         public override string Five() { return "D"; }  
    245.   
    246.         public override string Nine() { return "CM"; }  
    247.   
    248.         public override int Multiplier() { return 100; }  
    249.   
    250.     }  
    251.   
    252.   
    253.   
    254.     /// <summary>  
    255.   
    256.     /// A 'TerminalExpression' class  
    257.   
    258.     /// <remarks>  
    259.   
    260.     /// Ten checks for X, XL, L and XC  
    261.   
    262.     /// </remarks>  
    263.   
    264.     /// </summary>  
    265.   
    266.     class TenExpression : Expression  
    267.     {  
    268.   
    269.         public override string One() { return "X"; }  
    270.   
    271.         public override string Four() { return "XL"; }  
    272.   
    273.         public override string Five() { return "L"; }  
    274.   
    275.         public override string Nine() { return "XC"; }  
    276.   
    277.         public override int Multiplier() { return 10; }  
    278.   
    279.     }  
    280.   
    281.   
    282.   
    283.     /// <summary>  
    284.   
    285.     /// A 'TerminalExpression' class  
    286.   
    287.     /// <remarks>  
    288.   
    289.     /// One checks for I, II, III, IV, V, VI, VI, VII, VIII, IX  
    290.   
    291.     /// </remarks>  
    292.   
    293.     /// </summary>  
    294.   
    295.     class OneExpression : Expression  
    296.     {  
    297.   
    298.         public override string One() { return "I"; }  
    299.   
    300.         public override string Four() { return "IV"; }  
    301.   
    302.         public override string Five() { return "V"; }  
    303.   
    304.         public override string Nine() { return "IX"; }  
    305.   
    306.         public override int Multiplier() { return 1; }  
    307.   
    308.     }  
    309. }  

      本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
      转藏 分享 献花(0

      0条评论

      发表

      请遵守用户 评论公约

      类似文章 更多