23种设计模式----解释器模式----行为型模式
本文深入解析解释器模式,探讨其核心思想与应用案例。通过一个画线程序的实例,展示如何利用解释器模式应对需求频繁变化的场景,实现代码的灵活调整与高效开发。
文章信息
- 原文链接:https://jiayq.blog.csdn.net/article/details/85330780
- 发布时间:2018-12-28 20:00:38
- 阅读量:571
- 分类:java同时被 2 个专栏收录, 订阅专栏, 设计模式
- 标签:#23种设计模式, #解释器模式, #Java画图, #Java图形界面输入实时获取, #行为型模式
摘要
文章浏览阅读571次。本文深入解析解释器模式,探讨其核心思想与应用案例。通过一个画线程序的实例,展示如何利用解释器模式应对需求频繁变化的场景,实现代码的灵活调整与高效开发。
解释器模式
- 1.什么是解释器模式
- 2.核心思想
- 3.例子
- 3.1 背景
- 3.2 分析
- 3.3 画界面
- 3.4 代码实现
- 3.5 效果
- 3.1 背景
- 4.总结
1.什么是解释器模式
遇到需求经常变化的项目,直接用Java语言实现,然后每更改一次需求,就修改相应的源代码?
这样的做法是非常不明智的。
好一些的程序会把经常变化的部分作为可配置的,这样需要修改哪些部分,只需要修改配置文件即可。
但是如果我们需要修改的这部分不是静态的,或者说无法用静态的语言描述,甚至描述非常的困难时,配置文件的方法就力所不及了。
那么,该怎么办?
牛逼的人会创一套专门用于解决这部分问题的编程语言,这也是为什么有那么多的编程语言的一部分原因。
比如 :
程序员英文不好,那么就有了用中文编程的编程语言–易语言
普通编程语言对于数学,比如矩阵的加减乘除,点乘,叉乘等的支持不好,因为运算规则确定,却没有专门的支持,于是就有了—MATLAB,lingo等等
介绍一个新语言:Groovy语言,这个语言与Java无缝结合。
像我们一般玩家怎么办呢,就是使用封装在基本语言的上层的语言。
这里把一些功能强大,使用非常普遍的编程语言理解为基本语言。
但是遇到某个问题,我们既没有牛逼人物的牛逼能力,又找不到合适的封装语言,那该怎么办呢?
解释器模式。
2.核心思想
对于一些固定的操作进行封装,然后定义一套自己的规则。
然后在规则之上进行开发。
因为是封装,所以在规则之上的工作量远远小于没有封装的工作量(一般情况,除非封装是专门把操作复杂化)
这样每次改动的内容就比较少。
说白了就是自己顶一个语法规则,然后自己玩。。。。。。。
3.例子
3.1 背景
在面板上画线,按照4个方位。
要求:根据输入,实时画线。
3.2 分析
背景很简单,要求更简单。。。。
但是分析不简单:
首先画一条线,画多长?
怎么画?横着,竖着?
画一条?
两条?
画线的人如何交互?按钮?键盘?
实时响应?
错误输入怎么办?画无线长?
。。。。。
3.3 画界面
3.4 代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class Main {
/**
* 根窗口容器
*/
private JFrame jFrame;
/**
* 当前线段的起点x
*/
private int xnow;
/**
* 当前线段的起点y
*/
private int ynow;
/**
* 构造方法
*/
public Main(){
jFrame = new JFrame();
init();
//显示窗体
jFrame.setVisible(true);
}
/**
* 抽取初始化方法
*/
private void init(){
//窗口的标题
jFrame.setTitle("23种设计模式----解释器模式");
//使用绝对布局
jFrame.setLayout(null);
//设置大小
jFrame.setSize(800, 800);
//设置初始居中
jFrame.setLocationRelativeTo(null);
//设置不可最大化,不可拖动大小
jFrame.setResizable(false);
//设置默认关闭方式(有时可能是假关闭)
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//黄色面板
JPanel topPanel = new JPanel();
//设置背景色
topPanel.setBackground(Color.YELLOW);
//设置黄色面板大小
topPanel.setSize(jFrame.getSize().width, jFrame.getSize().height/2);
//设置黄色面板中点为初始点
xnow = jFrame.getSize().width/2;
//设置黄色面板中点为初始点
ynow = jFrame.getSize().height/4;
//绿色面板
JPanel botPanel = new JPanel();
//绿色面板背景
botPanel.setBackground(Color.GREEN);
//设置绿色面板大小
botPanel.setSize(jFrame.getSize().width, jFrame.getSize().height/2);
//设置绿色面板位置(从哪里开始画)
botPanel.setLocation(0, jFrame.getSize().height/2);
//增加文本区控件
botPanel.add(getJTextArea());
//把面板加到窗体中
jFrame.add(topPanel);
jFrame.add(botPanel);
//为窗口增加监听方法
addJFrameCloseListener();
}
private JTextArea getJTextArea(){
JTextArea textArea = new JTextArea();
//设置文本区的大小
textArea.setSize(jFrame.getSize().width, jFrame.getSize().height/2);
//设置文本区自动换行(一行满了换下一行)
textArea.setLineWrap(true);
//设置按字符换行(比如每一个字符或者单词的长短不一,不分割字符或者单词进行换行)
textArea.setWrapStyleWord(true);
//设置文本区域的背景色
textArea.setBackground(Color.GREEN);
//设置文本区域文字的颜色
textArea.setForeground(Color.BLUE);
//设置文本区域文字的字体(大小,风格,字体)
textArea.setFont(getFont());
//为文本区域增加监听
addTextAreaListener(textArea);
return textArea;
}
private Font getFont(){
//创建楷体,实线,23大小的字体
Font font = new Font("楷体", Font.BOLD, 23);
return font;
}
private void addJFrameCloseListener(){
//增加窗体监听
jFrame.addWindowListener(new WindowAdapter() {
//监听关闭事件
@Override
public void windowClosed(WindowEvent e){
//当窗体关闭后,程序进程也结束
System.exit(0);
}
});
}
private void addTextAreaListener(final JTextArea textArea){
//增加文本区的监听
textArea.getDocument().addDocumentListener(new DocumentListener() {
//文本区文本被移除
@Override
public void removeUpdate(DocumentEvent e) {
changedUpdate(e);
}
//文本区文本插入
@Override
public void insertUpdate(DocumentEvent e) {
changedUpdate(e);
}
//文本区文本改变
@Override
public void changedUpdate(DocumentEvent e) {
char c = textArea.getText().charAt(e.getOffset());
System.out.println(c);
draw(c);
}
});
}
private void draw(char c){
//获取画图的对象
Graphics graphics = jFrame.getGraphics();
//转换为专门画2d图的对象
Graphics2D graphics2d = (Graphics2D)graphics;
//设置画图的线的宽度
graphics2d.setStroke(new BasicStroke(5.0f));
//设置画图的线的颜色
graphics2d.setColor(Color.PINK);
//设置画图的字体
graphics2d.setFont(getFont());
//将要画的线段的结束端与开始端相同(点---起点)
int xnext = xnow;
int ynext = ynow;
switch(c){
//东
case 'W':
case 'w':
xnext = xnow + 10;
break;
//南
case 'S':
case 's':
ynext = ynow + 10;
break;
//西
case 'E':
case 'e':
xnext = xnow - 10;
break;
//北
case 'N':
case 'n':
ynext = ynow - 10;
break;
//其他
default:
xnext = xnow;
ynext = ynow;
break;
}
//超出边界的值设置为边界
xnext = xnext > jFrame.getSize().width ? jFrame.getSize().width : xnext;
ynext = ynext > jFrame.getSize().height/2 ? jFrame.getSize().height/2 : ynext;
xnext = xnext < 0 ? 0 : xnext;
ynext = ynext < 0 ? 0 : ynext;
//按照起点和终点画线
graphics2d.drawLine(xnow, ynow, xnext, ynext);
//把本次线段的终点设置为下一次线段的起点
xnow = xnext;
ynow = ynext;
}
public static void main(String[] args) {
new Main();
}
}
3.5 效果
4.总结
看上去挺简单的,但是只要不断的扩充,一定能够实现更复杂的程序。
比如我们的程序能够读取每一个字符,并在控制台回写,那么,所有的文本编辑器,与这个有什么区别呢?
能不能设置一个定时器,定时器里面有相应的画图的代码或者命令,实现动画功能?
能不能实现一些简单的小游戏呢?用解释器模式实现的小游戏,游戏规则是不是可以实时更改呢????




