软件构造笔记--Lab3面向可复用性和可维护性的编程


这次实验的任务量较大,且跟之前两次比起来更为抽象,最主要的是开始做实验之后的两三周才讲到实验中要用到的设计模式,因此需要提前自学,好在网上关于设计模式的讲解还算丰富。但其实我还是似懂非懂

实验内容

本次实验提供了5个应用场景

  1. 航班管理
  2. 高铁管理
  3. 操作系统进程管理
  4. 大学课表管理
  5. 学习日程管理

要求1必做、2和3选一个、4和5选一个。这些应用场景的共同点为都是指定一些计划项,这些计划项都有时间、地点和资源属性,都有等待、已分配资源、启动、取消、结束等状态。而有些应用的时间、地点和资源的特点又有区别,比如航班的地点属性为一个起点+一个终点,资源为单个飞机;而高铁的地点为一个起点+一串中间经停站+一个终点,资源为一列车厢。因此需要分别对这些应用的全局共性操作局部共性操作进行抽象。

关于局部共性操作的处理

实验指导书上给出了6种不同的处理方法,我选择的是第5种,即分别定义每种操作的接口并实现,然后定义应用继承它需要的操作的接口组合,实现可复用性。
刚开始做这部分时我比较没有头绪,不知道怎么写,担心这样写了会不会之后又得改来改去很麻烦。但这样想了一两天没什么进展,干脆就凭感觉写了,事实证明这一部分的任务量不算很多,这也让我认识到面对不知如何下手的时候可能光想不会想出结果,还得真正动手试一试才行奥力给,干就完了!

State设计模式

该实验中每个计划项的状态的功能实现使用状态设计模式,状态的接口定义为

public interface EntryState {
	/**
	 * print state
	 */
	public void showState();
	
	/**
	 * @return state
	 */
	public String getState();

	/**
	 * change state
	 */
	public void changeState(PlanningEntry pe, EntryState newState);
	
}

具体实现(以Allocated状态为例):

public class AllocatedState implements EntryState {

	private static AllocatedState instance = new AllocatedState();
	
	private AllocatedState() {    //构造器定义为私有
	}
	
	public static EntryState getInstance() {
		return instance;    //应用中使用的状态都是同一个对象,减少内存占用
	}

	@Override
	public void showState() {
		System.out.println(getState());
	}

	@Override
	public String getState() {
		return "Allocated";
	}

	@Override
	public void changeState(PlanningEntry pe, EntryState newState) {
		if(newState.getState().equals("Running")||newState.getState().equals("Cancelled")) {
			pe.changeState(newState);
		}else {
			System.out.println("Can't change to "+newState.getState());
		}
		
	}
}

Board功能以及三个应用

我感觉本次实验工作量最大的地方在这里。实验要求要能用GUI显示某个位置的信息板,例如哈尔滨机场的出发和到达航班信息,因此需要了解JAVA gui库的使用,我用WindowBuilder调各种layout简直能急死,后来干脆放弃了,直接弄了个Gridlayout把要展示的都放上去了。(这只是偷懒之举,请勿效仿

另外三个APP的编写感觉也都是一个流程,有很多重复的工作,不过只要写好了一个,另两个在第一个的基础上稍微改动也容易完成。但是如果想做的漂亮一点也有很多地方可以下功夫。

从文件读入数据构建计划项

这一部分用到了正则表达式,我构造的正则表达式如下,分别匹配文件中每个字段的信息,并提取出来用来构造计划项和飞机资源

String regex = "Flight:\\d{4}-\\d{2}-\\d{2},(.*)\n\\{\n"   //1
				+ "DepartureAirport:(.*)\n"  //2
				+ "ArrivalAirport:(.*)\n"  //3
				+ "DepatureTime:(.*)\n"    //4
				+ "ArrivalTime:(.*)\n"    //5
				+ "Plane:(.*)\n\\{\n"    //6
				+ "Type:(.*)\n"        //7
				+ "Seats:(.*)\n"       //8
				+ "Age:(.*)\n\\}\n\\}\n";   //9
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(data);

总结

这几周因为数据库和信息检索实验都ddl,所以软件构造实验就做的比较仓促,很多细节也不是很好,总体来说这次试验主要还是锻炼面向可复用性和可维护性编程的能力,以及实际运用一些课上讲到的设计模式。整体的工作量不小,但不能因为觉得工作量大、无从下手就不干了,提前计划很重要,但动手操作同样重要。