LAB3

目录

 

1 实验目标概述··· 1

2 实验环境配置··· 1

3 实验过程··· 1

3.1 待开发的三个应用场景··· 1

3.2 基于语法的图数据输入··· 2

3.3 面向复用的设计:CircularOrbit<L,E>· 2

3.4 public void readFile(String pathname);面向复用的设计:Track· 4

3.5 面向复用的设计:L· 5

3.6 面向复用的设计:PhysicalObject· 5

3.7 可复用API设计··· 6

3.8 图的可视化:第三方API的复用··· 6

3.9 设计模式应用··· 6

3.10 应用设计与开发··· 6

3.10.1 TrackGame·· 6

3.10.2 AtomStructure·· 7

3.10.3 SocialNetworkCircle·· 8

3.11 应对应用面临的新变化··· 9

3.12 Git仓库结构··· 9

4 实验进度记录··· 9

5 实验过程中遇到的困难与解决途径··· 10

6 实验过程中收获的经验、教训、感想··· 10

6.1 实验过程中收获的经验和教训··· 10

6.2 针对以下方面的感受··· 10

1 实验目标概述

2 实验环境配置

在这里给出你的GitHub Lab3仓库的URL地址(Lab3-学号)。

https://github.com/ComputerScienceHIT/Lab3-1170400307

3 实验过程

请仔细对照实验手册,针对每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。

3.1 待开发的三个应用场景

首先请列出你要完成的具体应用场景(至少3个,1和2中选一,3必选,4和5中选一,鼓励完成更多的应用场景)。

l  TrackGame

l  AtomStructure

l  SocialNetworkCircle

分析你所选定的多个应用场景的异同,理解需求:它们在哪些方面有共性、哪些方面有差异。

共性:

1)轨道都为圆形,其中包括轨道、中心物体、轨道物体。

2)都需要完成的功能有:添加/删除轨道,在某一轨道上添加/删除物体,获得轨道系统的熵值,获得逻辑距离,比较两个同类型轨道系统的差异,检查轨道系统是否合法,可视化。

差异:

1)TrackGame:需要编排。

2)AtomStructure:轨道物体都是值相同的对象,需要实现物体跃迁。

3)SocialNetworkCircle中需要实现物体关系及对应操作,需要计算信息扩散度。

3.2 基于语法的图数据输入

以下分别是三个应用的在输入处理中设计的正则表达式:

(1)String gameP = "Game\\s*::=\\s*([100|200|400,\\|]+)";

       String athletePattern = "Athlete\\s*::=\\s*<([a-zA-Z]+),(\\d+),([A-Z]{3}),(\\d+),(\\d{1,2}\\.\\d{2}+)>";

String trackp = "NumOfTracks\\s*::=\\s*([4-9,10]+)";

(2)String elementNamePattern = "ElementName\\s*::=\\s*([A-Z]{1}[a-z]{0,1})";

String trackPattern = "NumberOfTracks\\s*::=\\s*(\\d+)";

String electronPatternString = "NumberOfElectron\\s*::=\\s*([\\d+\\/\\d+,;]+)";

(3)Pattern pattern1 = Pattern.compile("([A-Z]|[a-z]|[0-9])+");

Pattern pattern3 = Pattern.compile("[,][ ]*(([0][.][0-9]{0,2}[0-9])|([1]([.][0]{0,3})?))");

Pattern pattern2 = Pattern.compile("([0][.][0-9]{0,2}[1-9])|([1]([.][0]{0,3})?)");

3.3 面向复用的设计:CircularOrbit<L,E>

/**

     * 增加一条轨道

     */

    public boolean addtrack(track t);

 

    /**

     * 删除一条轨道

     */

    public boolean removetrack(track t);

 

    /**

     * 设定中心点物体

     */

     public void setcentralobject(L o);

     

     /**

      * 获取中心天体

      */

     public L getcentralobject();

     

    /**

     * 增加物体到特定轨道

     */

    public boolean addobjecttotrack(track t, E o);

    /**

     * 移除物体从特定轨道

     */

    boolean removeobjecttotrack(track t, E o);

    /**

     * 移动物体到特定轨道

     */

    public boolean transit(E o, track t);

 

    /**

     * 在物体之间添加关系

     */

    public boolean addtrackrelation(E o1, E o2, double  distance);

   

    /**

     * 在物体之间添加关系

     */

    public boolean removetrackrelation(E object1, E object2, double  distance);

 

    /**

     * 在中心点与轨道物体上添加关系

     */

    public boolean addcentralrelation(L center, E object, double distance);

 

    /**

     * 计算熵值

     */

    public double getentropy();

 

    /**

     * 获取已排序轨道表

     */

    public List<track> getsortedtracks();

 

    /**

     * 获取轨道数量

     */

    public Integer gettracknum();

 

    /**

     * 获取轨道t上的物体数

     */

    public Integer getobjectnumontrack(track t);

 

    /**

     * 轨道t上的物体

     */

    public List<E> getobjectontrack(track t);

 

    /**

     * 可视化

     */

    public void drawpicture(String orbitname);

    /**

     * 从外部文件读取数据构造轨道系统对象

     */

3.4 面向复用的设计:Track

轨道类:唯一域为半径

    double radius;

 

    /*重写比较方法*/

    @Override

public int compareTo(track that)

 

    @Override

public int hashCode()

 

    @Override

    public boolean equals(Object obj)

3.5 面向复用的设计:L

构造了centralobject作为父类。

/**

     * @return 半径

     */

    public double getradius();

   

    /**

     * @return 极角

     */

    public double getangle();

   

    /**

     * @return 姓名

     */

    public String getname();

   

    /*比较函数*/

    public boolean equals(Object o);

   

    /*打印字符串*/

    public String toString();

3.6 面向复用的设计:PhysicalObject

/**

     * 

     * @return 半径

     */

    public double getradius();

    /**

     *

     * @return 极角

     */

    public double getangle();

    /**

     *

     * @return 姓名

     */

    public String getname();

   

    /*比较函数*/

    public boolean equals(Object o);

   

    /*打印字符串*/

    public String toString();

   

    public int hashCode();

3.7 可复用API设计

1.计算轨道系统熵值:在泛型中已经具体实现。

2.获取最短逻辑距离。在泛型中已经具体实现。

3.获取物理距离:在绘图相关类中实现。

4.计算两个多轨道系统之间的差异:

在ConcreteCircularOrbit中我们将两个对应的轨道物体集合添加到Difference对象中。下面声明Difference的类设计。

每一对比较的轨道,各自形成集合且只保留各自轨道上独有的轨道物体(去除交集,这里的比较使用equalsObject进行值比较),通过两个集合构造trackDifference对象,一个轨道系统的Difference由多个trackDifference构成。在trackDifference中提供toString方法将差异转化为字串,需要注意的是,如果两个集合都为空则说明两轨道上物体完全相同,这时候不输出“物体差异”。

3.8 图的可视化:第三方API的复用

本实验中使用Swing实现可视化功能。同时,在简单的轨道系统可视化基础上,添加了一部分简单控件用于优化交互体验。

3.9 设计模式应用

   Track,PhysicalObject等对象使用静态工厂方法实现。

3.10 应用设计与开发

利用上述设计和实现的ADT,实现手册里要求的各项功能。

以下各小节,只需保留和完成你所选定的应用即可。

3.10.1 TrackGame

排序策略

    public void pickingrade() {

        int num=gettracknum();

        racer[] all=new racer[num];

        int i=0;

        for(track temp:tracks) {

            all[i]=(racer) getobjectontrack(temp).get(0);

            i++;

        }

        for(i=0;i<num;i++) {

            for(int j=i;j<num;j++) {

                if(all[i].getgrade()>all[j].getgrade())

                {

                   racer x=new racer(null, num, 0, 0, null);

                   x=all[i];

                   all[i]=all[j];

                   all[j]=x;

                }

            }

        }

        i=0;

        for(track temp:tracks) {

            racer x=(racer) getobjectontrack(temp).get(0);

            racer y=all[i];

            removeobjecttotrack(temp, x);

            addobjecttotrack(temp, y);

            i++;

        }

    }

3.10.2 AtomStructure

/**

     *

     * @param electronic 

     * @param track

     * @return  if the electronic is not in destination and the transit completed successfully

     */

    public boolean transit(Electronic electronic, Track<Electronic> track) {

        if (electronic.getTrackRadius() == track.getRadius()) {

            return false;

        }

        if (deleteElectronic(electronic)) {

            track.add(electronic);

            electronic.setTrackRadius(track.getRadius());

            return true;

        } else {

            System.out.println("将该物体从原轨道上删除失败!");

            return false;

        }

    }

3.10.3 SocialNetworkCircle

/**

     * functon4: get the distance of the centralUser and the friend

     * @param friend1 one friend

     * @param friend2 another friend

     * @return the distance

     */

    public int getDistance(Friend friend1, Friend friend2) {

    // Used to determine whether to be accessed or not

        Map<Friend, Boolean> visited = new HashMap<>();

        // Used to record distance

        Map<Friend, Integer> distance = new HashMap<>();

        for (Friend temp : friendShip) {

        // Mark all persons as not accessed

            visited.put(temp, false);

        }

        visited.put(friend1, true);

        // 先广要用队列来做

        Queue<Friend> queue = new LinkedBlockingQueue<>();

        // Person 1 enters the queue

        queue.add(friend1);

        distance.put(friend1, 0);

        if (friend1.equals(friend2)) {

            return 0;

        }

        while (!queue.isEmpty()) {//Cycle until the queue is empty

            Friend head = queue.poll();//Get the head element and bring it out

            Friend tempt = head.getFriendShip().peek();//Get the first person associated with it

            int i = 0;

            while (tempt != null) {// Cycle until no one has a direct relationship with head

                if (!visited.get(tempt)) {//If tempt is not accessed

                    if (tempt.equals(friend2)) {// If you find friend

                        return distance.get(head) + 1;

                    } else {//if not

                        visited.put(tempt, true);

                        distance.put(tempt, distance.get(head) + 1);

                        queue.add(tempt);//Bring the current friend into the queue

                    }

                }

                if (++i < head.getFriendShip().size()) {//Keep looking for people who are related to them

                    tempt = head.getFriendShip().get(i);

                } else {

                    break;

                }

            }

        }

        return -1;

    }

3.11 应对应用面临的新变化

未完成

3.12 Git仓库结构

请在完成全部实验要求之后,利用Git log指令或Git图形化客户端或GitHub上项目仓库的Insight页面,给出你的仓库到目前为止的Object Graph,尤其是区分清楚312change分支和master分支所指向的位置。

4 实验进度记录

请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。

日期

时间段

计划任务

实际完成情况

4/11

10:46-17:05

ConcreteCircularOrbit大体结构

完成

4/12

20:00-0:02

完成TrackGame

完成

4/14

18:00-23:35

完成SocialNetworkCircle

完成

4/21

18:00-23:35

完成AtomStructyre

完成

5.5

18:00-23:35

312change

未完成

5 实验过程中遇到的困难与解决途径

遇到的难点

解决途径

设计模式不会

没写

代码难度太大

没有test

6 实验过程中收获的经验、教训、感想

6.1 实验过程中收获的经验和教训

6.2 针对以下方面的感受

(1)   重新思考Lab2中的问题:面向ADT的编程和直接面向应用场景编程,你体会到二者有何差异?本实验设计的ADT在五个不同的应用场景下使用,你是否体会到复用的好处?

面向ADT编程可复用。

复用确实简单一点,但找共同也很麻烦。

(2)   重新思考Lab2中的问题:为ADT撰写复杂的specification, invariants, RI, AF,时刻注意ADT是否有rep exposure,这些工作的意义是什么?你是否愿意在以后的编程中坚持这么做?

设计ADT的复杂是为了他人使用时候的省心。

如果只是给我自己写的ADT我显然不愿意这么干,太麻烦了。但是如果想要设计ADT给别人用,给公司用,那我是很乐意的!

(3)   之前你将别人提供的API用于自己的程序开发中,本次实验你尝试着开发给别人使用的API,是否能够体会到其中的难处和乐趣?

本实验中API感觉难度一般,具体应用很难。

(4)   在编程中使用设计模式,增加了很多类,但在复用和可维护性方面带来了收益。你如何看待设计模式?

设计模式的使用最大的好处就是简化程序吧,以及可维护性增强了。

(5)   你之前在使用其他软件时,应该体会过输入各种命令向系统发出指令。本次实验你开发了一个解析器,使用语法和正则表达式去解析输入文件并据此构造对象。你对语法驱动编程有何感受?

不理解什么是语法驱动编程。

(6)   Lab1和Lab2的大部分工作都不是从0开始,而是基于他人给出的设计方案和初始代码。本次实验是你完全从0开始进行ADT的设计并用OOP实现,经过三周之后,你感觉“设计ADT”的难度主要体现在哪些地方?你是如何克服的?

难在设计吧:高级类反复设计了好几次;具体功能调用函数反复写了好几次。

(7)   你在完成本实验时,是否有参考Lab4和Lab5的实验手册?若有,你如何在本次实验中同时去考虑后续两个实验的要求的?

没有

(8)   关于本实验的工作量、难度、deadline。

没有完成,希望从宽给分,绕我一命。

(9)   到目前为止你对《软件构造》课程的评价。

挺好的,能够大幅度提高自己的工程能力吧,比如设计模式就是程序员精髓。

猜你喜欢

转载自www.cnblogs.com/richardodliu/p/11061657.html