2021年春-OO-第四单元总结

针对本单元作业以及整个学期的课程内容,撰写技术博客与课程总结:

  1. 总结本单元作业的架构设计
  2. 总结自己在四个单元中架构设计及OO方法理解的演进
  3. 总结自己在四个单元中测试理解与实践的演进
  4. 总结自己的课程收获
  5. 立足于自己的体会给课程提三个具体改进建议

2021年春_OO_第四单元总结

架构设计

三次作业的架构基本相同的,并且在三次作业中基本是递增的。大致思路相同,我仅说明一下第三次作业的。

MyUmlGeneralInteraction类

  • 首先在MainClass中调用MyUmlGeneralInteraction这个类。这个类是主要的交互类,内置了读取UML信息,解析UML信息,然后对类图、顺序图、状态图这三种图进行相关查询操作以及Check8种错误。

对于读取和解析UML信息

  • 我构建了MyUmlFactory工厂类,根据读取到的UmlElement的ElementType信息,调用工厂类的相关函数,减小了类的耦合。
for (UmlElement temp : elements) {
    if (temp.getElementType() == ElementType.UML_CLASS) {
        factory.umlClass((UmlClass) temp); 
    }
    if (temp.getElementType() == ElementType.UML_INTERFACE) {
        factory.umlInterface(temp); 
    }
    if (temp.getElementType() == ElementType.UML_INTERACTION) {
        factory.umlInteraction(temp); 
    }
    if (temp.getElementType() == ElementType.UML_STATE_MACHINE) {
        factory.umlStateMachine(temp); 
    }
    if (temp.getElementType() == ElementType.UML_REGION) {
        factory.umlRegion(temp);
    }
}

对于UmlClass的存储等原子的存储

  • 我使用了三个HashMap,分别对应从id索引,从name索引,最后根据name索引重名个数,以便后边进行throws Exception。虽然事实证明我的方法是不准确,我构建idToClass的目的是保证记录所有读取的类,但是万万没有想到,测试数据竟然有读取相同id的Class的情况,令我直接在check时崩溃了。应该使用ArrayList来保存所有读取的类。
//Class
private Map<String, MyUmlClass> idToClass = new HashMap<>();
private Map<String, MyUmlClass> nameToClass = new HashMap<>();
private Map<String, Integer> nameToNumber = new HashMap<>();

//Interface
private Map<String, MyUmlInterface> idToInterface = new HashMap<>();
private Map<String, MyUmlInterface> nameToInterface = new HashMap<>();

//Operation
private Map<String, MyUmlOperation> idToOperation = new HashMap<>();
//AssociationEnd
private Map<String, MyUmlAssociationEnd> idToAssociationEnd = new HashMap<>();

//Interaction
private Map<String, MyUmlInteraction> idToInteraction = new HashMap<>();
private Map<String, MyUmlInteraction> nameToInteraction = new HashMap<>();
private Map<String, Integer> interactionNum = new HashMap<>();

//StateMachine
private Map<String, MyUmlStateMachine> idToStateMachine = new HashMap<>();
private Map<String, MyUmlStateMachine> nameToStateMachine = new HashMap<>();
private Map<String, Integer> stateMachineNum = new HashMap<>();

//Region
private Map<String, MyUmlRegion> idToRegion = new HashMap<>();
//Transition
private Map<String, MyUmlTransition> idToTransition = new HashMap<>();
//Lifeline
private Map<String, MyUmlLifeline> idToLifeline = new HashMap<>();
//Attribute
private Map<String, MyUmlAttribute> idToAttribute = new HashMap<>();
//Initial State
private Map<String, MyUmlPseudostate> idToPseudostate = new HashMap<>();

对于三种UML图的检测

  • 由于代码的递增关系,第一次作业检测了类图,没有封装,直接在MyUmlGeneralInteraction里书写代码,比较冗余。在后来的顺序图和状态图,我新构建了MyUmlCollaborationInteraction和MyUmlStateChartInteraction两个类,将相关存放的数据传入,然后调用里面的函数进行判断。
//MyUmlGeneralInteraction:
public int getSentMessageCount(String interactionName, String lifelineName, MessageSort sort) throws InteractionNotFoundException, InteractionDuplicatedException, LifelineNotFoundException, LifelineDuplicatedException {
    return myUmlCollaborationInteraction.getSentMessageCount(interactionName, lifelineName, sort);
}

//MyUmlCollaborationInteraction:
public int getSentMessageCount(String interactionName, String lifelineName, MessageSort sort)
    throws InteractionNotFoundException, InteractionDuplicatedException,
LifelineNotFoundException, LifelineDuplicatedException {
    checkInteraction(interactionName);
    MyUmlInteraction interaction = nameToInteraction.get(interactionName);
    interaction.checkLifeline(lifelineName);
    return interaction.getSendMessageNum(lifelineName, sort);
}

关于checkForUml00x()

  • 对于一些需要递归进行的check,我取巧的方法是,使用tryCatch, 不论递归多深,只要发现多继承或者循环继承,直接抛出Exception,在顶层的Method就可以Catch到这个Exception,然后将结果存入Classes,最后判断一下是否为空,不空,就抛出对应的UmlRule00xException。
public void checkForUml003() throws UmlRule003Exception {
    Set<UmlClassOrInterface> classes = new HashSet<>();
    for (MyUmlInterface myUmlInterface : idToInterface.values()) {
        try {
            myUmlInterface.check003(new ArrayList<>());
        } catch (Exception e) {
            classes.add(idToClassOrInterface.get(myUmlInterface.getId()));
        }
    }
    if (!classes.isEmpty()) {
        throw new UmlRule003Exception(classes);
    }
}

//check003():
public ArrayList<String> check003(ArrayList<String> ans) throws Exception {
    ArrayList<String> temp = ans;
    if (!parents.isEmpty()) {
        for (MyUmlInterface myUmlInterface : parents) {
            if (ans.contains(myUmlInterface.getId())) {
                throw new Exception();
            } else {
                ans.add(myUmlInterface.getId());
            }
        }
        for (MyUmlInterface myUmlInterface : parents) {
            temp = myUmlInterface.check003(temp);
        }
    }
    return temp;
}

四个单元中架构设计及OO方法理解的演进

第一单元

在第一单元,我没有形成较好的架构,前几次作业,我仅仅建立了MainClass和Expression,以及项Item三个类,类之间的耦合度较高,没有较好的理解OO的思想。现在再看,我直接在MainClass类里完成了大部分操作,面向过程地完成了大部分内容。完全没有类的继承,对类的封装、多态性没有较好的理解。Bug修复也十分难受。

第二单元

第二单元是多线程,多线程,我是参考了实验的代码,采用生产消费者模式,并且引入了生产者模式。通过这一单元的学习,对OO思想初步理解,对类的封装更好了,更多地采用调用不同对象的方法,而不是直接一步完成。

第三单元

第三次是作业是按照要求书写的代码,从老师给的代码中也学到了好多。

第四单元

最后几次作业,是我认为我对OO思想理解最好的几次。我对类图、顺序图、状态图,分别构建了不同的处理Interaction类,封装了对UML图的交互过程,并且使用了工厂模式,使用factory类创建UML图的各种元素。然后我还应用了类的继承,将InitialState、FinalState继承自State,几乎所有的元素,都继承自UMLElement类,这个类里面有id、fatherid和name等具有共性的内容。

四个单元中测试理解与实践的演进

四个单元中关于测试我主要学习到了两种方法,第一是构造测试集并写自己的测评程序,第二种是junit单元测试。在整个学期中我都是以第一种方法为主,从第三单元开始我接触到了junit,但是用的不是很多。

还有一个是在第三次作业中,我出现了CPU运行时间过长的情况,使用Jprofiler来定位某个函数运行时间过长,可以方便我进行调试,这是一个非常好的东西。

image-20210601202429922

课程收获

关乎课程收获,我认为收获很多,也有些不足。

对于Java的学习,上学期的Java课程惨不忍睹,老师讲解的没有任何实践性质,几乎学不到任何东西。这学期的Pre直接让我对Java和OO的一些知识有了初步了解,并且对类的组织构建有了明确的认识。

在表达式求导时,我接触到了regex,也开始明白工程中,需要对类进行不断分解到每一小项的必要性,任何事情,都需要先理解给的要求,然后先宏观地弄出一个大的架构,再开始书写代码,而不是直接开始写。要有宏观意识。

后来学习了多线程,知道了多个线程之间进行互斥和同步的一些知识。然后JML让我对工程规范有了进一步了解,但我始终认为其比较冗余,可以简化一下。

最后是UML,类图、顺序图、状态图,我头一次接触这样的UML规范,对各种关系都了解甚微。

在本课程中,我也锻炼了许多能力,比如拖延症。但是我也不太喜欢这样的高压式生活,写代码思考的同时,也忍受着宿舍内不同专业的舍友连麦打游戏的声音。也幸好我结识了一些好友,让我在困难时,帮助我完成任务,没有放弃。

不过,引用一句话,确实,不论遇到什么,都要抽象出有用的、整体的东西,这才是个人需要的能力,不论在何时。

抽象,才是程序员最锋利的武器。

三个具体改进建议

  1. 改进互测环节,简化互测程序,使得互测更加简明,透明化。可以减少互测的扣分值,更希望将互测环节更改为互相借鉴的环节,将互相内斗更改为互相学习,因为我的代码能力非常弱,在互测时完全没有任何优势,仅仅阅读了一些同学的代码,所以我认为对大部分同学来说,互相学习比互相斗争更好,特别是在这个畸形、可怕的社会。
  2. 改进课上环节,课上,老师始终从理论层面去告诉我们怎么做,但是却没有真正的实践,导致自己写代码时,还是按照自己固有的思想来写,完全就是摸不着头脑,并且测试的方式又有些奇怪。我希望老师能亲身实践一下,而不是过多的口头说教。
  3. 更改的作业的部分内容。有时,作业的描述总是那么的不令人愉快,和猜谜语一样猜测测试数据的可能形式,导致同学怨声载道,其实,我更希望可以精简一下作业,将无用的东西进行删除,仅在每次作业增加新的内容,并且在理论课上可以让老师说明一下,而不是每次都是不太切实际的理论。
posted @ 2021-06-24 13:54  imingx  阅读(73)  评论(1)    收藏  举报