本次实验要求写三个App,航班,列车,课程规划App.乍一看好像是ctrl cv大法永远滴神,不过实验报告书写的很清楚,这个实验要考察的是复用,所谓的ctrl cv是最简单的复用,这次实验要求我们从更高级的角度做ctrl cv
1.CRP
中文名叫做合成复用原则,这里祭出一张经典的图
这个图很好的解释了CRP的原理
这里结合本次实验说一下
首先我们有一个面向客户的接口,PlanningEntry
有一个实现该接口的类CommonPlanningEntry
仅有一个CommonPlanningEntry要实现航班,课程,列车貌似不太行
接下来我们可以考虑这些计划项的特殊性
例如
航班是需要两个地点信息的,而课程就需要一个地点信息即可
那么我们可以设计出两个接口
SingleLocationEntrry MultipleLocationEntry
和其对应的实现类SingleLocationEntryImpl MultipleLocationEntryImpl
这样我们就可以进行接口组合了
如下
public interface CourseLike extends SingleLocationEntry{
}
这时再设计CourseEntry就非常简单了
public class CourseEntry extends CommonPlanningEntry
implements CourseLike{
//delegation
SingleLocationEntryImpl a=new SingleLocationEntryImpl();
}
可以说掌握了CRP思想,不管是多少种App,只要抽取出其特征并进行接口组合,都可以直接通过这种复用去设计,极大的减轻了工作量
而在真正的设计中,要把握好一个原则,多用委派少用继承
因为继承是高度耦合的,所以会导致很严重的连锁反应
像这里使用了委派,那么出问题我就找被委派的接口及其实现就好了
代码的维护性大大增强
2.Strategy Iterator Facade设计模式
为什么把这几种设计模式放在一起,因为他们有一个共同的特点
高聚合
Strategy把同种操作不同实现聚合为一个接口
Facade把不同的API聚合成一个大API
Iterator将迭代器单独抽离出来
这三种模式都是让我们做到分离,聚合
本质上还是CRP或者说是委派的变种,这里依然可以看见委派的强大之处
3.语法驱动(正则表达式)
BNF范式
在双引号中的字 “word” 代表着这些字符本身。而double_quote用来代表双引号;
在双引号外的字(有可能有下划线)代表着语法部分;
尖括号 < > 内包含的为必选项;
方括号 [ ] 内包含的为可选项;
大括号 { } 内包含的为可重复0至无数次的项;
圆括号 ( ) 内包含的所有项为一组,用来控制表达式的优先级;
竖线 | 表示在其左右两边任选一项,相当于"OR"的意思;
::= 是“被定义为”的意思;
… 表示术语符号;
斜体字: 参数,在其它地方有解释;
这里不是形式语言与自动机,所以在此我只想谈谈Java中的正则表达式
Java中的正则表达式还是非常机械的,基本可以按照以下流程
String s=new String("...");
Pattern pattern = Pattern.compile("正则表达式");
Matcher m;
m = pattern.matcher(s);
if (m.matches()) {
String time = m.group(1);
String name = m.group(2);
String depart = m.group(3);
String arrival = m.group(4);
}
4.GUI设计
本次实验主要用到的是Java Swing与Awt
这种GUI设计的模式是自顶向下的,需要对于整个布局有一定的初步规划
对于本次实验,我使用的是GridLayout布局和BorderLayout布局
因为相对而言简洁,明了
BorderLayout如下
GridLayout
这两种未必是最好的布局,不过可以说是对于新手而言最好把握的布局,还是非常推荐使用的
不过总体而言,Awt和Swing在设计GUI上还是比较笨重的,不太适合于开发WinForm程序
在GUI的设计中,我们也可以选择高聚合低耦合的思路
低耦合:
不同的功能区分在不同的JFrame中,不同功能之间互不干扰
高聚合:
类似于facade设计模式,将所有的功能用GridLayout聚合在一起
这样设计出来的GUI在后续操作中是可维护的
缺点就是可能需要的窗口比较多,对用户的直接使用可能不是很方便