设计模式学习笔记十六——Interpreter模式

动机:在软件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。将特定领域的问题表达为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。

场景:把中文数字转换成罗马数字,如把九万九千九百九十九转换成99999,并且方便扩展到其它位,如扩展到亿位。


结构
Interpreter模式结构图

代码

ExpandedBlockStart.gif ContractedBlock.gif /**/ /*
InBlock.gif * 上下文
ExpandedBlockEnd.gif
*/

None.gif
namespace  DesignPattern.Interpreter
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public class Context
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private string statement;
InBlock.gif        
private int data;
InBlock.gif
InBlock.gif        
public Context(string statement)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.statement = statement;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public string Statement
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return statement;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                statement 
= value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public int Data
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return data;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                data 
= value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

ExpandedBlockStart.gif ContractedBlock.gif /**/ /*
InBlock.gif * 解释器
ExpandedBlockEnd.gif
*/
None.gif
namespace  DesignPattern.Interpreter
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public abstract class Expression
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
protected Dictionary<stringint> table = new Dictionary<stringint>(9);
InBlock.gif
InBlock.gif        
public Expression()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            table.Add(
""1);
InBlock.gif            table.Add(
""2);
InBlock.gif            table.Add(
""3);
InBlock.gif            table.Add(
""4);
InBlock.gif            table.Add(
""5);
InBlock.gif            table.Add(
""6);
InBlock.gif            table.Add(
""7);
InBlock.gif            table.Add(
""8);
InBlock.gif            table.Add(
""9);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public abstract string GetPostfix();
InBlock.gif
InBlock.gif        
public abstract int Multiplier();
InBlock.gif
InBlock.gif        
public virtual int GetLength()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return this.GetPostfix().Length + 1;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public virtual void Interpreter(Context context)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (context.Statement.Length == 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
foreach (string key in table.Keys)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
int value = table[key];
InBlock.gif                
if (context.Statement.EndsWith(key + GetPostfix()))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    context.Data 
+= value * this.Multiplier();
InBlock.gif                    context.Statement 
= context.Statement.Substring(0, context.Statement.Length - this.GetLength());
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
if (context.Statement.EndsWith(""))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    context.Statement 
= context.Statement.Substring(0, context.Statement.Length - this.GetLength());
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public class GeExpression : Expression
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public override string GetPostfix()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return "";
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public override int Multiplier()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return 1;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public class ShiExpression : Expression
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public override string GetPostfix()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return "";
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public override int Multiplier()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return 10;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public class BaiExpression : Expression
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public override string GetPostfix()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return "";
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public override int Multiplier()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return 100;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public class QianExpression : Expression
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public override string GetPostfix()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return "";
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public override int Multiplier()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return 1000;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public class WanExpression : Expression
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public override string GetPostfix()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return "";
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public override int Multiplier()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return 10000;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public override void Interpreter(Context context)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (context.Statement.Length == 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            IList
<Expression> expressionCollection = new List<Expression>();
InBlock.gif            expressionCollection.Add(
new GeExpression());
InBlock.gif            expressionCollection.Add(
new ShiExpression());
InBlock.gif            expressionCollection.Add(
new BaiExpression());
InBlock.gif            expressionCollection.Add(
new QianExpression());
InBlock.gif
InBlock.gif            
foreach (string key in table.Keys)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
int temp = context.Data;
InBlock.gif                context.Data 
= 0;
InBlock.gif                context.Statement 
= context.Statement.Substring(0, context.Statement.Length - 1);
InBlock.gif
InBlock.gif                
foreach(Expression expression in expressionCollection)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    expression.Interpreter(context);
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                context.Data 
+= temp + this.Multiplier() * context.Data;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

ExpandedBlockStart.gif ContractedBlock.gif /**/ /*
InBlock.gif * 客户程序
ExpandedBlockEnd.gif
*/

None.gif
namespace  DesignPattern.Interpreter
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public class Client
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private string chineseDigit;
InBlock.gif        
private Context context;
InBlock.gif        IList
<Expression> expressionCollection = new List<Expression>();
InBlock.gif
InBlock.gif        
public Client(string chineseDigit)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.chineseDigit = chineseDigit;
InBlock.gif            context 
= new Context(chineseDigit);
InBlock.gif
InBlock.gif            expressionCollection.Add(
new GeExpression());
InBlock.gif            expressionCollection.Add(
new ShiExpression());
InBlock.gif            expressionCollection.Add(
new BaiExpression());
InBlock.gif            expressionCollection.Add(
new QianExpression());
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public string ChineseDigit
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return chineseDigit;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                value 
= chineseDigit;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public int GetRomanDigit()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
foreach (Expression expression in expressionCollection)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                expression.Interpreter(context);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return context.Data;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}


要点
      1、本模式应用场景:只有满足“业务规则频繁变化,且类似的模式不断重复出现,并且容易抽象成语法规则的问题”。
      2、使用本模式来表达文法规则,从而可以使用面向对象技巧来方便地扩展文法。
      3、本模式比较适合简单的文法表示,对于复杂的文法表示,本模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具。

转载于:https://www.cnblogs.com/Charly/archive/2007/07/17/820494.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值