• Summary of OO Unit4


    一、本单元作业的架构设计

    本单元中,我对几个关键的UmlElement进行了包装,使它们存储的信息更多,查询功能更全面。同时,基于UmlClass与UmlInterface的行为共性,建立了共同接口UmlClassic。此外,将实现视为特殊的继承,无论是继承还是实现,都把id放到同一个HashSet内进行管理。缺点在于,没有对各个查询方法进行封装,而是直接在用户交互层面进行。

    在第二次作业中,新增的功能并不多,但由于第一次作业没有抽象出图类,因此我进行了小幅度的重构。我为三种图设计了三个类,将第一次作业的许多查询方法封装到类图中,存储相关元素的包装类,为了方便和偷懒,每一个元素都有两个HashMap,分别以id和name为key。

    在第三次作业中,需要进行八种有效性检查,其中个人认为最棘手的是R002-R004。为此,在继承与实现的结构层次上,我在每个类、接口中除了记录父节点,还记录所有子节点,从而在有新的继承时,对父子类实现同步更新,并针对R003、R004,直接从父节点往下进行广搜。对其他的检查,可以直接在图的构造过程中完成判断,因此在输入结束后,我已经获得了所有检查的判断结果。

    以下是第三次作业的UML类图(只画出了关键的几个类,其余元素单纯只是被存储到了它们之中):

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

    在第一单元,我还停留在面向过程的思维,没有抽象,没有分工,直到第三次作业才有了建立表达式树分层次管理的意识,也是从这时候起,我开始有了抽象、分类、包装的意识。

    在第二单元,我在架构上下了功夫,使用生产者消费者模式,代码耦合度低,分工明确,这个单元也是我将面向对象设计理念运用得最好的一次。通过这个单元作业和实验的练习,我体会到了善用架构对程序的功能管理、迭代开发的好处。

    在第三单元,本以为上个单元是一个开始,实际上却成了巅峰。依赖着jml,我在架构设计上犯懒严重,代码虽然有一定的分工,但还是回到了面向过程的老毛病。一个单元下来,我体会到了从规格的角度出发审视、设计代码的重要性。从规格出发,我们就能成为代码的主人。

    在第四单元,架构上还不错,起到了一定的解耦作用,但由于时间较紧,代码比较难看。不过,本单元学习之后,我对OO方法有了进一步认识,知道了如何用面向对象式的抽象又直观的描述逻辑,把系统抽象表示为类和类之间的协同,通过可视化的模型图来描述和展示系统功能、结构和行为。

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

    第一单元:采用python的sympy、xeger库随机生成数据进行测试,为了防止ctle,还手动构造了一些测试数据。

    第二单元:个人认为本单元只需处理好几个特殊的输入情况即可基本完成测试,因此没有使用随机生成的数据,而是搭建了一个输入接口,实现延时读入乘客的功能。源码如下:

    import java.io.InputStream;
    import java.util.List;
    import java.util.Scanner;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    import java.util.function.Consumer;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class ScheduledInput {
        private static final Pattern PATTERN = Pattern.compile("^\[(?<time>\d+.\d+)](?<personId>\d+)-FROM-(?<fromFloor>(-|\+|)\d+)-TO-(?<toFloor>(-|\+|)\d+)\s*$");
    
        private final Scanner scanner;
        private final ScheduledExecutorService executor;
        private final Consumer<Passenger> consumer;
        private final Runnable closeRunnable;
        private final List<Elevator> elevators;
    
        public ScheduledInput(InputStream input, Consumer<Passenger> consumer, Runnable closeRunnable,
                              List<Elevator> elevators) {
            this.scanner = new Scanner(input);
            this.consumer = consumer;
            this.closeRunnable = closeRunnable;
            this.executor = Executors.newSingleThreadScheduledExecutor();
            this.elevators = elevators;
        }
    
        public void start() {
            while (true) {
                try {
                    String s = scanner.nextLine();
                    if (s.isEmpty()) {
                        scanner.close();
                        executor.shutdown();
                        closeRunnable.run();
                        return;
                    }
                    parse(s);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        public void parse(String s) {
            Matcher matcher = PATTERN.matcher(s);
            if (!matcher.matches()) throw new IllegalArgumentException();
    
            long time = (long) (Double.parseDouble(matcher.group("time")) * 1000);
            int personId = Integer.parseInt(matcher.group("personId"));
            int fromFloor = Integer.parseInt(matcher.group("fromFloor"));
            int toFloor = Integer.parseInt(matcher.group("toFloor"));
            Passenger passenger = new Passenger(personId, fromFloor, toFloor);
            passenger.compute(elevators);
            executor.schedule(() -> consumer.accept(passenger), time, TimeUnit.MILLISECONDS);
        }
    }
    
    

    第三单元:本单元过于掉以轻心,只采取了手动构造数据+与同学对拍的方式,测试得并不充分,导致了三次作业失分严重。后来在单元结束时,学会了使用Junit进行测试。

    第四单元:个人认为,本单元和第二单元类似,只要在保证基本功能的正确性后,处理好少数几个特殊情况即可,因此主要通过手动画图、利用官方包导出数据的方式进行测试。

    四、课程收获

    一学期下来,我最大的收获就是学会了用抽象的方式剖析任务。面对较为复杂的需求,不再一头雾水,想到什么写什么,而会首先分析内在逻辑,归纳功能层次,提取潜在共性,设计出一个脉络清晰、有明确分工的程序。

    此外,我对数据结构与程序设计的结合有了新的认识,二者是相辅相成的。同时,也纠正了以前学习这两门课时固有的面向过程的设计思维,学会用更清晰的逻辑设计程序。

    五、三个具体改进建议

    研讨课希望能更看重质,而不是量。对报名的同学进行严格甄选,将空谈理论的予以淘汰。如果实在没有合适的人,不如带领我们阅读一些官方源码或者好的文章,宁缺毋滥。

    第三单元中算法似乎过于抢戏,有的同学为了不在测试中超时,优化了算法而牺牲了架构,背离了OO的理念。

    第四单元的理论课似乎没有起到足够的知识积累的作用,理论部分占比太大,对三类图的讲解偏少。虽然课后在讨论区还有暖心贴、答疑帖,但还是希望课上能学到更多具体的内容。

    六、线上学习OO课程的体会

    就我个人感受而言,OO课不同于传统理工科课程,如数学、物理等,更多时候是学生自己在实践中发现问题、解决问题,达到学习的效果,因此无所谓线上线下。不过若论课堂讨论的活跃程度,自然是现场上课要好得多。

  • 相关阅读:
    将博客搬至CSDN
    Fish 下报错 Unsupported use of '||'. In fish, please use 'COMMAND; or COMMAND'.
    使用VMWare虚拟机打开MFC报错:不支持16位系统
    CodeForce Div 2 C. Masha and two friends
    POJ1426 Find The Multiple
    Educational Codeforces Round 54 (Rated for Div. 2) D:Edge Deletion
    CodeForce Educational round Div2 C
    Tenka 1 Computer Contest C-Align
    CodeForce edu round 53 Div 2. D:Berland Fair
    CodeForce 517 Div 2. C Cram Time
  • 原文地址:https://www.cnblogs.com/edogawaai/p/13128479.html
Copyright © 2020-2023  润新知