BUAA_OO_Unit4总结
Unit 4
架构设计
-
UmlClassModel
类UmlClassModel的属性如下所示:
private final HashMap<String, UmlElement> elements = new HashMap<>(); //对于每一个UmlElement,建立其Id与自身一一对应的关系,以便根据Id便可以直接找到UmlElement private final HashMap<String, ArrayList<String>> classes = new HashMap<>(); //键为UmlClass的name,值为UmlClass的Id private final HashMap<String, ArrayList<String>> interfaces = new HashMap<>(); //键为UmlInterface的name,值为UmlInterface的Id private final HashMap<String, ArrayList<String>> attributes = new HashMap<>(); //键为UmlClass或UmlInterface的Id,值为UmlAttribute的Id private final HashMap<String, HashMap<String, ArrayList<String>>> operations = new HashMap<>(); //键为UmlClass或UmlInterface的Id,第二个键为UmlOperation的name,值为UmlOperation的Id private final HashMap<String, ArrayList<String>> parameters = new HashMap<>(); //键为UmlOperation的Id,值为UmlParameter的Id private final HashMap<String, ArrayList<String>> associations = new HashMap<>(); //键为UmlClass或UmlInterface的Id,值为UmlAssociationEnd的Id private final HashMap<String, ArrayList<String>> generalize = new HashMap<>(); //键为UmlClass或UmlInterface的Id,值为UmlClass或UmlInterface的Id private final HashMap<String, ArrayList<String>> generalized = new HashMap<>(); //键为UmlClass或UmlInterface的Id,值为UmlClass或UmlInterface的Id private final HashMap<String, ArrayList<String>> realize = new HashMap<>(); //键为UmlClass的Id,值为UmlInterface的Id private final HashMap<String, ArrayList<String>> realized = new HashMap<>(); //键为UmlInterface的Id,值为UmlClass的Id
-
UmlCollaboration
类UmlCollaboration的属性如下所示:
private final HashMap<String, UmlElement> elements = new HashMap<>(); //对于每一个UmlElement,建立其Id与自身一一对应的关系,以便根据Id便可以直接找到UmlElement private final HashMap<String, HashSet<String>> attributes = new HashMap<>(); //键为UmlCollaboration的Id,值为UmlAttribute的Id private final HashMap<String, ArrayList<String>> interactions = new HashMap<>(); //键为UmlInteraction的name,值为UmlInteraction的Id private final HashMap<String, HashMap<String, ArrayList<String>>> lifelines = new HashMap<>(); //键为UmlInteraction的Id,第二个键为UmlLifeline的name,值为UmlLifeline的Id private final HashMap<String, HashSet<String>> endPoints = new HashMap<>(); //键为UmlInteraction的Id,值为UmlEndPoint的Id private final HashMap<String, ArrayList<String>> receivedMessages = new HashMap<>(); //键为UmlLifeline或UmlEndPoint的Id,值为UmlMessage的Id private final HashMap<String, ArrayList<String>> sentMessages = new HashMap<>(); //键为UmlLifeline或UmlEndPoint的Id,值为UmlMessage的Id
-
UmlStateChart
类UmlStateChart的属性如下所示
private final HashMap<String, UmlElement> elements = new HashMap<>(); //对于每一个UmlElement,建立其Id与自身一一对应的关系,以便根据Id便可以直接找到UmlElement private final HashMap<String, ArrayList<String>> stateMachines = new HashMap<>(); //键为UmlStateMachine的name,值为UmlStateMachine的Id private final HashMap<String, String> regions = new HashMap<>(); //键为UmlStateMachine的Id,值为UmlRegion的Id private final HashMap<String, HashMap<String, ArrayList<String>>> states = new HashMap<>(); //键为UmlRegion的Id,第二个键位UmlState的name,值为UmlState的Id private final HashMap<String, ArrayList<String>> pseudoStates = new HashMap<>(); //键为UmlRegion的Id,值为UmlPseudoState的Id private final HashMap<String, ArrayList<String>> finalStates = new HashMap<>(); //键为UmlRegion的Id,值为UmlFinalState的Id private final HashMap<String, HashMap<String, ArrayList<String>>> transitions = new HashMap<>(); //键为UmlTransition的source的Id,第二个键为UmlTransition的target的Id,值为UmlTransition的Id private final HashMap<String, ArrayList<String>> events = new HashMap<>(); //键为UmlTransition的Id,值为UmlEvent的Id private final HashMap<String, ArrayList<String>> behaviors = new HashMap<>(); //键为UmlTransition的Id,值为UmlBehavior的Id
四个单元架的构设计思维
第一单元
-
递归下降
表达式为项的和,项为因子的乘积,因子又分为变量因子、常数因子、表达式因子、三角函数因子等,使用递归下降的方法,对输入的字符串层层解析。
-
层次化设计
Expr为第一层,Term为第二层,Factor为第三层,分层设计,各司其职,协同工作。
第二单元
-
生产者消费者模型
Input线程为生产者,电梯线程为消费者,Input将输入进来的请求放到共享队列中,电梯线程进行处理。
-
自由竞争
多个电梯共享一个共享队列,采取自由竞争的方法,将请求分配给多个电梯
-
流水线架构
新增Controller类来对请求进行分段处理,通过交替乘坐横纵电梯将请求送到目的地。
第三单元
-
JML的阅读与编写
本单元的核心目标为通过阅读JML来理解需求,并用代码实现,同时要求我们有一定的编写JML的能力。
-
时间复杂度
本单元对性能的要求较高,要求我们使用合适的数据结构或者算法,尽量降低时间复杂度以满足要求。
第四单元
-
数据结构的设计
本单元要求我们在理解UML的基础上,对UML进行有关的询问以及合法性检查,所以在原来的UML元素数组的基础上我们需要通过构造函数建立新的数据结构以方便我们的询问以及检查,正如上面写到的第四单元三个类中的属性。
四个单元的测试
第一二单元
由于前两个单元的输出并不唯一,所以自动化的正确性检测很困难,我采用了自己构造数据检查输出的方法。
第三四单元
后两个单元的输出是唯一的,并且此时也理解到了自动化检测的重要性,于是通过编写python程序实现了数据生成器以及对拍器来检测程序的正确性,并且深刻感受到了自动化检查的方便快捷,以后也会尽可能多的使用自动化检查。
课程收获
-
注重OOP思想
由于继承、封装、多态的特性,使得代码更好扩展。同时,面向对象编程也符合人类对事物的认识。
-
重设计轻实现
我们应把大量的时间花费在设计上,而不是急于实现。当我们设计完成后,我们就应该知道我们的代码可以完成哪些功能,而又不可以完成哪些功能。实现只是对设计的代码化,个人认为这是一个比较机械的过程。如果并没有完成设计就开始了代码实现,此时思路并不清晰,极易出现bug,而且当这一设计走不通时,代码还要重写。
-
化繁为简
当我们面临一个复杂的工程时,可以将这一复杂的工程进行适当的简化,并在此基础上进行迭代开发,逐步解决复杂工程。
-
及时重构
当我们需要对工程的功能进行扩展时,如果我们当前的架构已经不能实现该功能,或者我们为了实现这一功能导致架构很不优雅,这时我们就需要及时对我们的架构进行重构,设计出一个更好的架构。
-
单一职责
每一个类都应该有自己所应该履行的职责,并且这个职责是单一的。比如共享对象类,应该确保自己的线程安全性,确保任何线程调用自己的方法都不会出现线程安全的问题,而不需要线程本身去维护,线程类则只需要专注于自己的业务。如果不注重单一职责,则各个类之间互相依赖,关系错综复杂,极易出现bug。
-
全面考虑
多线程程序比较复杂,我们需要考虑到所有可能会发生的情况,并对一些操作进行原子化,防止因为线程不安全而产生bug,并且这类bug一般不易复现。
改进建议
-
第一单元
对于第一单元,我认为可以去掉自定义函数以及求和函数的相关内容,因为我在处理这两类函数的时候仅使用了字符串的替换,并没有涉及到面向对象的相关思维。我认为可以把这一部分内容换成输入的合法性检测,对于不合法的输入抛出异常,使得程序的鲁棒性更强。
-
测试
测试在软件开发的重要程度也非常高,与其在强测中wrong answer再修复bug,不如提前编写测试程序对程序的正确性进行检查,但由于课程组并没有提供有关自动化测试的教程,导致只有少数人进行了自动化测试,大部分同学并没有培养相关的测试能力。
-
第三单元
本单元的作业中只要求了JML的阅读,并没有要求JML的编写,导致很多同学并不能真正的有能力编写JML规格。