软件构造实验三心得体会
设计模式
在本次实验中,首先对上课说得和书本上的一些设计模式有了一个新的理解。主要是委托模式和装饰模式。而最后选择了装饰模式
装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活。
例如,在我们的实验中
IntervalSet是抽象构件,定义一个对象接口,里面有insert,start等等方法,我们可以给这些对象动态地添加职责;ConreteIntervalSet定义一个具体对象,也可以给这个对象添加一些职责。
而Decorator是装饰抽象类,实现接口或抽象方法;DutyIntervalSet是具体装饰对象,起到给IntervalSet添加职责的功能,例如show,addEmployee等等。
RI,AF,safety from the rep exposition
这个主要是上一次实验的内容,但是当时对这些的理解还不深,在这次再来谈一下。
首先,由于是重头开始完成代码,我们需要在开始的时候,就将RI,AF,spec这些定义好,同时在完成的过程中,发现有问题的时候,不断地去完善它,而不应该到了快要结束的时候,再去完成。这样的话,可以少走很多弯路。
其次,考虑safety的问题,我们的变量最好都是private final的immutable的变量,这样可以防止client对我们的变量进行改动。如果要是mutable类型的话,我们需要在构造器,变值器,产生器中加入checkRep检查有没有不符合我们的要求,同时在观察器返回的时候,最好是返回一个拷贝,虽然说会产生额外的性能开销,但是会增强我们程序的安全性。
可复用性
在复用方面,我们采取了多种方式,包括继承和委托等。
注意,复用一定要注意LSP原则(Liskov 替换原则)所有引用积累的地方必须能够透明地使用其子类的对象
-
子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法(CommonIntervalSet中对IntervalSet中抽象方法的完成)
-
子类可以增加自己特有的方法(ProcessINtervalSet中的addProcess 等等)
正则表达式
在这次实验中,我还学到了以前从来没有涉及到的内容——java中的正则表达式。
在形式语言与自动机课上学过正则表达式,但是在Java中更多的是应用。
我们主要是完成集中pattern的设计,让我们要读取的文本与这个pattern匹配,从而通过find和group来获取数据
例如:DutyIntervalSet中三个我们要读取数据的类型和获取开始于结束日期的具体实现
String REGEX1="([A-Za-z]*)\\{([A-Za-z\\s]*),(\\d+)-(\\d+)-(\\d+)}"; String REGEX2="Period\\{(\\d+)-(\\d+)-(\\d+),(\\d+)-(\\d+)-(\\d+)}"; String REGEX3="([A-Za-z]*)\\{(\\d+)-(\\d+)-(\\d+),(\\d+)-(\\d+)-(\\d+)}"; Pattern p2=Pattern.compile(REGEX2); Matcher m2 = p2.matcher(build.toString()); m2.find(); duty=new DutyIntervalSet(Integer.parseInt(m2.group(1)),Integer.parseInt(m2.group(2)), Integer.parseInt(m2.group(3)),Integer.parseInt(m2.group(4)), Integer.parseInt(m2.group(5)),Integer.parseInt(m2.group(6))); duty.setDutyIntervalSet(new CommonIntervalSet<Employee>()); LocalDate beginDate=LocalDate.of(Integer.parseInt(m2.group(1)),Integer.parseInt(m2.group(2)), Integer.parseInt(m2.group(3)));
结束
总而言之,在本次试验中,我进一步加强了对OOP和ADT这两个之前知识的理解,同时对可复用性,正则表达式,设计模式等等新学的知识点有了一个新的认识,通过这次实验,更是学到了如何从头到尾自己构建一个简单项目的能力,我未来的学习和工作打下了一个很好的基础。