软件构造实验三报告

 

目录

 

1 实验目标概述···· 1

2 实验环境配置···· 1

3 实验过程···· 1

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

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

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

3.4 面向复用的设计:Track· 2

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

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

3.7 可复用API设计···· 2

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

3.9 设计模式应用···· 2

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

3.10.1 TrackGame· 2

3.10.2 StellarSystem· 2

3.10.3 AtomStructure· 2

3.10.4 PersonalAppEcosystem· 2

3.10.5 SocialNetworkCircle· 2

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

3.11.1 TrackGame· 3

3.11.2 StellarSystem· 3

3.11.3 AtomStructure· 3

3.11.4 PersonalAppEcosystem· 3

3.11.5 SocialNetworkCircle· 3

3.12 Git仓库结构··· 3

4 实验进度记录···· 3

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

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

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

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

 

 

 

 

  1. 实验目标概述

本次实验覆盖课程第 3、5、6 章的内容,目标是编写具有可复用性和可维护

性的软件,主要使用以下软件构造技术:

⚫ 子类型、泛型、多态、重写、重载

⚫ 继承、代理、组合

⚫ 常见的 OO 设计模式

⚫ 语法驱动的编程、正则表达式

⚫ 基于状态的编程

⚫ API 设计、API 复用

本次实验给定了五个具体应用(径赛方案编排、太阳系行星模拟、原子结构

可视化、个人移动 App 生态系统、个人社交系统),学生不是直接针对五个应用

分别编程实现,而是通过 ADT 和泛型等抽象技术,开发一套可复用的 ADT 及其

实现,充分考虑这些应用之间的相似性和差异性,使 ADT 有更大程度的复用(可

复用性)和更容易面向各种变化(可维护性)。

 

  1. 实验环境配置

简要陈述你配置本次实验所需环境的过程,必要时可以给出屏幕截图。

特别是要记录配置过程中遇到的问题和困难,以及如何解决的。

建立远程仓库链接:

$ git init命令初始化

       $ git remote add origin <url> 添加远程仓库

       $ git add.添加文件到仓库

       $ git commit –m “”提交

       $ git push上传到远程仓库

 

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

https://github.com/ComputerScienceHIT/Lab3-1170300724.git

 

  1. 实验过程

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

    1. 待开发的三个应用场景

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

  1. TrackGame
  2. AtomStructer
  3. SocialNetWorkCicle

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

相同点:

都有多个轨道,轨道上有一些物体,轨道上的物体属于一个类,要实现增加轨道,删除轨道,在某个轨道上增加物体,在某个轨道上删除物体,从文件中按照一定规则读取信息,并建立轨道系统。

不同点:

TrackGame:

①需要分成多个组,每个组都是一个轨道系统

②每组中每个轨道上都最多只能有一个Athlete

③运动员位置的分配有两种方案且两种方案可以随时切换

④没有中心点

AtomStructer

①每个电子之间都没有区别

SocialNetWorkCicle

①轨道物体之间、轨道物体与中心点之间可能存在双向的具有权值的边

②在关系确定的情况下,每个物体所在的轨道都是确定不可改变的

③第一轨道上的Friend都具有扩散度这一属性

④物体之间具有逻辑距离

    1. 基于语法的图数据输入

TrackGame:

    String regex_1="(Athlete ::= <)([\\w,.\\d]+)(>)";

    String regex_2="(Game ::= )([,.\\d]+)";

    String regex_3="(NumOfTracks ::= )([\\w,.\\d]+)";

AtomStructer:

    String regex_1="(NumberOfElectron ::= )([\\d/;]+)";

    String regex_2="(ElementName ::= )((\\w){1,2})";

    String regex_3="(NumberOfTracks ::= )(\\d)";

SocialNetWorkClcle:

    String regex_1="(CentralUser ::= <)([\\w\\d,.]+)(>)";

    String regex_2="(Friend ::= <)([\\w\\d,.\\s]+)(>)";

    String regex_3="(SocialTie ::= <)([\\w\\d,.\\s]+)(>)";

利用正则表达式

regex1匹配中心点用户信息,<>中信息的形式是<姓名,年龄,性别>,姓名是Word,由多个字母构成,有大写,也有小写,年龄是正整数,姓名是字符串,是“M”““”“F”之一。

regex2匹配关系,关系由两个人名及其亲密度组成,SocialTie ::= <用户 1 姓名,用户 2 姓名,社交亲密度>, 亲密度是范围在(0,1]内的小数,最多 3 位小数位,用户 1 和用户 2 可以是 CentralUser 或 Friend,由于文件中存在空格,于是匹配的时候加入“\\s”。

regex3匹配朋友信息,朋友信息和中心用户信息形式一致,但<>中具有多余的空格,匹配时先把空格读入,在录入信息时将空格删去

读入后还要进行合法性检查,保证不会出现错误的显示

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

public interface CircularOrbit<L,E> {

     * get tracks map

    public Map<Track, List<E>> getTracks();

     * get center L

    public L getCenter();

     * get center relation List

    public Map<E, Double> getCenterRelation();

     * get relation map E and E

    public Map<E, Map<E, Double>> getRelation();

     * public getPosition map

    public Map<E, Position> getPositions();

     * Create an empty circularOrbit.

    public static <L,E> CircularOrbit<L,E> empty() {

    return new ConcreteCircularOrbit<L, E>();

    }

     * add some tracks to this game

    public boolean addTrack(Track track);

     * delete a track of this system

    public boolean removeTrack(Track track);

     * add a centraobject

    public boolean addCentra(L center);

     * add object to track

    public boolean addObjectToTrack(E e,Track track);

     * add relation between centra and an object

    public boolean addCentraRelation(E e,double d);

     * add relation between tow object on track

    public boolean addRelation(E e1,E e2,double d);

     * create an Orbit from reading file

    public boolean Creat(String Fielname);

     * change the track

    public boolean transit(Track t1,Track t2);

     * move an object on a track

    public boolean move(E object, double sitha);

     * next

    public void next();

     * remove a object on track

    public boolean removeObjectOnTrack(E e,Track t);

    1. 面向复用的设计:Track

Track只具有2个属性:id和半径

    private int r;

     Object pobject;

    private String name;

       public Track(String name,int r) {

              this.r=r;

              this.name=name;

       }

       public String getName() {

              return this.name;

       }

       public int getR() {

              return this.r;

       }

       public boolean addObject(L newObject)

         {

            if(isExist(newObject))

                     return false;

              pobject.add(newObject);

               return true;

         }

         public boolean remove(L newObject)

         {

                //int size=pobject.size();

                //for(int i=0;i<size;i++)

                {

                       //if(pobject.get(i).equals(newObject))

                       {

                              //pobject.remove(i);

                              return true;

                       }

                }

                return false;

         }

         public boolean isExist(L obj)

         {

                //int size=pobject.size();

                //for(int i=0;i<size;i++)

                {

                       //if(pobject.get(i).equals(obj))

                              return true;

                }

                return false;

         }

         public L get(L obj)

         {

                //for(int i=0;i<pobject.size();i++)

                {

                       //if(pobject.get(i).equals(obj))

                             // return pobject.get(i);

                }

                System.out.println("not exist");

                return null;}

       @Override

       public boolean equals(Object obj) {

              if (obj instanceof Track) {

            Track t= (Track) obj;

            return r==t.getR();

        }

        return false;

       }

       @Override

       public int hashCode() {

              return this.r;

       }

    1. 面向复用的设计:L

centralObject类作为父类,只有名字name一个属性

所有L均为centralObject, TrackGame中其实没有中心物体,作为泛型的L,为防止空指针错误,设计一个EmptyCentral表示空中心,EmptyCentral的名字一定是empty,可以通过名字判断中心是否为空。

public class ConcreteCircularOrbit<L,E> implements CircularOrbit<L, E>

public static <L,E> CircularOrbit<L,E> empty()

    1. 面向复用的设计:PhysicalObject

为了实现可复用的PhysicalObject,设计了一个ADT,其他类都继承自这个ADT

public abstract class PhysicalObject {

     String name;

    public String getName() {

        return this.name;

    }

    /*public PhysicalObject(String name)

    {

        this.name=name;

    }*/

    public PhysicalObject(String name) {

        super();

        this.name = name;

    }

public class Electron extends PhysicalObject{

    private final boolean isDifferent=false;

    private int number;

    public boolean isDifferent() {

        return isDifferent;

    }

    public Electron(String name) {

        super(name);

    }

    public String getName()

    {

        return this.name;

    }

    public int getNumber()

    {

        return this.number;

    }

    @Override

    public String toString() {

        return this.getName();

    }

    @Override

    public boolean equals(Object obj)

    {

        if(!(obj instanceof Electron))

            return false;

        Electron f=(Electron)obj;

        return f.number==this.number;

    }

}

public class Person {

    private String name;

    private int age;

    private String sex;

    private final boolean isDifferent=true;

    public boolean isDifferent() {

        return isDifferent;

    }

    public Person(String name, int age, String sex) {

        super();

        this.name = name;

        this.age = age;

        this.sex = sex;

    }

    public String getName() {

        return name;

    }

    public int getAge() {

        return age;

    }

    public String getSex() {

        return sex;

    }

    @Override

    public String toString() {

        return this.name;

    }

    @Override

    public boolean equals(Object obj) {

        if(!(obj instanceof Person))

        return false;

            Person person= (Person) obj;

            return name.equalsIgnoreCase(person.getName().trim());

    }

    @Override

    public int hashCode()

    {

        int sum=0;

        for(int i=0;i<name.length();i++)

        {

            sum+=(int)name.charAt(i);

        }

            return sum;

    }

}

public class Player extends PhysicalObject{

    private String nation;

    private int number;

    private int age;

    private double bestScore;

    private final boolean isDifferent=true;

    public boolean isDifferent() {

        return isDifferent;

    }

    public Player(String name,int number, String nation, int age, double bestS) {

        super(name);

        this.number = number;

        this.nation = nation;

        this.age = age;

        this.bestScore = bestS;

    }

   

    public int getNumber() {

        return this.number;

    }

    public String getNation() {

        return this.nation;

    }

 

    public int getAge() {

        return this.age;

    }

 

    public double getBestScore() {

        return this.bestScore;

    }

 

    @Override

    public String toString() {

        return this.getName()+" "+this.bestScore;

    }

    @Override

    public boolean equals(Object obj) {

        if (obj instanceof Player) {

            Player person= (Player) obj;

            return this.getName().equalsIgnoreCase(person.getName().trim());

        }

        return false;

    }

    @Override

    public int hashCode() {

        return this.age;

    }

    1. 可复用API设计

计算熵值公式:-∑x(i)ln(x(i)),x(i)=number(i)/sum,number(i)第i个轨道上物体的数量,sum是所有轨道上物体的总数。

public double getObjectDistributionEntropy(CircularOrbit<L,E> c) {

        double entropy=0;

        double sum=0;

        Map<Track, List<E>> OTmap = new HashMap<>();

        for(Track t:OTmap.keySet()) {

            sum+= OTmap.get(t).size();

        }

        sum=0;

        for(Track k:c.getTracks().keySet()) {

            sum+=c.getTracks().get(k).size();

        }

        for(Track t:OTmap.keySet()) {

            double piOTmap.get(t).size()/sum;

            if(pi==0)

                continue;

            entropy += -pi*Math.log(pi)/Math.log(2);

        }

        entropy=0;

        for(Track k:c.getTracks().keySet()) {

            double y=(double)c.getTracks().get(k).size();

            double x=y/(double)sum;

            entropy+=(-x*Math.log(x));

        }

        return entropy;

    }

计算逻辑距离

每次取出队首元素并将和该节点有关系的元素入队

被放入的元素相应的Integer设置为父结点Integer+1

返回e2对应的Integer,若一直找不到,则返回-1

public int getLogicalDistance (CircularOrbit<L,E> c, E e1, E e2) {

        Map<E, Map<E, Double>> relationMap=c.getRelation();

        List<E> gragh=new ArrayList<E>();

        for(E k:relationMap.keySet()) {

            gragh.add(k);

        }

        int visit[]=new int[gragh.size()];

        Map<E, Integer> map=new HashMap<E, Integer>();

        for(int i=0;i<gragh.size();i++) {

            map.put(gragh.get(i), i);

        }

        if(e1.equals(e2)) {

            return 0;

        }

        List<E> que=new ArrayList<E>();

        que.add(e1);

        while(!que.isEmpty()) {

            if(que.get(0).equals(e2)) {

                return visit[map.get(que.get(0))];

            }

            else {

                if(relationMap.get(que.get(0))==null) {

                    que.remove(0);

                    continue;

                }

                for(E k:relationMap.get(que.get(0)).keySet()) {

                    if(visit[map.get(k)]==0) {

                        visit[map.get(k)]=visit[map.get(que.get(0))]+1;

                        que.add(k);

                    }

                }

                que.remove(0);

            }

        }

        return -1;

    }

计算物理距离

利用余弦定理可以求得e1,e2的距离。

public double getPhysicalDistance (CircularOrbit<L,E> c, E e1, E e2) {

        double result;

        Map<E, Position> positionMap=c.getPositions();

        int r1=positionMap.get(e1).getR();

        int r2=positionMap.get(e2).getR();

        double bearing1=positionMap.get(e1).getBearing();

        double bearing2=positionMap.get(e2).getBearing();

        result=r1*r1+r2*r2-2*r1*r2*Math.cos(bearing2-bearing1);

        result=Math.sqrt(result);

        return result;

    }

 

求取轨道系统之间的差异

public class TrackDifference<L,E> {

    int id;

    int number;

    boolean flag=false;

    List<E> listA=new ArrayList<E>();

    List<E> listB=new ArrayList<E>();

    public TrackDifference(List<E> track1,List<E> track2,int id){

        this.id=id;

        int n1=track1.size();

        int n2=track2.size();

        this.number=n1-n2;

        List<E> lista=new ArrayList<E>();

        for(int i=0;i<track1.size();i++) {

            if(track1.get(i) instanceof Electron) {

                flag=true;

            }

            lista.add(track1.get(i));

        }

        List<E> listb=new ArrayList<E>();

        for(int i=0;i<track2.size();i++) {

            if(track2.get(i) instanceof Electron) {

                flag=true;

            }

            listb.add(track2.get(i));

        }

        lista.removeAll(track2);

        listb.removeAll(track1);

        this.listA=lista;

        this.listB=listb

    }

 

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

class MyPanel<L,E> extends JPanel{

    private static final long serialVersionUID = 1L;

    CircularOrbit<L, E> c;

    public MyPanel(CircularOrbit<L, E> c) {

        super();

        this.c = c;

    }

    public void paint(Graphics g){

        super.paint(g);

        //g.drawString(c.getCenter().toString(), 1000, 500);

        g.drawString(c.getCenter().toString(), 1000, 500);

        Map<E,Double> centralRelation=c.getCenterRelation();

        Map<E, Map<E, Double>> relationMap=c.getRelation();

        Map<E,Position> positionMap=c.getPositions();

        for(E k:centralRelation.keySet()) {

            if(positionMap.get(k)==null) {

                continue;

            }

            int r=positionMap.get(k).getR();

            double bearing=positionMap.get(k).getBearing();

            g.drawLine(1000,500,(int)(1000.0+50*r*Math.sin(bearing)), (int)(500.0+50*r*Math.cos(bearing)));

        }

        for(E k:relationMap.keySet()) {

            for(E j:relationMap.get(k).keySet()) {

                int r1=positionMap.get(k).getR();

                double bearing1=positionMap.get(k).getBearing();

                int r2=positionMap.get(j).getR();

                double bearing2=positionMap.get(j).getBearing();

                g.drawLine((int)(1000.0+50*r1*Math.sin(bearing1)), (int)(500.0+50*r1*Math.cos(bearing1)),(int)(1000.0+50*r2*Math.sin(bearing2)), (int)(500.0+50*r2*Math.cos(bearing2)));

            }

        }

        for(Track k:c.getTracks().keySet()) {

            int r=k.getR();

            g.drawOval(1000-50*r, 500-50*r, 100*r, 100*r);

            double b=35.0;

            for(int j=0;j<c.getTracks().get(k).size();j++) {

                g.drawString(c.getTracks().get(k).get(j).toString(), (int)(1000.0+50*r*Math.sin((Math.PI/180.0)*b*j)), (int)(500.0+50*r*Math.cos((Math.PI/180.0)*b*j)));

            }

        }

       

    }

根据c画出图形,根据轨道的半径画同心圆,根据轨道中存的position在每个物体相应的位置标注,遍历关系Map,若两个人有关系,获取两个人的位置,在两个位置间连线。

    1. 设计模式应用

策略模式

定义了strategy类,TrackGameStrategy1和TrackGameStrategy2继承自Strategy类,Strategy:

public List<TrackGame> strategy=new ArrayList<TrackGame>();

   public TrackGame trackgame;

   //Strategy和TrackGame的交互,初始时,TrackGame,create()读取文件,构造出一个存放运动员的List,TrackGameStrategy1和TrackGameStrategy2利用该List对运动员进行一定处理,并构建TrackGame,加入到strategy,形成不同的方案

public class TrackGame extends ConcreteCircularOrbit<EmptyCentral, Player>{

    private int Gametype;

    private int NumOfTracks;

    private List<Player> players=new ArrayList<Player>();

   

    public int getGametype() {

        return Gametype;

    }

 

    public void setGametype(int gametype) {

        Gametype = gametype;

    }

 

    public int getNumOfTracks() {

        return NumOfTracks;

    }

 

    public void setNumOfTracks(int numOfTracks) {

        NumOfTracks = numOfTracks;

    }

    public void putout() {

        for(Player k:players) {

            System.out.println(k.toString());

        }

    }

    public int getRestNumber() {

        return this.players.size();

    }

public int nowGame=0;//当前组编号,用于GUI显示

TrackGameStrategy1:

public TrackGameStrategy1(TrackGame trackgame)//传入TrackGame,获取存放Player的List

public void init()//每次从List中取出若干个Player,构建TrackGame,加入到strategy中

public class TrackGameStrategy1 extends Strategy{

    public TrackGameStrategy1(TrackGame trackgame) {

        super();

        this.trackgame = trackgame;

    }

 

 

    public void init() {

        int now=1;

        while(trackgame.getRestNumber()>0) {

            System.out.println(""+now+":");

            trackgame.next();

            strategy.add(trackgame.clone(trackgame));

            trackgame.outPutOnTrack();

            now++;

        }

    }

   

}

TrackGameStrategy2:

public TrackGameStrategy2(TrackGame trackGame)//传入TrackGame,获取Player的List

public void sortList()//对Player的List进行排序

public void init()//按成绩从差到好编排,每次取出若干个Player,成绩好的放在内轨道,成绩差的放在外轨道。

public class TrackGameStrategy2 extends Strategy{

    public void sortList(){

        trackgame.getPlayers().sort(new Comparator<Player>() {

           

            @Override

            public int compare(Player o1, Player o2) {

                if(o1.getBestScore()>o2.getBestScore()) {

                    return -1;

                }

                return 1;

            }

        });

        trackgame.getPlayers().forEach(System.out::println);

    }

    public TrackGameStrategy2(TrackGame trackGame) {

        this.trackgame=trackGame;

    }

    public void init() {

        int now=1;

        while(trackgame.getRestNumber()>0) {

            System.out.println(""+now+":");

            trackgame.next2();

            strategy.add(trackgame.clone(trackgame));

            trackgame.outPutOnTrack();

            now++;

        }

    }

    public static void main(String[] args) {

        TrackGame trackgame=new TrackGame();

        trackgame.Creat("TrackGame.txt");

        TrackGameStrategy2 trackGameStrategy2=new TrackGameStrategy2(trackgame);

        trackGameStrategy2.sortList();

        trackGameStrategy2.init();

    }

}

    1. 应用设计与开发

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

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

      1. TrackGame

GUI可视化。

读取文件并建立轨道系统

增加轨道

删除轨道

增加物体

删除物体

计算熵值

编排不同比赛方案

改变运动员所在组和轨道

      1. AtomStructure

电子跃迁

       public boolean transit(Track t1, Track t2) {

              Electron electron=null;

              for(Track k:this.getTracks().keySet()) {

                     if(k.getR()==t1.getR()) {

                            if(this.getTracks().get(k).size()>0) {

                                   electron=this.getTracks().get(k).get(0);

                                   this.removeObjectOnTrack(electron, t1);

                                   this.addObjectToTrack(electron, t2);

                                   return true;

                            }

                     }

              }

              return false;

       }

      1. SocialNetworkCircle

计算逻辑距离

    public int centralDistance(Person e) {

        if(this.getCenterRelation().containsKey(e)) {

            return 1;

        }

        CircularOrbitAPIs<Person, Person> circularOrbitAPIs=new CircularOrbitAPIs<Person, Person>();

        int min=Integer.MAX_VALUE;

        for(Person j:this.getCenterRelation().keySet()) {

            if(circularOrbitAPIs.getLogicalDistance(this, j, e)<min

                    &&circularOrbitAPIs.getLogicalDistance(this, j, e)!=(-1)) {

                min=circularOrbitAPIs.getLogicalDistance(this, j, e);

            }

        }

        if(min==Integer.MAX_VALUE) {

            return -1;

        }

        else {

            return min+1;

        }

    }

    1. 应对应用面临的新变化

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

      1. TrackGame

在选择完策略放置的时候,每个轨道放4个

 

      1. StellarSystem
      2. AtomStructure

在中心物体类nucleus中加入两个list,分别用来存放质子和中子

      1. PersonalAppEcosystem
      2. SocialNetworkCircle

改变添加关系的方法,将原来的加双向关系改为只加单向关系,在添加边的时候不添加反向边即可

并且在用户输入的时候进行判断

    1. Git仓库结构

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

  1. 实验进度记录

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

每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。

不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。

日期

时间段

计划任务

实际完成情况

4-19

22:00-23:00

完成CircularOrbit接口,完成ConcreteCircularOrbit

完成

4-20

6:30-23:30

完善3个基础类并排掉BUG

完成

4-21

6:30-23:30

写完通用GUI

完成

4-27

6:30-23:30

写API和部分GUI

完成

4-28

6:30-23:30

写完3个具体的GUI

完成

5.1-5.5

全天

测试、排BUG、newChange

完成

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

遇到的难点

解决途径

 

GUI写不明白一直在报奇怪的错误

 

尽可能去规避可能的错误,借用了室友的GUI进行基础设计

  1. 实验过程中收获的经验、教训、感想
    1. 实验过程中收获的经验和教训
    2. 针对以下方面的感受
  1. 重新思考Lab2中的问题:面向ADT的编程和直接面向应用场景编程,你体会到二者有何差异?本实验设计的ADT在五个不同的应用场景下使用,你是否体会到复用的好处?
    复用会增加代码出错的几率,但是减少了很多代码量,增加了效率
  2. 重新思考Lab2中的问题:为ADT撰写复杂的specification, invariants, RI, AF,时刻注意ADT是否有rep exposure,这些工作的意义是什么?你是否愿意在以后的编程中坚持这么做?
    可以让别人更快的理解我的代码,增加沟通能力,方便查错
  3. 之前你将别人提供的API用于自己的程序开发中,本次实验你尝试着开发给别人使用的API,是否能够体会到其中的难处和乐趣?
    设计一个好的API的确不容易,首先,一个好的API应该可以应用于多种场景,而不同场景往往有不同的特性,怎样根据这些场景设计一个兼容的功能,具有很大挑战性。
  4. 在编程中使用设计模式,增加了很多类,但在复用和可维护性方面带来了收益。你如何看待设计模式?
    设计模式能增加代码的逻辑性和和后期处理的能力,是非常必要的。
  5. 你之前在使用其他软件时,应该体会过输入各种命令向系统发出指令。本次实验你开发了一个解析器,使用语法和正则表达式去解析输入文件并据此构造对象。你对语法驱动编程有何感受?
    这种方法实用性太差了,对公式的书写要求很高,出现一点错误就会导致整个出错
  6. Lab1和Lab2的大部分工作都不是从0开始,而是基于他人给出的设计方案和初始代码。本次实验是你完全从0开始进行ADT的设计并用OOP实现,经过三周之后,你感觉“设计ADT”的难度主要体现在哪些地方?你是如何克服的?
    主要难在思考的全面性,要不然后期还要重新写或者增加内容。每次要考虑周全,知道自己到底要干什么,到底需要什么样的功能。
  7. 你在完成本实验时,是否有参考Lab4和Lab5的实验手册?若有,你如何在本次实验中同时去考虑后续两个实验的要求的?
    没有看
  8. 关于本实验的工作量、难度、deadline。
    工作量真的很大,真的写不完。
  9. 到目前为止你对《软件构造》课程的评价。
    更加坚信了软件构造的重要性,它绝非向我们介绍某种语言,而是向我们传授一些软件开发所通用的方法,模式,策略,从而提升开发效率,在实验中逐渐理解了各种模式的优越性。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值