java项目手册构建考试中心的领域对象_第1页
java项目手册构建考试中心的领域对象_第2页
java项目手册构建考试中心的领域对象_第3页
java项目手册构建考试中心的领域对象_第4页
java项目手册构建考试中心的领域对象_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

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

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

3、re(得分):分数这些类的主要属性和方法如下(省略了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关联类qu

4、estion,score属性name考试名称description考试描述numquestion考试由多少道题组成timelimitmin考试时间pass考试是否通过fixedscore考试的分值score考试的得分方法producetest初始化开始,从题库中提取试题addquestion为考试增加一道试题computescore计算考试的得分computepass计算考试是否通过4. question类类名question关联类qchoice属性name试题描述rightanswer正确答案answer答案fixedscore试题分值score试题得分diff试题难度usedcount试题

5、的使用次数enabled试题是否还可以使用方法addchoice(qchoice)在试题中增加一个选项5. qchoice类类名qchoice属性name选择题选项iscorrect是否为正确选项6. answer类类名answer关联类属性txtanswer文本答案right答案是否正确方法computeanswer(answer)根据试题的参考答案判断答案是否正确7. score类类名score属性score分数scoredesc分数描述根据上述分析,得到如下类图,注意,类图省略了属性和方法。考试中心类图让我们根据上述分析开始编写代码。练习提示第一步 新建项目1. 在eclipse中新建j

6、ava项目:fansoft_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;2pr

8、ivate string password;3private static profile profiles;c) 为属性定义getter和setter的方法。在eclipse的代码编辑器中用鼠标右键点击,选择source,点击generate getters and setters,选择select all,其他选项默认,点击ok完成。看看新生成了哪些代码?(可使用eclipse提供的方法来创建这些getter和setter方法,参考profile类的说明,读者请注意,在后面的练习中,我们将省略这些getter和setter方法的说明,如果用到这些方法,读者可以自行编写这些方法),代码如下:

9、在eclipse中生成getter和setter方法1public static profile getprofiles() 2return profiles;34public static void setprofiles(profile profiles) 5pfiles = profiles;67public string getpassword() 8return password;910public void setpassword(string password) 11this.password = password;1213public string getu

10、serid() 14return userid;1516public void setuserid(string userid) 17this.userid = userid;1819public static profile getprofiles() 20return profiles;2122public static void setprofiles(profile profiles) 23pfiles = profiles;2425public string getpassword() 26return password;2728public void setpa

11、ssword(string password) 29this.password = password;3031public string getuserid() 32return userid;3334public void setuserid(string userid) 35this.userid = userid;36d) 定义构造函数。java默认有一个不带参数的构造函数,当我们定义一个新的构造函数后,默认的构造函数就不存在了。构造函数由new关键词调用,一般用于初始化对象。在eclipse代码编辑器中用鼠标右键点击,选择source,点击generate constructor us

12、ing fields,选择所有属性,点击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)2bo

13、olean isauthenticate=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(str

14、ing password)2if(!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,为此

15、,定义关联属性profile。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(n

17、ame);5setemail(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,

18、null,null,null,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方法。客户可以修改有关本

19、身的信息。1public void 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(post

20、code);10setphone(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

21、static string customer_data=23bill,/name4fangsoft,/,/email6china,beijing,beijing,beijing,/address7100081,/postcode813910797448/phone9,1011fangsoft,12fangsoft,13fangsoft.java,14china,peking,peking,peking,15100081,16139107974481718;g) 根据customer_data数组的数据我们可以构造出customer对象,保存在custo

22、mers数组中,为此,定义了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(custd

23、ata0,8 custdata1,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包中创建q

24、choice类,定义属性name,correct以及其相应的getter和setter方法。1private string name=;/选项说明2private boolean iscorrect=false;/ 是否为正确选项b) 定义qchoice类的构造函数:1public qchoice(string name,boolean iscorrect)2=name;3this.iscorrect=iscorrect;4c) 覆盖object类的tostring()方法。1public string tostring()/用于显示2return name;35. 创建sc

25、ore类。a) 在org.fangsoft.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!=n

26、ull)3this.score+=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

27、static final int 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

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

29、answer.gettxtanswer();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);17retu

30、rn result;187. 创建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;/试

31、题是否可以使用7private 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(enabl

32、ed);6c) 定义addchoice方法,将选项加入到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 i

33、nt numquestion;/考试的试题个数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 te

34、st(string name,int numquestion,2int timelimitmin ,string description,string scorevalue)3=name;4this.description=description;5this.numquestion=numquestion;6this.timelimitmin=timelimitmin;7questions=new questionnumquestion;8float f=0f;9try10f=float.parsefloat(scorevalue);11catch(exception ex)

35、12this.setfixedscore(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

36、questionsindex;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 的jav

37、a知识测试,7 108 ,910 /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#29,303132331,0,true,34如果一个属性用private声明,下面论述正确的是?,35不可变,36同步(synchronized),

38、37#封装,38代表is-a关系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=#

39、;f) 定义computescore方法,计算考试的得分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) 定义

40、computepass方法,判断考试是否通过。我们假定答对所有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;i=70*size)12result=test.pass;13else14result=test.fail;1516setpass(result);1

41、7return result;18h) 考试的信息保存在exam_question_lib数组中,在程序运行的时候,根据这些数据,我们需要生成test,question,qchoice对象,由此定义了初始化考试数据的方法producetest,代码如下:1public static test producetest()2string testdata=exam_question_lib0;3test test=new test(testdata0,4 integer.parseint(testdata1),5 integer.parseint(testdata2),6 testdata3,7

42、testdata48 );9int numofquestion=exam_question_lib.length;10for(int numq=1;numqnumofquestion;numq+)11string questiondata=exam_question_libnumq;12question question=new question(questiondata3,13 integer.parseint(questiondata0),14 boolean.getboolean(questiondata1)15);16/choice17answer rightanswer=new an

43、swer(question);18int numofchoice=questiondata.length-4;19qchoice choices=new qchoicenumofchoice;20stringbuffer right=new stringbuffer();21for(int num=4;numquestiondata.length;num+)22string choicetext=questiondatanum;23boolean rightchoice=false;24if (choicetext.indexof(right_choice)=0)25choicetext=ch

44、oicetext.substring(1);26rightchoice=true;27right.append(num-3);2829choicesnum-4=new qchoice(choicetext,rightchoice);3031rightanswer.settxtanswer(right.tostring();32question.setrightanswer(rightanswer);33question.setchoices(choices);34test.addquestion(question);3536return test;37第三步 编写测试领域对象的类1. 编写co

45、nsole类。我们编写好profile,customer,qchoice,answer,score,question,test代码后,它们是否能正确运行呢?让我们开始实现考试中心testcenter类,它是一个主类(main),程序从testcenter开始运行。简单起见,我们在标准控制台(windows的标准控制台就是dos窗口,运行cmd.exe)上可以实现这样一个流程:先登录,然后参加考试,考试完成后得到考试结果。由此,我们为在标准控制台上的操作归纳到一起,定义一个有关标准控制台上的操作类console,比如,提示客户回答“是否”的问题处理过程都是一样的,只是提示的问题的内容不一样而已,

46、所有的方法定义为静态方法。 a) console类不仅可以用在考试中心的应用程序中,还可以用在其他程序中,因此,为console类新建一个包org.fangsoft.util。b) 在org.fangsoft.util中新建console类。c) 定义console类所需的常量,有关输出的格式,请参见java api文档中的java.util.formatter类的说明,这是jdk1.5的新用法。注意,在java中常量的定义。一般地,常量定义为“public”,除非这些常量局限于一个类或包里使用。1public static final string q_format=%3s%n;/提示问题输

47、出格式2public static final string o_format=s%n;/提示问题选项输出格式3public static final string separator=. ;/序号与提示问题选项之间的分隔符4public static final string yes = y;/提示客户“是否”问题的回答5public static final string no = n;d) 定义console类的io输入(input)与输出(out)以及相应的setter和getter方法,默认初始值为标准控制台的标准输入和标准输出,windows的标准输入是键盘,标准输出是显示器。(i

48、o输入和输出将在后面的章节中学到,读者暂时可以忽略。)1private static bufferedreader input=new bufferedreader(new inputstreamreader(system.in);/输入2private static printstream out=system.out;/输出e) 定义格式化输出的output方法。这里用到了jdk1.5新增的特性格式化输出和可变参数,如果读者不熟悉,应参考jdk1.5的api文档中java.util.formatter类的说明。1public static void output(string format, object. msgs) 2out.printf(format, msgs);3i) 定义向非格式化输出的方法,重载o

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论