java项目手册构建考试中心的领域对象.doc

上传人:laozhun 文档编号:2387114 上传时间:2023-02-17 格式:DOC 页数:25 大小:607KB
返回 下载 相关 举报
java项目手册构建考试中心的领域对象.doc_第1页
第1页 / 共25页
java项目手册构建考试中心的领域对象.doc_第2页
第2页 / 共25页
java项目手册构建考试中心的领域对象.doc_第3页
第3页 / 共25页
java项目手册构建考试中心的领域对象.doc_第4页
第4页 / 共25页
java项目手册构建考试中心的领域对象.doc_第5页
第5页 / 共25页
点击查看更多>>
资源描述

《java项目手册构建考试中心的领域对象.doc》由会员分享,可在线阅读,更多相关《java项目手册构建考试中心的领域对象.doc(25页珍藏版)》请在三一办公上搜索。

1、第三章 构建考试中心的领域对象学习目标1. 如何从需求分析得到领域对象。2. 实现考试中心的领域对象。练习内容在面向对象分析设计中,功能的实现是由对象之间的交互而完成的。对象有状态、行为和标识,而且可以与需求的中具体事物对应。一般地,我们可以采用综合的方法从所有可能的需求文档中去寻找对象,比如,通过设计小组头脑风暴的方法从需求文档中找出名词作为候选对象,然后去掉那些重复、与需求无关、模糊、仅代表对象属性或操作的名词。总之,对象必须拥有一个明确的功能。想必读者对考试中心的功能非常了解,我们以选择题的考试为例来说明考试中心的领域模型。在实际考试中,考试有考题,选择题有选项,考题在考试中需要提供答案

2、,一个考试还有分数。由此,我们定义出与实际考试中相对应的对象,当我们用类图来描述这些实际考试中的基本概念时,大家可以看到类以及类与类之间关系确实能在很大程度上来表示需求,如:考试中心有考试,考试由考题组成等,这正是所谓“领域模型”的来由,它是对需求进行建模的技术之一,目的是提取需求中的基本概念。1. Customer(客户):参加考试的用户。2. Profile(用户概要):保存用户密码。3. Test(考试):考试4. Question(试题):考试的试题(考虑为选择题)。5. QChoice(选择题的选项):选项。6. Answer(答案):考题答案7. Score(得分):分数这些类的主

3、要属性和方法如下(省略了setter和getter方法):1. Customer类类名Customer关联类Profile属性name客户姓名email电子邮件phone电话addrCountry国家(地址)addrProvince省或市(地址)addrStreet街道或村(地址)postcode邮政编码方法login登录update更新客户信息2. Profile类类名Profile关联类属性userId用户id(系统唯一)password口令方法authenticate认证登录的用户是否为系统已设置的用户Update更新密码3. Test类类名Test关联类Question,Score属性

4、name考试名称description考试描述numQuestion考试由多少道题组成timeLimitMin考试时间pass考试是否通过fixedScore考试的分值score考试的得分方法produceTest初始化开始,从题库中提取试题addQuestion为考试增加一道试题computeScore计算考试的得分computePass计算考试是否通过4. Question类类名Question关联类QChoice属性name试题描述rightAnswer正确答案answer答案fixedScore试题分值score试题得分diff试题难度usedCount试题的使用次数enabled试题

5、是否还可以使用方法addChoice(QChoice)在试题中增加一个选项5. QChoice类类名QChoice属性name选择题选项isCorrect是否为正确选项6. Answer类类名Answer关联类属性txtAnswer文本答案right答案是否正确方法computeAnswer(Answer)根据试题的参考答案判断答案是否正确7. Score类类名Score属性score分数scoreDesc分数描述根据上述分析,得到如下类图,注意,类图省略了属性和方法。考试中心类图让我们根据上述分析开始编写代码。练习提示第一步 新建项目1. 在Eclipse中新建Java项目:fansoft_

6、testcenter_model_first。第二步 编写领域对象面对上面的类图,我们应该从哪个类开始编码呢?显然,我们可以从最独立、不依赖于其他类的类开始编码,这样,我们可以编写一个类就编译一个类,在上面的类图中,编写代码的顺序是:Profile,Customer,Qchoice,Score,Answer,Question,Test。为什么需要Profile类呢?一般地,我们应将有关客户的敏感信息,如密码,与非敏感信息分离开,敏感信息一般还需要加密处理,防止泄露,在此,我们暂时忽略有关安全的处理。这些类属于问题领域对象,可以将它们置入同一个包中,如果领域对象众多,可以细分成多个领域对象的包,

7、按惯例,我们命名这个包为:org.fangsoft.testcenter.model。1. 创建org.fangsoft.testcenter.model包。(读者如果忘了如何在Eclipse中创建项目,请参考前一章)。2. 创建Profile类。a) 创建Proflie类。在org.fangsoft.testcenter.model包中创建Profile类。b) 定义Profile类的属性:userId,password,存放Profile数据的一个静态数组profiles,注意,属性一般都定义私有,如下面代码:1private String userId;2private String p

8、assword;3private static Profile profiles;c) 为属性定义getter和setter的方法。在Eclipse的代码编辑器中用鼠标右键点击,选择Source,点击Generate Getters and Setters,选择Select All,其他选项默认,点击Ok完成。看看新生成了哪些代码?(可使用Eclipse提供的方法来创建这些Getter和Setter方法,参考Profile类的说明,读者请注意,在后面的练习中,我们将省略这些Getter和Setter方法的说明,如果用到这些方法,读者可以自行编写这些方法),代码如下:在Eclipse中生成Get

9、ter和Setter方法1public static Profile getProfiles() 2return profiles;34public static void setProfiles(Profile profiles) 5Profile.profiles = profiles;67public String getPassword() 8return password;910public void setPassword(String password) 11this.password = password;1213public String getUserId() 14retu

10、rn userId;1516public void setUserId(String userId) 17this.userId = userId;1819public static Profile getProfiles() 20return profiles;2122public static void setProfiles(Profile profiles) 23Profile.profiles = profiles;2425public String getPassword() 26return password;2728public void setPassword(String

11、password) 29this.password = password;3031public String getUserId() 32return userId;3334public void setUserId(String userId) 35this.userId = userId;36d) 定义构造函数。Java默认有一个不带参数的构造函数,当我们定义一个新的构造函数后,默认的构造函数就不存在了。构造函数由new关键词调用,一般用于初始化对象。在Eclipse代码编辑器中用鼠标右键点击,选择Source,点击Generate Constructor using Fields,选择所

12、有属性,点击OK。在Eclipse生成构造函数1public Profile(String userId,String password)2setUserId(userId);3setPassword(password);4e) 定义authenticate方法。我们假定Profile的数据保存在静态数组profiles中,登录认证的数据需要与profiles中的数据比较,若一致,登录成功,authenticate方法的代码如下:1public static boolean authenticate(String userId,String password)2boolean isAuthen

13、ticate=false;3int num=profiles.length;4Profile profile;5for(int i=0;inum;i+)6profile=profilesi;7if(profile.getUserId().equals(userId) & 8 profile.getPassword().equals(password)9isAuthenticate=true;10break;111213return isAuthenticate;14f) 定义update方法。客户可以更改密码。代码如下:1public void update(String password)2

14、if(!this.password.equals(password)3this.password=password;43. 创建Customer类。a) 类似Profile类的创建,在org.fangsoft.testcenter.model包中创建Customer类,我们以Customer的email为客户的Id,因为email本身就是唯一的,在实际应用中,我们也可以采用这种做法。b) 根据上述说明,定义Customer的属性以及Getters和Setters方法,数组customers保存Customer的数据,每一个Customer都有一个Profile,为此,定义关联属性profile

15、。1private Profile profile;2private String name;3private String email;4private String addrCountry;5private String addrProvince;6private String addrCity;7private String addrStreet;8private String postcode;9private String phone;10private static Customer customers;/用于存储当前客户c) 定义Customer的构造函数,为了使用方便,我们可以

16、定义多个重载(overloading)的构造函数,一般先定义参数最多的构造函数,再用它来定义参数较少的构造函数,调用参数周全的构造函数。重载方法都可以采用这样的方法来定义。(读者可以使用在Profile类中创建构造函数的方法)。1public Customer(String name,String password,String email,2String addrCountry,String addrProvince,String addrCity,3String addrStreet,String postcode,String phone)4setName(name);5setEmail

17、(email);6setAddrCountry(addrCountry);7setAddrProvince(addrProvince);8setAddrCity(addrCity);9setAddrStreet(addrStreet);10setPostcode(postcode);11setPhone(phone);12profile=new Profile(email,password);1314public Customer(String name,String password,String email)15this(name,password,email,null,null,null

18、,null,null, null);1617public Customer(String name,String password,String email,String phone)18this(name,password,email,null,null,null,null,null, phone);192021public Customer(String email,String password)22this(null,password,email,null,null,null,null,null,null);23d) 定义update方法。客户可以修改有关本身的信息。1public v

19、oid update(String name,String password,2String addrCountry,String addrProvince,String addrCity,3String addrStreet,String postcode,String phone )4setName(name);5setAddrCountry(addrCountry);6setAddrProvince(addrProvince);7setAddrCity(addrCity);8setAddrStreet(addrStreet);9setPostcode(postcode);10setPho

20、ne(phone);11profile.update(password);12e) 定义login方法。用户的敏感信息保存在Profile中,客户登录时只需要调用Profile的authenticate方法,代码如下:1public static boolean login(String userId,String password)2return Profile.authenticate(userId,password);3f) 我们假定Customer的数据保存在一个CUSTOMER_DATA的二维数组中,一行代表一个Customer,代码如下:1public static String

21、CUSTOMER_DATA=23bill,/name4fangsoft,/password5fangsoft.org,/email6china,beijing,beijing,beijing,/address7100081,/postcode813910797448/phone9,1011fangsoft,12fangsoft,13fangsoft.java,14china,peking,peking,peking,15100081,16139107974481718;g) 根据CUSTOMER_DATA数组的数据我们可以构造出Customer对象,保存在customers数组中,为此,定义了

22、produceCustomer方法,代码如下所示:1public static Customer produceCustomer()2int numCustomer=CUSTOMER_DATA.length;3customers=new CustomernumCustomer;4Profile profiles=new ProfilenumCustomer;5for(int num=0;numnumCustomer;num+)6String custData=CUSTOMER_DATAnum;7Customer customer=new Customer(custData0,8 custDat

23、a1,9custData2,10custData3,11 custData4,12custData5,13 custData6,14custData7,15 custData816 );17customersnum=customer;18profilesnum=customer.getProfile();1920Profile.setProfiles(profiles);/注意在这里初始化了Profile的数据21return customers;224. 创建考试试题选项QChoice类。a) 在org.fangsoft.testcenter.model包中创建QChoice类,定义属性na

24、me,correct以及其相应的Getter和Setter方法。1private String name=;/选项说明2private boolean isCorrect=false;/ 是否为正确选项b) 定义QChoice类的构造函数:1public QChoice(String name,boolean isCorrect)2this.name=name;3this.isCorrect=isCorrect;4c) 覆盖Object类的toString()方法。1public String toString()/用于显示2return name;35. 创建Score类。a) 在org.f

25、angsoft.testcenter.model包中创建Score类,定义如下构造函数和属性(请读者加上属性相应的Getter和Setter方法):1private float score=1;2private String scoreDesc=;3public Score(float score, String scoreDesc) 4super();5this.score = score;6this.scoreDesc = scoreDesc;7b) 定义add方法,代码如下:1public Score add(Score score) 2if(score!=null)3this.scor

26、e+=score.getScore();45return this;6c) 定义decrease方法,代码如下:1public Score decrease(Score score) 2if(score!=null)3this.score-=score.getScore();45return this;66. 创建Answer类。a) 在org.fangsoft.testcenter.model包中创建Answer类,定义如下属性以及属性相应的Getter和Setter方法。1public static final int RIGHT=1;/答案正确2public static final i

27、nt WRONG=0; /答案错误3public static final int UNKNOW=-1; /答案未知4private String txtAnswer;/文本答案5private int right=UNKNOW;/答案初始为未知6public Answer(String txtAnswer, int right, Question question) /构造函数7super();8this.txtAnswer = txtAnswer;9this.right = right;10if(question!=null)question.setAnswer(this);11b) 定义

28、computeAnswer(Answer rightAnswer)方法,选择题的答案与正确答案比较时,选项序号的顺序可能与正确答案顺序不一致,但应判断答案为正确,比如:正确答案是“abc”,答案如果是“cab”也应是正确答案。读者有更好的算法来实现此功能吗?1public int computeAnswer(Answer rightAnswer) 2int result=Answer.UNKNOW;3if(rightAnswer=null) return result;4String answer=getTxtAnswer();5String right=rightAnswer.getTxtA

29、nswer();6if(answer=null | right=null)return result;7char answers=answer.toCharArray();8char rights=right.toCharArray();9Arrays.sort(answers);/排序10Arrays.sort(rights);/排序11if(Arrays.equals(answers,rights)/排序后比较12result=Answer.RIGHT;13else14result=Answer.WRONG;1516setRight(result);17return result;187.

30、 创建Question类。a) 在org.fangsoft.testcenter.model包中创建Question类,定义如下属性以及属性相应的Getter和Setter方法。1private Answer answer;/考试时参考人员的答案2private Answer rightAnswer;/试题的正确答案3private String name;/试题名称4private int diff=3;/1,2,3,4,5/试题难度5private int usedCount=0;/试题使用次数计数6private boolean enabled=true;/试题是否可以使用7privat

31、e Score score; 8private Score fixedScore=new Score(1f,”); /试题分数,默认为1分9private QChoice choices;/试题选项10private int counter=0;/计数器b) 创建Question类的构造函数,为使用方便,重载构造函数:1public Question()/构造函数2public Question(String name, int diff,boolean enabled) 3setName(name);4setDiff(diff);5setEnabled(enabled);6c) 定义addC

32、hoice方法,将选项加入到Question对象中,因为采用数组choices来保存试题的选项,所以定义了一个计数器变量counter,代码如下:1public void addChoice(QChoice choice)2choicescounter+=choice;38. 创建Test类。a) 在org.fangsoft.testcenter.model包中创建Test类,定义如下属性以及相应的Getter和Setter方法。1private String name;/考试名称2private String description;/考试描述3private int numQuestion

33、;/考试的试题个数4private int timeLimitMin;/考试时间,以分钟计5private Score score;/考试得分6private Score fixedScore;/考试的分值7private int pass=UNKNOW;/考试是否通过,默认未知8public static final int PASS=1; /考试通过9public static final int FAIL=0;/考试不通过10public static final int UNKNOW=-1;/考试是否通过未知b) 定义Test的构造函数。1public Test(String name

34、,int numQuestion,2int timeLimitMin ,String description,String scoreValue)3this.name=name;4this.description=description;5this.numQuestion=numQuestion;6this.timeLimitMin=timeLimitMin;7questions=new QuestionnumQuestion;8float f=0f;9try10f=Float.parseFloat(scoreValue);11catch(Exception ex)12this.setFixe

35、dScore(new Score(f,);1314public Test()15this(,0,0,);16c) 定义将试题加入考试的方法addQuestion,得到试题的方法getQuestions,以及得到所有试题的方法getQuestions,试题保存在数组questions中。1private int counter=0;2public void addQuestion(Question question)3questionscounter+=question;45public Question getQuestions(int index)6return questionsindex

36、;78public Question getQuestions()9return questions;10d) 我们先假定试题数据保存在一个二维数组EXAM_QUESTION_LIB中,其中以“#”开头的选项为正确选项,第一行为考试描述,其他行是试题和选项描述,代码如下:1private static final String EXAM_QUESTION_LIB=2/test属性:name , numQuestion , timeLimitMin , description,score3 java知识测试,45,5 10,6 www.fangsoft.org的java知识测试,7 108 ,9

37、10 /Question属性:diff,usedCount,enabled11121,0,true,13/Question属性:name14有关java语言论述正确是?,15/QChoice16#它是一门编程语言,17#它是一个平台,18#它是跨平台的,19#它是面向对象的20,21221,0,true,23Java学习常可以参考的网站有?,24/QChoice25#,26#,27#28#www.fangsoft.org29,303132331,0,true,34如果一个属性用private声明,下面论述正确的是?,35不可变,36同步(synchronized),37#封装,38代表is-a

38、关系39,40411,0,true,42有关语句int a = 4,5,2, 8,1; System.out.println(a22 + a11); +43下面论述正确的是?,44编译失败,45编译成功,程序输出5,46编译成功,程序输出1 4,47#编译成功,运行时报告异常48,49501,0,true,51有关hasa关系论述正确是?(选择两个答案),52#表示一种组合关系,53#表示一种关联关系,54表示一种继承关系,55表示一种实现关系5657;e) 定义一个字符串常量“#”:Public static final String RIGHT_CHOICE=#;f) 定义computeS

39、core方法,计算考试的得分1public Score computeScore() 2Score testScore=new Score(0,);3if(questions!=null)4int size=questions.length;5for(int i=0;isize;i+)6Question q=questionsi;7if(q.getAnswer().isRight()=Answer.RIGHT)8testScore.add(q.getScore();91011setScore(testScore);12return testScore;13g) 定义computePass方法,

40、判断考试是否通过。我们假定答对所有70%的试题为通过考试。1public int computePass() 2int result=Test.UNKNOW;3Question questions=getQuestions();4if(questions=null)return result;5int size=questions.length;6int rightAnswercount=0;7for(int i=0;isize;i+)8Question q=questionsi;9if(q.getAnswer().isRight()=Answer.RIGHT)rightAnswercount+;1011

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号