·
解釋器模式在王者榮耀中的應用
·
一、簡述
在王者榮耀手遊中,有局內語音轉文字功能,玩家通過使用普通話在5秒的倒計時內進行簡短而有效的語音輸入,系統會自動將玩家說的話在極短時間內轉換成文字內容,然後點擊發送,玩家的文字聊天信息就發送出去,其他玩家就可以以文字讀取方式瞭解你要傳達的信息了。
在本實例中,我們通過實現局內語音轉文字功能進而說明解釋器模式的應用實例。具體而言,當我們在語音轉文字過程中是需要解釋執行的,這樣我們可以將轉文字中每一個字句表示爲一個類。但是由於漢語結構、規則複雜,過多的字句組合使得我們很難維護所有的類,所以在這裏我們只簡單做5個字的語音轉換來說明解釋器模式的應用實例。
對於這一問題,如果使用程序實現這一效果的話,定義的基本操作是將語音的值轉換爲漢語文字,比如,發音“zhong”就解釋執行爲“中”,發音“le”就解釋執行爲“了”……這樣一來,當玩家通過語音說“zhong lu yi bo le”時,程序就解釋執行輸出“中路一波了”。
二、解釋器模式(Interpreter Pattern)
解釋器模式理解:
高度概括:給定一個語言,定義他的文法的一種表示並定義一個解釋器,這個解釋器使用該表是來解釋語言中的句子。
對於某些問題,我們可能希望用簡單的語言來描述及希望用簡單的語言來實現一些操作,比如使用簡單語言,實現簡單的翻譯操作,解釋模式是關於怎樣實現一個簡單語言的陳述模式,其關鍵是將每一個語法規則表示成一個類。
解釋器模式結構中的四種角色:
①抽象表達式(AbstractExpression):該角色爲一個接口,負責定義抽象的解釋操作;
②終結符表達式(TerminalExpression):實現抽象表達式接口的類,該類將接口中的解釋操作實現爲與文法中的終結符相關聯的操作,即文法中每個終結符號需要一個終結符表達式類;
③非終結符表達式(NonterminalExpression):實現抽象表達式接口的類,文法中的每一條規則都需要非終結符表達式類。非終結符表達式類爲文法中的非終結符號實現解釋操作,該解釋操作通常使用遞歸調用表示對象的解釋操作;
④上下文(Context):包含解釋器之外的一些全局信息。
解釋器模式的UML類圖:
解釋器模式的優缺點:
優點:
①將每一個語法規則表示成一個類,方便實現簡單的語言;
②由於使用肋表示語法規則可以較容易改變或擴展語言的行爲;
③通過在類結構中加入新的方法,可以在解釋的同時增加新的行爲;
缺點:
①如果文法過於複雜,那麼過多的文法規則是我們很難維護所給出的類;
②執行效率較低。
解釋器模式的適用情景:
當有一個簡單的語言需要解釋執行,並且可以將該語言的每一個規則表示爲一個類時,就可以使用解釋器模式。
三、王者榮耀角度下實現解釋器模式結構圖及代碼
eclipse結構圖
主函數【應用(Application)】
Applicayion.java
public class Application{
public static void main(String args[]){
System.out.println("①當玩家使用“普通話”向隊友發送消息時:");
System.out.println(" 【系統提示】正在打開麥克風……");
System.out.println(" 【系統提示】語音錄入中……");
System.out.println(" 【系統提示】正在轉換……");
System.out.print(" 【系統提示】轉換成功:");
String text="Zhong Lu Yi Bo Le";
Context context=new Context(text);
Node node=new OneTwoNode();
node.parse(context);
node.execute();
System.out.println("");
System.out.println("");
System.out.println("★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★");
System.out.println("");
System.out.println("②當玩家使用“方言”向隊友發送消息時:");
System.out.println(" 【系統提示】正在打開麥克風……");
System.out.println(" 【系統提示】語音錄入中……");
System.out.println(" 【系統提示】正在轉換……");
System.out.print(" 【系統提示】轉換成功:");
text="Ji He Jin Gong Zhu Zai";
context=new Context(text);
node=new OneTwoNode();
node.parse(context);
node.execute();
}
}
抽象表達式(AbstractExpression)
Node.java
public interface Node{
public void parse(Context text);
public void execute();
}
終結符表達式(TerminalExpression)
OneNode.java
public class OneNode implements Node{
String [] word={"Zhong","","","",""};
String token;
boolean boo;
public void parse(Context context){
token=context.nextToken();
int i=0;
for(i=0;i<word.length;i++){
if(token.equalsIgnoreCase(word[i])){
boo=true;
break;
}
}
if(i==word.length)
boo=false;
}
public void execute(){
if(boo){
if(token.equalsIgnoreCase(word[0]))
System.out.print("中");
}
}
}
TwoNode.java
public class TwoNode implements Node{
String [] word={"Lu","","","",""};
String token;
boolean boo;
public void parse(Context context){
token=context.nextToken();
int i=0;
for(i=0;i<word.length;i++){
if(token.equalsIgnoreCase(word[i])){
boo=true;
break;
}
}
if(i==word.length)
boo=false;
}
public void execute(){
if(boo){
if(token.equalsIgnoreCase(word[0]))
System.out.print("路");
}
}
}
ThreeNode.java
public class TwoNode implements Node{
String [] word={"Lu","","","",""};
String token;
boolean boo;
public void parse(Context context){
token=context.nextToken();
int i=0;
for(i=0;i<word.length;i++){
if(token.equalsIgnoreCase(word[i])){
boo=true;
break;
}
}
if(i==word.length)
boo=false;
}
public void execute(){
if(boo){
if(token.equalsIgnoreCase(word[0]))
System.out.print("路");
}
}
}
ForeNode.java
public class ForeNode implements Node{
String [] word={"","","","Bo",""};
String token;
boolean boo;
public void parse(Context context){
token=context.nextToken();
int i=0;
for(i=0;i<word.length;i++){
if(token.equalsIgnoreCase(word[i])){
boo=true;
break;
}
}
if(i==word.length)
boo=false;
}
public void execute(){
if(boo){
if(token.equalsIgnoreCase(word[3]))
System.out.print("波");
}
}
}
FiveNode.java
public class FiveNode implements Node{
String [] word={"","","","","Le"};
String token;
boolean boo;
public void parse(Context context){
token=context.nextToken();
int i=0;
for(i=0;i<word.length;i++){
if(token.equalsIgnoreCase(word[i])){
boo=true;
break;
}
}
if(i==word.length)
boo=false;
}
public void execute(){
if(boo){
if(token.equalsIgnoreCase(word[4]))
System.out.print("了");
}
else{
System.out.print("嗚嗚嗚~~~什麼都沒聽清┭┮﹏┭┮");
}
}
}
非終結符表達式(NonterminalExpression)
FirstNode.java
public class FirstNode implements Node{
Node node;
public void parse(Context context){
node =new OneNode();
node.parse(context);
}
public void execute(){
node.execute();
}
}
TwiceNode.java
public class TwiceNode implements Node{
Node node;
public void parse(Context context){
node =new TwoNode();
node.parse(context);
}
public void execute(){
node.execute();
}
}
ThirdNode.java
public class ThirdNode implements Node{
Node node;
public void parse(Context context){
node =new ThreeNode();
node.parse(context);
}
public void execute(){
node.execute();
}
}
ForthNode.java
public class ForthNode implements Node{
Node node;
public void parse(Context context){
node =new ForeNode();
node.parse(context);
}
public void execute(){
node.execute();
}
}
FifthNode.java
public class FifthNode implements Node{
Node node;
public void parse(Context context){
node =new FiveNode();
node.parse(context);
}
public void execute(){
node.execute();
}
}
OneTwoNode.java
public class OneTwoNode implements Node{
Node one,twoThree;
public void parse(Context context){
one =new FirstNode();
twoThree=new TwoThreeNode();
one.parse(context);
twoThree.parse(context);
}
public void execute(){
one.execute();
twoThree.execute();
}
}
TwoThreeNode.java
public class TwoThreeNode implements Node{
Node two,threeFore;
public void parse(Context context){
two =new TwiceNode();
threeFore=new ThreeForeNode();
two.parse(context);
threeFore.parse(context);
}
public void execute(){
two.execute();
threeFore.execute();
}
}
ThreeForeNode.java
public class ThreeForeNode implements Node{
Node three,foreFive;
public void parse(Context context){
three =new ThirdNode();
foreFive=new ForeFiveNode();
three.parse(context);
foreFive.parse(context);
}
public void execute(){
three.execute();
foreFive.execute();
}
}
ForeFiveNode.java
public class ForeFiveNode implements Node{
Node fore,five;
public void parse(Context context){
fore =new ForthNode();
five=new FifthNode();
fore.parse(context);
five.parse(context);
}
public void execute(){
fore.execute();
five.execute();
}
}
上下文(Context)
Context.java
import java.util.StringTokenizer;
public class Context{
StringTokenizer tokenizer;
String token;
public Context(String text){
setContext(text);
}
public void setContext(String text){
tokenizer=new StringTokenizer(text);
}
String nextToken(){
if(tokenizer.hasMoreTokens()){
token=tokenizer.nextToken();
}
else
token="";
return token;
}
}
運行結果截圖
更多設計模式在王者榮耀中的應用請點擊我的→設計模式在王者榮耀中的應用專欄。
歡迎留言,一起學習交流~
感謝閱讀
END