《大話設(shè)計模式》閱讀筆記和總結(jié)。原書是C#編寫的略贮,本人用Java實現(xiàn)了一遍送挑,包括每種設(shè)計模式的UML圖實現(xiàn)和示例代碼實現(xiàn)屯远。
目錄:設(shè)計模式
Github地址:DesignPattern
說明
定義:解釋器模式(interpreter),給定一個語言颤绕,定義它的文法中的一種表示幸海,并定義一個解釋器祟身,這個解釋器使用該表示來解釋語言中的句子。
UML圖:
代碼實現(xiàn):
AbstractExpression(抽象表達式),聲明一個抽象的解釋操作物独,這個接口為抽象語法樹中所有的節(jié)點所共享
abstract class AbstractExpression{
public abstract void Interpret(Context context);
}
TerminalExpression(終結(jié)符表達式)袜硫,實現(xiàn)與文法中的終結(jié)符相關(guān)聯(lián)的解釋操作。實現(xiàn)抽象表表達式中所要求的接口议纯,主要是一個interpret()方法父款。文法中每一個終結(jié)符都有一個具體終結(jié)表達式與之相對應。
class TerminalExpression extends AbstractExpression{
@Override
public void Interpret(Context context) {
System.out.println("終端解釋器");
}
}
NonterminalExpression(非終結(jié)符表達式)瞻凤,為文法中的非終結(jié)符實現(xiàn)解釋器操作憨攒。對文法中每一條規(guī)則R1、R2……Rn都需要一個具體的非終結(jié)符表達式類阀参。通過實現(xiàn)抽象表達式的interpret()方法實現(xiàn)解釋操作肝集。解釋操作以遞歸方式調(diào)用上面所提到的代表R1、R2……Rn中各個符號的實例變量
class NonterminalExpression extends AbstractExpression{
@Override
public void Interpret(Context context) {
System.out.println("非終端解釋器");
}
}
Context蛛壳,包含解釋器之外的一些全局信息
class Context {
private String input;
private String output;
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
public String getOutput() {
return output;
}
public void setOutput(String output) {
this.output = output;
}
}
客戶端代碼
public class InterpreterPattern {
public static void main(String[] args){
Context context = new Context();
List<AbstractExpression> list = new ArrayList<>();
list.add(new TerminalExpression());
list.add(new NonterminalExpression());
list.add(new TerminalExpression());
list.add(new TerminalExpression());
for (AbstractExpression expression : list) {
expression.Interpret(context);
}
}
}
運行結(jié)果
終端解釋器
非終端解釋器
終端解釋器
終端解釋器
示例
例子:音樂解釋器杏瞻。在以前程序演奏音樂的時候有一套規(guī)則,規(guī)定O表示音階衙荐,O 1表示低音捞挥,O 2表示中音,O 3表示高音忧吟,“P ”表示休止符砌函,"C D E F G A B "表示“Do-Re-Mi-Fa-So-La-Ti”,音符長度1表示一拍溜族,2表示2拍讹俊,0.25表示四分之一拍,0.5表示半拍煌抒,所有字母和數(shù)字都要使用半角空格分開仍劈,例如上海灘第一句“浪奔”,可以寫成“O 2 E 0.5 G 0.5 A 3 ”,表示中音開始寡壮,演奏的是mi so la
UML圖:
代碼實現(xiàn):
表達式類(AbstractExpression)
/**
* 表達式類(AbstractExpression)
*/
public abstract class Expression {
public void Interpret(PlayContext context) {
if (context.getText().length() == 0) {
return;
} else {
String playKey = context.getText().substring(0, 1);
context.setText(context.getText().substring(2));
double playValue = Double.valueOf(context.getText().substring(0, 1).trim());
context.setText(context.getText().substring(context.getText().indexOf(" ") + 1));
Excute(playKey, playValue);
}
}
public abstract void Excute(String key, double value);
}
音符類(TerminalExpression)
public class Note extends Expression {
@Override
public void Excute(String key, double value) {
String note = "";
switch (key){
case "C":
note = "1";
break;
case "D":
note = "2";
break;
case "E":
note = "3";
break;
case "F":
note = "4";
break;
case "G":
note = "5";
break;
case "A":
note = "6";
break;
case "B":
note = "7";
break;
}
System.out.print(note+" ");
}
}
音階類(TerminalExpression)
public class Scale extends Expression {
@Override
public void Excute(String key, double value) {
String scale = "";
switch ((int) value){
case 1:
scale = "低音";
break;
case 2:
scale = "中音";
break;
case 3:
scale = "高音";
break;
}
System.out.print(scale+" ");
}
}
音速類(TerminalExpression)
public class Speed extends Expression{
@Override
public void Excute(String key, double value) {
String speed;
if(value<500){
speed="快速";
}else if(value>=1000){
speed="慢速";
}else{
speed="中速";
}
System.out.print(speed+" ");
}
}
演奏內(nèi)容類贩疙,Context
public class PlayContext {
private String text;
public void setText(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
客戶端代碼
public class Main {
public static void main(String[] args){
PlayContext context = new PlayContext();
System.out.println("上海灘");
context.setText("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 = null;
try {
while (context.getText().length() > 0) {
String string = context.getText().substring(0, 1);
switch (string) {
case "O":
expression = new Scale();// 為O時,實例化音階
break;
case "T":
expression = new Speed();
break;
case "C":
case "D":
case "E":
case "F":
case "G":
case "A":
case "B":
case "P":
expression = new Note();// 實例化音符
break;
default:
break;
}
expression.Interpret(context);
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
運行結(jié)果
上海灘
快速 中音 3 5 6 3 5 2 3 5 6 高音 1 中音 6 5 1 3 2