每日日报76——软件设计17|解释器模式
(1)JAVA版本
运行效果如下:
工程目录如下:
代码如下:
AbstractNode.java
1 package mode; 2 3 /** 4 * 抽象表达式 5 * 6 * @author Administrator 7 * 8 */ 9 public abstract class AbstractNode { 10 public abstract String interpret(); 11 }
ActionNode.java
1 package mode; 2 3 /** 4 * 动作解释:终结符表达式 5 * 6 * @author Administrator 7 * 8 */ 9 public class ActionNode extends AbstractNode { 10 11 private String action; 12 13 public ActionNode(String action) { 14 this.action = action; 15 } 16 17 @Override 18 public String interpret() { 19 // TODO Auto-generated method stub 20 if (action.equalsIgnoreCase("move")) { 21 return "移动"; 22 } else if (action.equalsIgnoreCase("run")) { 23 return "快速移动"; 24 } else { 25 return "无效指令"; 26 } 27 } 28 }
AndNode.java
1 package mode; 2 3 /** 4 * Annd解释:非终结符 5 * @author Administrator 6 * 7 */ 8 public class AndNode extends AbstractNode { 9 10 private AbstractNode left; 11 private AbstractNode right; 12 13 public AndNode(AbstractNode left,AbstractNode right) { 14 this.left=left; 15 this.right=right; 16 } 17 18 @Override 19 public String interpret() { 20 // TODO Auto-generated method stub 21 return left.interpret()+"再"+right.interpret(); 22 } 23 24 }
Client.java
1 package mode; 2 3 public class Client { 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 String instruction = "down run 10 and up move 20"; 8 InstructionHandler handler = new InstructionHandler(); 9 handler.handle(instruction); 10 11 String outputString; 12 outputString = handler.output(); 13 System.out.println(outputString); 14 } 15 16 }
DirectionNode.java
1 package mode; 2 3 /** 4 * 方向解释:终结符表达式 5 * 6 * @author Administrator 7 * 8 */ 9 public class DirectionNode extends AbstractNode { 10 11 private String direction; 12 13 public DirectionNode(String direction) { 14 this.direction = direction; 15 } 16 17 @Override 18 public String interpret() { 19 // TODO Auto-generated method stub 20 if (direction.equalsIgnoreCase("up")) { 21 return "向上"; 22 } else if (direction.equalsIgnoreCase("down")) { 23 return "向下"; 24 } else if (direction.equalsIgnoreCase("left")) { 25 return "向左"; 26 } else if (direction.equalsIgnoreCase("right")) { 27 return "向右"; 28 } else { 29 return "无效指令"; 30 } 31 } 32 33 }
DistanceNode.java
1 package mode; 2 3 /** 4 * 距离解释:终结符表达式 5 * 6 * @author Administrator 7 * 8 */ 9 public class DistanceNode extends AbstractNode { 10 11 private String distance; 12 13 public DistanceNode(String distance) { 14 this.distance = distance; 15 } 16 17 @Override 18 public String interpret() { 19 // TODO Auto-generated method stub 20 return this.distance; 21 } 22 23 }
InstructionHandler.java
1 package mode; 2 3 import java.util.Stack; 4 5 /** 6 * 指令处理类:工具类 7 * 8 * @author Administrator 9 * 10 */ 11 public class InstructionHandler { 12 private String instruction; 13 private AbstractNode node; 14 15 @SuppressWarnings("unchecked") 16 public void handle(String instruction) { 17 AbstractNode left = null; 18 AbstractNode right = null; 19 AbstractNode direction = null; 20 AbstractNode action = null; 21 AbstractNode distance = null; 22 @SuppressWarnings("rawtypes") 23 Stack stack = new Stack(); 24 String[] words = instruction.split(" ");// 以空格分割字符串 25 for (int i = 0; i < words.length; i++) { 26 /** 27 * 本实例采用栈的方式处理指令,如果遇到and,将其后的3个单词作为3个终结 表达式连成一个简单句子SentenceNode作为and的右表达式,而将从栈顶 28 * 弹出的表达式作为and的左表达式,最后将新的and表达式压入栈中 29 */ 30 if (words[i].equalsIgnoreCase("and")) { 31 left = (AbstractNode) stack.pop(); // 弹出栈顶表达式作为左表达式 32 String word1 = words[++i]; 33 direction = new DirectionNode(word1); 34 String word2 = words[++i]; 35 action = new ActionNode(word2); 36 String word3 = words[++i]; 37 distance = new DistanceNode(word3); 38 39 right = new SentenceNode(direction, action, distance); 40 stack.push(new AndNode(left, right)); // 将新表达式压入栈中 41 } else { 42 String word1 = words[i]; 43 direction = new DirectionNode(word1); 44 String word2 = words[++i]; 45 action = new ActionNode(word2); 46 String word3 = words[++i]; 47 distance = new DistanceNode(word3); 48 left = new SentenceNode(direction, action, distance); 49 stack.push(left); 50 } 51 } 52 this.node = (AbstractNode) stack.pop(); // 将全部表达式从栈中弹出 53 } 54 55 public String output() { 56 return node.interpret(); 57 } 58 59 public String getInstruction() { 60 return instruction; 61 } 62 63 public void setInstruction(String instruction) { 64 this.instruction = instruction; 65 } 66 }
SentenceNode.java
1 package mode; 2 3 /** 4 * 简单句子解释:非终结符表达式 5 * 6 * @author Administrator 7 * 8 */ 9 public class SentenceNode extends AbstractNode { 10 11 private AbstractNode direction; 12 private AbstractNode action; 13 private AbstractNode distance; 14 15 public SentenceNode(AbstractNode direction, AbstractNode action, AbstractNode distance) { 16 this.direction = direction; 17 this.action = action; 18 this.distance = distance; 19 } 20 21 @Override 22 public String interpret() { 23 // TODO Auto-generated method stub 24 return direction.interpret() + action.interpret() + distance.interpret(); 25 } 26 27 }
类图如下:
参考链接:(两个链接不同)
解释器模式
(2)C++版本
运行效果如下:
代码如下:
1 #include2 #include 3 using namespace std; 4 5 #define MAX_SIZE 256 6 #define SAFE_DELETE(p) if (p) { delete p; p = NULL; } 7 8 const wchar_t* const DOWN = L"down"; 9 const wchar_t* const UP = L"up"; 10 const wchar_t* const LEFT = L"left"; 11 const wchar_t* const RIGHT = L"right"; 12 13 const wchar_t* const MOVE = L"move"; 14 const wchar_t* const RUN = L"run"; 15 16 class AbstractNode 17 { 18 public: 19 virtual wchar_t* Interpret() = 0; 20 }; 21 22 class AndNode : public AbstractNode 23 { 24 public: 25 AndNode(AbstractNode* left, AbstractNode* right) : m_pLeft(left), m_pRight(right) {} 26 27 wchar_t* Interpret() 28 { 29 wchar_t* pResult = new wchar_t[MAX_SIZE]; 30 memset(pResult, 0, MAX_SIZE * sizeof(wchar_t)); 31 32 wchar_t* pLeft = m_pLeft->Interpret(); 33 wchar_t* pRight = m_pRight->Interpret(); 34 wcscat_s(pResult, MAX_SIZE, pLeft); 35 wcscat_s(pResult, MAX_SIZE, pRight); 36 37 SAFE_DELETE(pLeft); 38 SAFE_DELETE(m_pRight); 39 40 return pResult; 41 } 42 43 private: 44 AbstractNode* m_pLeft; 45 AbstractNode* m_pRight; 46 }; 47 48 class SentenceNode : public AbstractNode 49 { 50 public: 51 SentenceNode(AbstractNode* direction, AbstractNode* action, AbstractNode* distance) : 52 m_pDirection(direction), m_pAction(action), m_pDistance(distance) {} 53 54 wchar_t* Interpret() 55 { 56 wchar_t* pResult = new wchar_t[MAX_SIZE]; 57 memset(pResult, 0, MAX_SIZE * sizeof(wchar_t)); 58 59 wchar_t* pDirection = m_pDirection->Interpret(); 60 wchar_t* pAction = m_pAction->Interpret(); 61 wchar_t* pDistance = m_pDistance->Interpret(); 62 wcscat_s(pResult, MAX_SIZE, pDirection); 63 wcscat_s(pResult, MAX_SIZE, pAction); 64 wcscat_s(pResult, MAX_SIZE, pDistance); 65 66 SAFE_DELETE(pDirection); 67 SAFE_DELETE(pAction); 68 SAFE_DELETE(pDistance); 69 70 return pResult; 71 } 72 73 private: 74 AbstractNode* m_pDirection; 75 AbstractNode* m_pAction; 76 AbstractNode* m_pDistance; 77 }; 78 79 class DirectionNode : public AbstractNode 80 { 81 public: 82 DirectionNode(wchar_t* direction) : m_pDirection(direction) {} 83 84 wchar_t* Interpret() 85 { 86 wchar_t* pResult = new wchar_t[MAX_SIZE]; 87 memset(pResult, 0, MAX_SIZE * sizeof(wchar_t)); 88 89 if (!_wcsicmp(m_pDirection, DOWN)) 90 { 91 wcscat_s(pResult, MAX_SIZE, L"向下"); 92 } 93 else if (!_wcsicmp(m_pDirection, UP)) 94 { 95 wcscat_s(pResult, MAX_SIZE, L"向上"); 96 } 97 else if (!_wcsicmp(m_pDirection, LEFT)) 98 { 99 wcscat_s(pResult, MAX_SIZE, L"向左"); 100 } 101 else if (!_wcsicmp(m_pDirection, RIGHT)) 102 { 103 wcscat_s(pResult, MAX_SIZE, L"向右"); 104 } 105 else 106 { 107 wcscat_s(pResult, MAX_SIZE, L"无效指令"); 108 } 109 110 SAFE_DELETE(m_pDirection); 111 return pResult; 112 } 113 114 private: 115 wchar_t* m_pDirection; 116 }; 117 118 class ActionNode : public AbstractNode 119 { 120 public: 121 ActionNode(wchar_t* action) : m_pAction(action) {} 122 123 wchar_t* Interpret() 124 { 125 wchar_t* pResult = new wchar_t[MAX_SIZE]; 126 memset(pResult, 0, MAX_SIZE * sizeof(wchar_t)); 127 128 if (!_wcsicmp(m_pAction, MOVE)) 129 { 130 wcscat_s(pResult, MAX_SIZE, L"移动"); 131 } 132 else if (!_wcsicmp(m_pAction, RUN)) 133 { 134 wcscat_s(pResult, MAX_SIZE, L"快速移动"); 135 } 136 else 137 { 138 wcscat_s(pResult, MAX_SIZE, L"无效指令"); 139 } 140 141 SAFE_DELETE(m_pAction); 142 return pResult; 143 } 144 145 private: 146 wchar_t* m_pAction; 147 }; 148 149 class DistanceNode : public AbstractNode 150 { 151 public: 152 DistanceNode(wchar_t* distance) : m_pDistance(distance) {} 153 154 wchar_t* Interpret() 155 { 156 wchar_t* pResult = new wchar_t[MAX_SIZE]; 157 memset(pResult, 0, MAX_SIZE * sizeof(wchar_t)); 158 159 wcscat_s(pResult, MAX_SIZE, m_pDistance); 160 161 SAFE_DELETE(m_pDistance); 162 return pResult; 163 } 164 165 private: 166 wchar_t* m_pDistance; 167 }; 168 169 class InstructionHandler 170 { 171 public: 172 InstructionHandler(wchar_t* instruction) : m_pInstruction(instruction), m_pTree(NULL) {} 173 174 void Handle(); 175 void Output(); 176 177 private: 178 void SplitInstruction(wchar_t**& instruction, int& size); 179 180 wchar_t* m_pInstruction; 181 AbstractNode* m_pTree; 182 }; 183 184 void InstructionHandler::Handle() 185 { 186 AbstractNode* pLeft = NULL; 187 AbstractNode* pRight = NULL; 188 AbstractNode* pDirection = NULL; 189 AbstractNode* pAction = NULL; 190 AbstractNode* pDistance = NULL; 191 192 vector node; // Store the instruction expression 193 194 // Split the instruction by " " 195 wchar_t** InstructionArray = NULL; 196 int size; 197 SplitInstruction(InstructionArray, size); 198 for (int i = 0; i < size; ++i) 199 { 200 if (!_wcsicmp(InstructionArray[i], L"and")) // The instruction is composited by two expressions 201 { 202 wchar_t* pDirectionStr = InstructionArray[++i]; 203 pDirection = new DirectionNode(pDirectionStr); 204 205 wchar_t* pActionStr = InstructionArray[++i]; 206 pAction = new ActionNode(pActionStr); 207 208 wchar_t* pDistanceStr = InstructionArray[++i]; 209 pDistance = new DistanceNode(pDistanceStr); 210 211 pRight = new SentenceNode(pDirection, pAction, pDistance); 212 node.push_back(new AndNode(pLeft, pRight)); 213 } 214 else 215 { 216 wchar_t* pDirectionStr = InstructionArray[i]; 217 pDirection = new DirectionNode(pDirectionStr); 218 219 wchar_t* pActionStr = InstructionArray[++i]; 220 pAction = new ActionNode(pActionStr); 221 222 wchar_t* pDistanceStr = InstructionArray[++i]; 223 pDistance = new DistanceNode(pDistanceStr); 224 225 pLeft = new SentenceNode(pDirection, pAction, pDistance); 226 node.push_back(pLeft); 227 } 228 } 229 230 m_pTree = node[node.size() - 1]; 231 } 232 233 void InstructionHandler::Output() 234 { 235 wchar_t* pResult = m_pTree->Interpret(); 236 237 setlocale(LC_ALL, ""); 238 wprintf_s(L"%s个单位", pResult); 239 240 SAFE_DELETE(pResult); 241 } 242 243 void InstructionHandler::SplitInstruction(wchar_t**& instruction, int& size) 244 { 245 instruction = new wchar_t* [10]; 246 memset(instruction, 0, 10 * sizeof(wchar_t*)); 247 248 for (int i = 0; i < 10; ++i) 249 { 250 instruction[i] = new wchar_t[10]; 251 memset(instruction[i], 0, 10 * sizeof(wchar_t)); 252 } 253 254 size = 0; 255 int n = 0; 256 while (*m_pInstruction != L'\0') 257 { 258 if (*m_pInstruction == L' ') 259 { 260 size++; 261 m_pInstruction++; 262 n = 0; 263 continue; 264 } 265 266 instruction[size][n++] = *m_pInstruction++; 267 } 268 size++; 269 } 270 271 int main() 272 { 273 wchar_t* pInstructionStr =(wchar_t*)L"down run 10 and left move 20"; 274 275 InstructionHandler* pInstructionHandler = new InstructionHandler(pInstructionStr); 276 pInstructionHandler->Handle(); 277 pInstructionHandler->Output(); 278 279 SAFE_DELETE(pInstructionHandler); 280 }
类图如下:
参考链接:
C++设计模式——解释器模式