一、题目描述
某航空公司的会员积分系统(CFrequentFlyer)的主要功能描述如下:
乘客只要办理该航空公司的公员卡,即可成为普卡会员(Basic)。随着飞行里程数的积累,可以从普卡会员升级到银卡会员(Silver)或金卡会员(Gold)。非会员(NonMember)不能累积里程数。系统根据会员在本年度累积的里程数对会员等级进行调整。
普卡会员在累积的里程数若满25, 000英里但不足50, 000英里,则自动升级为银卡会员;若累积的里程数在50, 000英里以上,则自动升级为金卡会员。银卡会员累积的里程数若在50, 000英里以上,则自动升级为金卡会员。
非会员(NonMember)不打折,普卡会员(Basic)打9折,银卡会员(Silver)打8折,金卡会员(Gold)打6折。
现采用状态(State)模式实现上述场景,绘制类图(暂时不做,下次上机课再做)并编程模拟实现(本题根据软件设计师2018年下半年下午第5题(第6题)及2013年下半年下午第3题改编而成)。
要求:
-
使用C++、JAVA或C#语言编写,编程环境不限(如C++编写,可使用VC++2010学习版,安装包在“资料”的“安装包”文件夹中可以下载到,安装和使用教程请参见附录)。
-
初始里程数为0,状态为“非会员”。
-
CFrequentFlyer类中有3个成员函数:apply()函数办理会员卡(即将CFrequentFlyer对象的状态由“非会员”修改为“普卡会员”);travel()函数接收当次飞行的里程数和原价,根据当关会员等级输出打折后的价格并累积里程数调整会员等级;setState()函数设置CFrequentFlyer对象的状态。
-
在主函数中创建CFrequentFlyer类对象并测试相关功能,向用户显示必要的提示信息,测试数据可由使用者自己输入。
二、解答
我使用的是讲状态类设计成一个抽象类,让具体的状态类去继承这个抽象类,最后实现状态转换。
- 情景类的创建
package StatePattern.MemberPointsSystem;
public class CFrequentFlyer {
//创建状态
private Member MEMBER;
//创建私有成员变量,用来接收传进来的里程数和机票价格
private double mileage;
private double money;
//构造器
public CFrequentFlyer(double mileage,double money){
this.mileage = mileage;
this.money = money;
}
//get方法
public double getMileage() {
return mileage;
}
public double getMoney() {
return money;
}
//设置当前状态
public void setMember(Member member){
this.MEMBER = member;
this.MEMBER.setCurrentMember(this);
}
public void apply(){
this.MEMBER.apply();
}
public void travel(){
this.MEMBER.travel();
}
}
- 状态抽象类创建
package StatePattern.MemberPointsSystem;
public abstract class Member {
protected CFrequentFlyer cFrequentFlyer;
public void setCurrentMember(CFrequentFlyer cFrequentFlyer){
this.cFrequentFlyer = cFrequentFlyer;
}
public abstract void apply();
public abstract void travel();
}
- 各个状态实体类的实现
package StatePattern.MemberPointsSystem;
public class NonMember extends Member{
@Override
public void apply() {
//非会员成为会员需要办卡操作
cFrequentFlyer.setMember(new BasicMember());
System.out.println("恭喜您成为普通会员");
}
@Override
public void travel() {
System.out.println("非会员不打折!");
System.out.println(cFrequentFlyer.getMileage());
System.out.println(cFrequentFlyer.getMoney());
}
}
package StatePattern.MemberPointsSystem;
public class