软件结构体系实验作业一——使用状态模式模拟会员积分系统

状态模式实战

  • 一、题目描述
  • 二、解答

一、题目描述

某航空公司的会员积分系统(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题改编而成)。

要求:

  1. 使用C++、JAVA或C#语言编写,编程环境不限(如C++编写,可使用VC++2010学习版,安装包在“资料”的“安装包”文件夹中可以下载到,安装和使用教程请参见附录)。

  2. 初始里程数为0,状态为“非会员”。

  3. CFrequentFlyer类中有3个成员函数:apply()函数办理会员卡(即将CFrequentFlyer对象的状态由“非会员”修改为“普卡会员”);travel()函数接收当次飞行的里程数和原价,根据当关会员等级输出打折后的价格并累积里程数调整会员等级;setState()函数设置CFrequentFlyer对象的状态。

  4. 在主函数中创建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 BasicMember extends Member {

    double totalmile = 0;
    double discount = 0;

    @Override
    public void apply() {
        //普通会员可以升级
        if(totalmile < 50000 && totalmile >= 25000){
            cFrequentFlyer.setMember(new SilverMember());
            System.out.println("恭喜您升级成银卡会员!");
        }else if(totalmile >= 50000){
            cFrequentFlyer.setMember(new GoldMember());
            System.out.println("恭喜您升级成金卡会员!");
        }
    }

    @Override
    public void travel() {
        //这里是接收到了手动输入的里程数和机票钱
        //也可以把travel改成带参的函数进行实现
        totalmile = cFrequentFlyer.getMileage();
        discount = cFrequentFlyer.getMoney() * 0.9;
        System.out.println("普通会员机票打九折!");
        //输出里程数和钱
        System.out.println(totalmile);
        System.out.println(discount);
        //判断里程数积累后是否可以升级
        if( totalmile < 50000 && totalmile >= 25000){
            System.out.println("恭喜您行程累积超过25000,自动升级为银卡会员!");
            cFrequentFlyer.apply();
        }else if(totalmile >= 50000){
            System.out.println("恭喜您行程累计超过50000,自动升级为金卡会员!");
            cFrequentFlyer.apply();
        }
    }
}

package StatePattern.MemberPointsSystem;

public class SilverMember extends Member {

    @Override
    public void apply() {
        //银卡会员可以升级成金卡会员
        cFrequentFlyer.setMember(new GoldMember());
        System.out.println("恭喜您升级为金卡会员!");
    }

    @Override
    public void travel() {
        double totalmile = cFrequentFlyer.getMileage();
        double discount = cFrequentFlyer.getMoney() * 0.8;
        System.out.println("银卡会员机票打八折");
        System.out.println("累计行程" + totalmile +"英里");
        System.out.println("机票打折后价格:" + discount);
        if(totalmile >= 50000){
            System.out.println("恭喜您行程累计超过50000,自动升级为金卡会员!");
            cFrequentFlyer.apply();
        }
    }
}

package StatePattern.MemberPointsSystem;

public class GoldMember extends Member {

    @Override
    public void apply() {
        //金卡不用升级,撒也不写
    }

    @Override
    public void travel() {
        double totalmile = cFrequentFlyer.getMileage();
        double discount = cFrequentFlyer.getMoney() * 0.6;
        System.out.println("金卡会员机票打6折");
        System.out.println("累计行程" + totalmile +"英里");
        System.out.println("机票打折后价格:" + discount);
    }
}

  • 客户端
package StatePattern.MemberPointsSystem;
import java.util.Scanner;

public class StatepatternDemo01 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入旅程行程和机票原价:");
        CFrequentFlyer cFrequentFlyer = new CFrequentFlyer(scanner.nextDouble(),scanner.nextInt());
        cFrequentFlyer.setMember(new NonMember());
        //升级成普通会员
        cFrequentFlyer.apply();
        cFrequentFlyer.travel();
    }
}

  室友使用了将状态类设计成一个接口,让各个具体状态类去实现这个接口,然后实现状态的转换。

  • 情景类的创建
package work.copy;

public class CFrequentFlyer {
	private State state;
	private int milage = 0;// 里程数

	public int getMilage() {
		return milage;
	}

	public void setMilage(int milage) {
		this.milage = milage;
	}

	public CFrequentFlyer() {
		state = new NonMember();
	}

	// 办理会员卡
	public void apply() {
		this.state = new Basic();
	}

	// 状态转换
	public void setState(State state) {
		this.state = state;
	}

	public void travele(int milage, double price) {
		this.state.travel(milage, price);
	}
}

  • 状态抽象类创建
package work.copy;

public interface State {
	CFrequentFlyer cFlyer = new CFrequentFlyer();
	void travel(int milage,double price);//里程数
}

  • 各个状态实体类的实现
package work.copy;

public class NonMember implements State {

	@Override
	public void travel(int milage, double price) {
		System.out.println("您的里程数为"+milage);
		System.out.println("价格为"+price);
	}

}

package work.copy;

public class Basic implements State {
	@Override
	public void travel(int milage, double price) {
		if (milage>25000&&milage<=50000) {
			Silver silver = new Silver();
			cFlyer.setState(silver);
			silver.travel(milage, price);
		}else if (milage>50000) {
			Gold gold = new Gold();
			cFlyer.setState(gold);
			gold.travel(milage, price);
		}else if(milage<=25000&&milage>0){
			System.out.println("我是普卡");
			price = price*0.9;
			cFlyer.setMilage(cFlyer.getMilage()+milage);
			System.out.println("里程数是"+milage);
			System.out.println("价格是"+price);
		}else {
			System.out.println("抱歉,您的里程数有误!");
			System.out.println("请重新输入!");
		}
		

	}

}

package work.copy;


public class Silver implements State {

	@Override
	public void travel(int milage, double price) {
		if (milage>50000) {
			Gold gold = new Gold();
			cFlyer.setState(gold);
			
		}else {
			price = price*0.8;
			cFlyer.setMilage(cFlyer.getMilage()+milage);
			System.out.println("我是银卡");
			System.out.println("里程数是"+milage);
			System.out.println("价格是"+price);
		}
		
	}

}

package work.copy;

public class Gold implements State {

	@Override
	public void travel(int milage, double price) {
		price = price * 0.6;
		cFlyer.setMilage(cFlyer.getMilage()+milage);
		System.out.println("我是金卡");
		System.out.println("里程数是"+milage);
		System.out.println("价格是"+price);
	}

}

-客户端

package work.copy;

import java.util.Random;
import java.util.Scanner;

public class Test {
	public static void main(String[] args) {
		CFrequentFlyer cFlyer = new CFrequentFlyer();
		System.out.println("请问你需要升级会员吗?");
		System.out.println("0------不升级             1-------升级");
		Scanner scanner = new Scanner(System.in);
		
		boolean flag = true;
		while (flag) {
			switch (scanner.nextInt()) {
			case 0:
				flag = false;
				break;
			case 1:
				cFlyer.apply();
				System.out.println("恭喜你升级成功");
				flag = false;
				break;
			default:
				System.out.println("输入有误,请重试");
				flag = true;
			}
		}
		System.out.println("请输入你本次航行的里程数和价格:");
		int milage = scanner.nextInt();
		double price = scanner.nextDouble();
		cFlyer.travele(milage, price);
		
	}
}

  由于对题意的理解,有不同的差异,而且这道题没有唯一的答案,所以以上仅仅是记录,我的学习过程,嘿嘿,可能有的地方很愚蠢,但是也很可爱,我以后看一定会笑出声!

你可能感兴趣的:(设计模式,专业课,状态模式,设计模式,java)