今天分享一套针对《软件工程与计算》这本书的真题案例,有关《软件工程与计算》23章内容的重点知识整理,已经总结在了博客专栏中,有需要的自行阅读:
《软件工程与计算》啃书总结https://blog.csdn.net/jsl123x/category_12468792.html?spm=1001.2014.3001.5482
总的来说,干货满满。
目录
一.名词解释
1.软件工程
2.软件演化生命周期模型
3.螺旋模型
二.代码评注及修改
1.对软件设计模式原则的甄别
2.有关耦合种类的辨析
3.有关需求类型的辨析
4.有关测试用例的设计
5.有关人机交互设计的内容
6.修改代码的设计
按照风险解决的方式来组织软件开发活动~
a.A同学开发了一个手机应用,准备投放到 Apple Appstroe 和 Google Play 市场中去,下面是他应用的部分关于应用描述的代码,请分析其设计是否合理,是否违反某些设计原则,是否能够应用某种设计模式来重构。
class Application { prative String applicatioName; prative float avarageRate; prative ArrayList
newFeatureItems = new ArrayList (); String getDescriptionForiOS(){ StringBuffer result = new StringBuffer(); result.append("This is "+ applicatioName + " for iOS platform\n"); for(int i =0; i< newFeatureItems.size(); i++){ result.append(newFeatureItems.get(i).getDescription()); } result.append("Avarage Rate from App Store\n"); result.append(String.valueOf(avarageRate)); return result.toString(); } String getDescriptionForAndroid(){ StringBuffer result = new StringBuffer(); result.append("This is "+ applicatioName + " for Android platform\n"); for(int i =0; i< newFeatureItems.size(); i++){ result.append(newFeatureItems.get(i).getDescription()); } result.append("Avarage Rate from Google Play\n"); result.append(String.valueOf(avarageRate)); return result.toString(); } } 1 ) 指出违反的原则,请解释该原则,并给出修改后的代码首先,插播一下有关 迪米特法则和 开闭原则的知识:软件设计模式原则(一)迪米特法则软件设计模式原则(二)开闭原则
- 违背开闭原则,当IOS亦或Android中任何一个发生变更时,都会导致另一方也被修改(因为在同一个类中,无论是否变更都算发生修改),所有应该将两个逻辑上并立的代码分开封装,并抽象一个统一的接口~
- 违反迪米特法则,for循环中出现隐式方法,所以应该使用迭代器访问集合对象,减少与其他类的交互
改进后的代码如下:
2) 解释该设计模式,写出应用该设计模式后的代码可以采用策略模式重构,改进后的代码如下:
b.B同学开发了一个影片出租店用的程序,其中需要计算客户的积分。如果电影是新发布的电影并且租用的时间超过 1 天,则可以得到 2 点积分,否则是 1 点积分。
1 ) 请画出下列代码设计的顺序图。2 ) 指出其是否违反某些设计原则,解释这些原则customer与rental和movie都进行了交互,所以违反了迪米特原则——迪米特原则要求,一个软件实体应该尽可能少地与其他实体发生相互作用~3 ) 对其代码进行修改,写出修改之后的代码并画出修改之后的顺序图。
c.
数据结构栈有四个功能:压栈、弹栈、得到栈的大小、得到栈是否为空。 C 同学使用继承如下设计了栈。
复习指路:
软件工程与计算总结(十三)详细设计中的模块化与信息隐藏https://jslhyh32.blog.csdn.net/article/details/133841782
B同学写出如下代码:
1) validate_request 方法和 valid_month 方法之间是哪种类型的耦合,如何修改?
属于印记耦合,因为共享了数据结构【date】,修改这种类型,只需要将重合部分的字段设置为公有即可~
void validate_request(input_form i){ if(!valid_string(i.name)){ error_message(“Invalid name”); } if(!valid_month(i.date.month)){ error_message(“Invalid month”); } } int valid_month(int month){ return d.month >=1 && d.month<=12; }
2)C同学对代码做出了如下的修改,validate_request 方法和 valid 方法之间是哪种类型的耦合,如何修改?
很明显,valid方法的结果作为validrequest中分支结构用到的参数,这属于控制耦合的范畴~
修改后,只需要根据后两个方法的返回值即可,而不需要人为地根据方法内部的逻辑设置参数~
(注:这是一个难点!)
复习指路:
软件工程与计算总结(五)软件需求基础https://jslhyh32.blog.csdn.net/article/details/133579557
有关需求的分类,可以参考上文中的模式,这里简单给出一个样例:
- 业务、用户、系统级需求是按照层次性来划分的需求~
- 而功能需求和(2)小问中的需求都属于软件需求~
假设需要你想出常见 ATM 机的需求:
答案统一给出如下:
复习指路:
软件工程与计算总结(十九)软件测试https://jslhyh32.blog.csdn.net/article/details/133915874
插播一个科普:Object类型1.Object 类:位于 java.lang 包中的类(java.lang包中的内容自动导入);
2.Object 是每个类的父类,直接父类或者是间接的父类;
3.Object 类型的引用可以存储任意类型的对象;
4.Ovject 类中的方法是每个类都默认的功能方法。
首先,这里是在进行功能测试,所以肯定要选择黑盒测试,至于是等价类划分还是边界值分析都无妨~这里使用等价类划分编写测试用例:不难看出,上面的方法只有输入,而下面的方法只有输出~因此可以采用一次输入一次输出的方式来设计
详细内容参考:软件工程与计算总结(十一)人机交互设计
答案:
优点:界面简洁、良好的导航栏、及时的用户操作反馈
原则(最后两个好像不在总结(十一)里面,关注一下):
- 简洁设计:不要使用太大的菜单,不要在一个窗口中表现过多的信息类别,不要在一个表单中使用太多的颜色和字体作为线索
- 一致性设计:遵循了用户已有的精神模型
- 低出错率设计:避免用户操作可能引起的错误,并提供简洁的指导帮助用户消除错误
- 易记性设计:减少用户记忆负担
- 导航:停用一个很好的完成任务的入口
- 反馈:提示用户交互行为的结果,但不打断用户工作的意识流
- 不暴露软件系统内部构造机制
- 协作式设计:调整计算机因素以更好地适应并帮助用户的设计方式
原代码:
tax = 0.
if (taxable_income == 0) goto EXIT;
if (taxable_income > 10000) tax = tax + 1000;
else{ tax = tax + .10*taxable_income;
goto EXIT;
}
if (taxable_income > 20000) tax = tax + 1200;
else{ tax = tax + .12*(taxable_income-10000):
goto EXIT;
}
if (taxable_income > 30000) tax = tax + 1500;
else{ tax = tax + .15*(taxable_income-20000);
goto EXIT;
}
if (taxable_income < 40000){
tax = tax + .18*(taxable_income-30000);
goto EXIT;
}
else
tax = tax + 1800. + .20*(taxable_income-40000);
EXIT;
这道题解法很多,有关代码设计的要点,大家可以看如下这篇博文:
软件工程与计算总结(十八)代码设计https://jslhyh32.blog.csdn.net/article/details/133895023
博主给出的解法如下,答案不唯一,本质上是利用一个循环的辗转相减法,这样可以避免分支语句过多:
int count(int income)
{
int tax=0;
float ratio[5]={0.1,0.12,0.15,0.18,0.2};
for(int i=4;i>=0;i--) //从税率最高的部分开始计算,依次递减
{
int temp=0;
temp=income-10000*i;
if(temp>=10000)
temp=10000; // 忽略已经计算过的部分
cout<