OO第一单元总结

第一次作业

UML类图

OO第一单元总结_第1张图片

耦合度

OO第一单元总结_第2张图片

简单分析

​ 第一次作业,仅需简单的多项式求导,合并,化简,故只创建了多项式Poly类,计算Compute类,和数据处理类RegexMatches。第一次作业并未体现太多面向对象的思想。

Bug分析

  • 自身bug:第一次作业较为简单,未发现bug。但仍需注意+1,-1,0等特殊情况。
  • 同学bug:由一般性的数据,到一些特殊情况的数据,还是测出了一些bug。

测试

​ 第一次作业较为简单,手动生成数据进行测试。

第二次作业

UML类图

OO第一单元总结_第3张图片

耦合度分析

OO第一单元总结_第4张图片

简单分析

​ 第二次作业相比于第一次,难度呈指数级增长。首先,本次增加了三角函数,故增加功能,使Poly多项式增加存储三角函数类Triangle的功能。但是我的解决方法十分粗糙,仅仅是在Poly内增加一个内部变量,导致第三次作业迭代困难。

​ 在阅读了大佬们的总结后,发现可以运用接口与工厂模式的知识,使每个因子实现同一个接口,简化问题。可能我急于将代码写完,而忽略了学以致用。虽然第二次作业较为顺利,但间接导致了后续任务开展困难,也算是一个教训吧。

​ 优化方面,采用了评论区同学分享的分情况讨论的方法,效果不错。

bug分析

  • 本次强测出现一处bug,在于计算结果全为0时,未输出的特判,修改两行通过。互测bug也是出于此处。
  • 互测同学们的bug时,分为两种。第一种是特殊短小的数据,主要测试边界条件的判断;第二种时普通但冗长的数据,主要测试程序的健壮性。

第三次作业

UML

OO第一单元总结_第5张图片

耦合度分析

OO第一单元总结_第6张图片

简单分析

​ 第三周ddl较多,想着周六一天写完的计划最后失败了,中测还有两个点没过,也算是给自己一个教训吧。不仅仅是时间规划的问题,更重要的是,对于面向对象编程理解的不够深刻。’

​ 第三次作业,在第二次的基础上增加了复合关系。实操过程中就多了两个难点。

  • 嵌套因子导致解析输入更加困难
  • 嵌套因子构建语法树

​ 事实上,难点二已经被攻克(不考虑优化),语法树已经构建好。但对于题目因子定义理解的偏差,导致输入数据处理有问题。况且这次时间有限,加上作业一、二留下的隐患——迭代能力差,更是雪上加霜。作业三基本上又是重构了一次。更是让我意识到接口,工厂模式的重要性。

BUG分析

  • 对于题意理解有误,导致中测未得满分

第一单元总结

程序结构

​ 通过三张UML图能够发现,代码仍然处于“面向过程”的阶段,导致模块间__耦合度__高,牵一发而动全身。每周几乎都是通过重构编写代码,效率低下。

​ 接下来应当多多阅读大佬们的优秀代码,迎头赶上。

BUG分析

  • 自测

    自测过程以特殊加一般结合,以xeger根据正则表达式生成一般数据,尽量做到全覆盖。接着手动输入特殊数据点,检测边界条件。

  • 互测

    互测过程则进行全覆盖测试。再对错误代码进行分析,缩小错误范围,最终找到bug类型。之后的数据点尽量避免此类bug,避免同质化。

应用对象创建模式重构

OO第一单元总结_第7张图片

​ 参考助教分享的优秀代码,可为每个基本因子实现同一个Factor接口,具有相同的基础方法。再使用工厂模式,每次代码的迭代,仅需修改接口内的方法,或者增添新的计算因子类实现此接口,就可以完成迭代。

​ 接口与工厂模式的使用达到了高内聚,低耦合的效果。

对比心得和体会

​ 第一单元眨眼就过去了,面向对象的思维也在第三次作业的失利中深入人心。再总结一下设计追求或者设计思想吧,希望在之后的学习中能够时时想起这些原则。

  • 高内聚低耦合

    • 耦合就是元素与元素之间的连接,感知和依赖量度。这里说的元素即是功能,对象,系统,子系统。模块。

      低耦合即元素之间不能过于依赖,应当各司其职。

      具体实现可通过接口有效降低耦合度。

    • 高内聚是另外一个评判软件设计质量的标准。内聚更为专业的说法叫做功能内聚,是对系统中元素职责的相关性和集中度的量度。如果元素有高度的相关职责,除了这些职责在没有其他的工作,那么该元素就有高内聚。

      高内聚可以使代码具有高的可读性、复用性、可维护性等。

  • 设计模式六大原则

    • 单一职责原则

      对象不应承担太多功能,正如一心不能而用,比如太多的工作(种类)会使人崩溃。唯有专注才能保证对象的高内聚;唯有唯一,才能保证对象的细粒度。即A类需求修改时,不能影响B类。

    • 接口隔离原则

      • 客户端不应依赖它不需要的接口

      • 类间的依赖关系应该建立在最小的接口上

      即不能让一个接口给多个模块调用时,每个模块依赖的方法不同,而不得不实现不必要的方法。做法是接口中不应有很多方法,接口应当专门化。

    • 依赖倒置原则

      • 层模块不应该依赖底层模块,二者都应该依赖抽象。
      • 抽象不应该依赖细节,细节应该依赖抽象。
      • 依赖倒置的中心思想是面向接口编程。
      • 依赖倒置原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础搭建的架构要稳定的多。
      • 使用接口或抽象类的目的是指定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类来完成。
    • 里氏替换原则

      子类应当可以替换父类并出现在父类能够出现的地方。

    • 迪米特法则(LOD)

      ​ 也叫最少知识原则。迪米特法则的定义是只与你的直接朋友交谈,不与"陌生人"说话。如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该应用。其目的是降低类之间的耦合度,提高模块的相对独立性。

        迪米特法则中的朋友是指:当前对象本身、当前对象的成员对象、当前对象所创建的对象、当前对象的方法参数等,这些对象存在关联、聚合或组合关系,可以直接访问这些对象的方法。

    • 开闭原则

      Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.软件对象(类、模块、方法等)应该对于扩展是开放的,对修改是关闭的。

      ​ 用抽象构建框架,用实现扩展细节。因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节,我们用从抽象派生的实现类来进行扩展,当软件需要发生变化时,我们只需要根据需求重新派生一个实现类来扩展就可以了。当然前提是我们的抽象要合理,要对需求的变更有前瞻性和预见性才行。

    其实概念再多,也不及自己的熟能生巧,第一单元已经过去,凡为过往,皆为序章。希望自己能够早日走向“面向对象”的正规,和“面向过程”再见。

你可能感兴趣的:(OO第一单元总结)