黑马程序员---移动用户资费系统

---------------------- android培训java培训、期待与您交流! ----------------------


这个系统感觉东西比较多,所以比较麻烦,但是逻辑还是蛮清楚的
打电话 发短信 上网流量
都可以用一个计算公式
数据类型也都可以用int
套餐也都是同一种类型的


class Customer{
	//记录入网的时间
	private Calendar AccessCalendar;

	//这一串表示<通话分钟数,短信条数,流量KB>中<免费,超出免费的部分,总共>的数据
	private int FreeTalkMinute=0;
	private int FreeMessage=0;
	private int FreeNetFlow=0;
	private int ChargingTalkMinute=0;
	private int ChargingMessage=0;
	private int ChargingNetFlow=0;
	private int TotalTalkMinute=0;
	private int TotalMessage=0;
	private int TotalNetFlow=0;

	//电话,短信,上网的计费:
	private float TalkCost;
	private float MessageCost;
	private float NetFlowCost;

	//用户类型
	private CustomerType type;

	//这个月正在用的套餐和下个月的套餐
	private Packet thisMonthPacket;
	private Packet nextMonthPacket;

	//VIP无套餐的月租记录在这
	private int specialCost=0;

	//客户名字 方便查看log
	private String name;

	//构造指定类型的Customer	
	public Customer(CustomerType type,int count){
		this.type=type;
		if(type==CustomerType.NORMAL){
			thisMonthPacket=Packet.NORMAL_BASIC;
			nextMonthPacket=Packet.NORMAL_BASIC;
			name="普通客户"+count+"号";
		}else{
			thisMonthPacket=Packet.VIP_BASIC;
			nextMonthPacket=Packet.VIP_BASIC;
			name="VIP客户"+count+"号";
		}
		refreshState();
		AccessCalendar=Calendar.getInstance();

		//新入网用户赠送的免费的那堆东西
		if(type==CustomerType.NORMAL){
			FreeTalkMinute+=60;
			FreeMessage+=200;
			FreeNetFlow+=50000;
		}else{
			FreeTalkMinute+=200;
			FreeMessage+=200;
			FreeNetFlow+=100000;
		}
	}

	//随即构造一种类型的Customer
	public Customer(int count){
		this(Math.random()>0.5?CustomerType.NORMAL:CustomerType.VIP,count);
	}

	//改变套餐,下月生效,所以记录在nextMonthPacket这个变量里就行
	public void usePacket(Packet p){
		nextMonthPacket=p;
	}

	//月初时刷新用户的数据
	private void refreshState(){
		FreeTalkMinute=thisMonthPacket.getFreeTalkMinute();
		FreeMessage=thisMonthPacket.getFreeMessage();
		FreeNetFlow=thisMonthPacket.getFreeNetFlow();
		TalkCost=thisMonthPacket.getTalkCost();
		MessageCost=thisMonthPacket.getMessageCost();
		NetFlowCost=thisMonthPacket.getNetFlowCost();
		ChargingTalkMinute=0;
		ChargingMessage=0;
		ChargingNetFlow=0;
		TotalTalkMinute=0;
		TotalMessage=0;
		TotalNetFlow=0;
		specialCost=0;
	}

	//3种产生计费的动作:打电话,发短信,上网
	public void talk(int minute){
		TotalTalkMinute+=minute;
		if(FreeTalkMinute>minute)
			FreeTalkMinute-=minute;
		else{
			FreeTalkMinute=0;
			minute-=FreeTalkMinute;
			ChargingTalkMinute+=minute;
		}
	}
	public void message(int count){
		TotalMessage+=count;
		if(FreeMessage>count)
			FreeMessage-=count;
		else{
			FreeMessage=0;
			count-=FreeMessage;
			ChargingMessage+=count;
		}
	}
	public void netflow(int flow){
		TotalNetFlow+=flow;
		if(FreeNetFlow>flow)
			FreeNetFlow-=flow;
		else{
			FreeNetFlow=0;
			flow-=FreeNetFlow;
			ChargingNetFlow+=flow;
		}
	}

	//get方法 获取一些private变量
	public CustomerType getType(){
		return type;
	}
	public String getName() {
		return name;
	}
	public Packet getPacket(){
		return thisMonthPacket;
	}
	public void addSpecialCost(int cost){
		specialCost+=cost;
	}

	//新的一个月
	//将账单打印在一个文件,并更新套餐,数据等.
	public void nextMonth(){
		float totalCost=0;
		totalCost=thisMonthPacket.getCost()+ChargingTalkMinute*TalkCost+ChargingMessage*MessageCost+ChargingNetFlow*NetFlowCost+specialCost;
		totalCost=(int)(totalCost*10)/10.0f;
		StringBuilder s=new StringBuilder();
		String r=System.getProperty("line.separator");
		int year=MobilePhoneBillingSystem.currentDate.get(Calendar.YEAR);
		int month=MobilePhoneBillingSystem.currentDate.get(Calendar.MONTH);
		if(month==1){
			year-=1;
			month=12;
		}else{
			month--;
		}
		s.append(name);
		s.append(r);
		s.append(r);
		s.append(year);
		s.append("年 ");
		s.append(month);
		s.append("月   账单明细");
		s.append(r);
		s.append(r);
		s.append("总费用:\t\t");
		s.append(totalCost);
		s.append("\t元");
		s.append(r);
		s.append(r);
		s.append("套餐月租:\t");
		s.append(thisMonthPacket.getCost());
		s.append("\t元");
		s.append(r);
		s.append("通话分钟:\t");
		s.append(TotalTalkMinute);
		s.append("\t分钟");
		s.append(r);
		s.append("通话计费:\t");
		s.append((int)(ChargingTalkMinute*TalkCost*10)/10.0f);
		s.append("\t元");
		s.append(r);
		s.append("短信条数:\t");
		s.append(TotalMessage);
		s.append("\t条");
		s.append(r);
		s.append("短信计费:\t");
		s.append((int)(ChargingMessage*MessageCost*10)/10.0f);
		s.append("\t元");
		s.append(r);
		s.append("流量统计:\t");
		s.append(TotalNetFlow);
		s.append("\tKB");
		s.append(r);
		s.append("流量计费:\t");
		s.append((int)(ChargingNetFlow*NetFlowCost*10)/10.0f);
		s.append("\t元");
		s.append(r);
		s.append("其他费用:\t");
		s.append(specialCost);
		s.append("\t元");
		s.append(r);
		thisMonthPacket=nextMonthPacket;
		refreshState();
		MobilePhoneBillingSystem.createLogFile(s.toString(),"log\\user\\"+name,year+"年"+month+"月账单.txt");
	}
}

//然后定义一个套餐类
//因为题目中的套餐都是一种形式的
//就是有免费的部分,然后超出部分是新的计费价格
//无套餐也可以看成没有免费部分的套餐
//所以可以全定义成一种类型

class Packet{
	//月租
	private int cost=0;

	//3种操作的免费部分
	private int FreeTalkMinute=0;
	private int FreeMessage=0;
	private int FreeNetFlow=0;

	//3个计费价格
	private float TalkCost;
	private float MessageCost;
	private float NetFlowCost;

	//套餐名字 方便查看
	private String name;

	//静态成员变量
	public static Packet NORMAL_BASIC,NORMAL_SPECIAL,VIP_BASIC,VIP_SPECIALA,VIP_SPECIALB;
	private Packet(
			int cost,
			int FreeTalkMinute,
			int FreeMessage,
			int FreeNetFlow,
			float TalkCost,
			float MessageCost,
			float NetFlowCost,
			String name){
		this.cost=cost;
		this.FreeTalkMinute=FreeTalkMinute;
		this.FreeMessage=FreeMessage;
		this.FreeNetFlow=FreeNetFlow;
		this.TalkCost=TalkCost;
		this.MessageCost=MessageCost;
		this.NetFlowCost=NetFlowCost;
		this.name=name;
	}
	
	//注册各个套餐的数据
	static{
		NORMAL_BASIC=	new Packet(0,  0,   0,  0,     0.6f,0.1f,0.005f ,"普通无套餐");
		NORMAL_SPECIAL=	new Packet(20, 60,  200,50000, 0.5f,0.1f,0.003f ,"普通套餐①");
		VIP_BASIC=		new Packet(0,  0,   0,  0,     0.4f,0.1f,0.003f ,"VIP无套餐");
		VIP_SPECIALA=	new Packet(100,750, 200,100000,0.3f,0.1f,0.001f ,"VIP套餐①");
		VIP_SPECIALB=	new Packet(200,2000,500,300000,0.2f,0.1f,0.0005f,"VIP套餐②");
	}

	//一堆get方法
	public int getCost() {
		return cost;
	}
	public int getFreeTalkMinute() {
		return FreeTalkMinute;
	}
	public int getFreeMessage() {
		return FreeMessage;
	}
	public int getFreeNetFlow() {
		return FreeNetFlow;
	}
	public float getTalkCost() {
		return TalkCost;
	}
	public float getMessageCost() {
		return MessageCost;
	}
	public float getNetFlowCost() {
		return NetFlowCost;
	}
	public String getName(){
		return name;
	}
}

//枚举2种客户类型
enum CustomerType{
	NORMAL,VIP;
}

//然后就是main函数
//主要是通过随机数来模拟客户的一些操作:
//打电话,发短信,上网,改套餐

public class MobilePhoneBillingSystem {

	//记录模拟的当前时间
	public static Calendar currentDate;

	//每XX毫秒走一天
	private static int MillisPerDay=100;

	//所有的客户放在这个ArrayList中
	private static ArrayList<Customer> al;
	private static int[] randomNetFlow={50,100,200,500,1000};
	public static void main(String[] args) {
		
		currentDate=Calendar.getInstance();

		al=new ArrayList<Customer>();

		//15个普通客户
		for(int i=0;i<15;i++)
			al.add(new Customer(CustomerType.NORMAL,i));

		//5个VIP客户
		for(int i=0;i<5;i++)
			al.add(new Customer(CustomerType.VIP,i));

		//计时器 用来模拟时间流逝 和客户操作
		new Timer().schedule(new TimerTask(){
			@Override
			public void run() {

				//以一天为单位 加一天 
				currentDate.add(Calendar.DAY_OF_MONTH,1);
				StringBuilder s=new StringBuilder();
				String r=System.getProperty("line.separator");
				s.append(currentDate.get(Calendar.YEAR));
				s.append("年");
				s.append(currentDate.get(Calendar.MONTH));
				s.append("月");
				s.append(currentDate.get(Calendar.DAY_OF_MONTH));
				s.append("日");
				s.append(r);
				s.append(r);
				System.out.println(currentDate.get(Calendar.YEAR)+"年"+currentDate.get(Calendar.MONTH)+"月"+currentDate.get(Calendar.DAY_OF_MONTH)+"日");
				for(int i=0;i<al.size();i++){
					Customer c=al.get(i);
					
					//用户每天模拟进行一种操作
					int action=(int)(Math.random()*4);
					if(action==0){
						int minute=1+(int)(Math.random()*10);
						c.talk(minute);
						s.append(c.getName());
						s.append(" 拨打电话 ");
						s.append(minute);
						s.append("分钟");
						s.append(r);
					}
					else if(action==1){
						int count=1+(int)(Math.random()*10);
						c.message(count);
						s.append(c.getName());
						s.append(" 发送短信 ");
						s.append(count);
						s.append("条");
						s.append(r);
					}
					else if(action==2){
						int flow=randomNetFlow[(int)(Math.random()*randomNetFlow.length)];
						c.netflow(flow);
						s.append(c.getName());
						s.append(" 产生流量 ");
						s.append(flow);
						s.append("KB");
						s.append(r);
					}
					else{
						//do nothing
					}

					//小概率事件:更改套餐
					if(Math.random()<0.1){
						Packet packet=null;
						if(c.getType()==CustomerType.VIP){
							int p=(int)(Math.random()*3);
							if(p==0)
								packet=Packet.VIP_BASIC;
							else if(p==1)
								packet=Packet.VIP_SPECIALA;
							else
								packet=Packet.VIP_SPECIALB;
						}else{
							int p=(int)(Math.random()*2);
							if(p==0)
								packet=Packet.NORMAL_BASIC;
							else
								packet=Packet.NORMAL_SPECIAL;
						}
						c.usePacket(packet);
						s.append(c.getName());
						s.append(" 变更套餐为 ");
						s.append(packet.getName());
						s.append(r);
					}

					//VIP无套餐客户的月租,按天收
					if(c.getType()==CustomerType.VIP&&c.getPacket()==Packet.VIP_BASIC){
						c.addSpecialCost(2);
						s.append(c.getName());
						s.append(" VIP月租 2元");
						s.append(r);
					}
				}

				//每天都有小概率事件:新用户入网
				if(Math.random()<0.05){
					al.add(new Customer(al.size()));
				}

				//如果是1号,就调用客户们的nextMonth方法
				if(currentDate.get(Calendar.DAY_OF_MONTH)==1){
					for(int i=0;i<al.size();i++)
						al.get(i).nextMonth();
				}

				//记录到文件
				createLogFile(s.toString(),"log\\system",currentDate.get(Calendar.YEAR)+"年"+currentDate.get(Calendar.MONTH)+"月"+currentDate.get(Calendar.DAY_OF_MONTH)+"日 日志.txt");
			}
		},0,MillisPerDay);
	}

	//记录到文件的共用方法
	public static void createLogFile(String s,String filePath,String fileName) {
		File f=new File(filePath);
		if(!f.exists())
			f.mkdirs();
		try {
			PrintWriter pw=new PrintWriter(new FileOutputStream(filePath+"\\"+fileName),true);
			pw.write(s);
			pw.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
}



---------------------- android培训java培训、期待与您交流! ----------------------
详细请查看: http://edu.csdn.net/heima
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值