返回顶部

一缕半夏微光

温柔半两,从容一生

导航

软件设计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 #include <iostream>
  2 #include <vector>
  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<AbstractNode*> 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++设计模式——解释器模式

posted on 2021-11-21 21:33  一缕半夏微光  阅读(34)  评论(0编辑  收藏  举报