private static IdGenerator instance = new IdGenerator();
主运行类
public static void main(String[] args) {
MobileCorporation corp = new MobileCorporation();
//设置要模拟的起始月份
Date month = new Date(109,0,1);
System.out.println("程序开始模拟从2009年1月1日开始,连续15个月的运行情况.");
//总共模拟15个连续的月份
for(int i=0;i<15/*3*/;i++){
corp.simulateBusiness(month);
Calendar calendar = Calendar.getInstance();
calendar.setTime(month);
calendar.add(Calendar.MONTH, 1);
month = calendar.getTime();
}
}
public abstract class Customer {
protected String name; private int customerType; private Date joinTime;//用户入网的时间
//下面集合中积累的结果只表示当月的记录,不代表所有历史记录
protected List<ActionRecord> actionRecords = new ArrayList<ActionRecord>();private ArrayList phoneRecords = new ArrayList();
private ArrayList messageRecords = new ArrayList();private ArrayList dataRecords = new ArrayList();
protected PackStrategy packStrategy;
public void monthBegin(){
phoneRecords.clear();messageRecords.clear();dataRecords.clear();actionRecords.clear();
}
public Customer(String name,int customerType,Date joinTime){
this.name = name;this.customerType = customerType;this.joinTime = joinTime;
}
public String toString(){ return name;
}
public void callPhone(int times){
phoneRecords.add(times); actionRecords.add(new ActionRecord("打电话",times + "分钟"));
}
public void sendMessage(int numbers){
messageRecords.add(numbers); actionRecords.add(new ActionRecord("发短信",numbers + "条"));
}
public void transferData(int size){
dataRecords.add(size); actionRecords.add(new ActionRecord("传数据",size + "k"));
}
private int gatherRecords(ArrayList records){
int sum = 0;
for(int i=0;i<records.size();i++){
sum += (Integer)(records.get(i));
}
return sum;
}
public abstract void randomCancelPack(Date month);
public abstract void randomOrderPack(Date month);
用户类中计算某月费用的方法
public int countMonthMoney(Date currentMonth){
boolean newcome = !joinTime.before(currentMonth);//joinTime.after(currentMonth);
int totalPhone = gatherRecords(phoneRecords);int totalMessage = gatherRecords(messageRecords);int totalData = gatherRecords(dataRecords);
int freePhone = 0;int freeMessage = 0;int freeData = 0;
if(newcome){
freePhone = ConfigManager.getNewUserFree(customerType,0); freeMessage = ConfigManager.getNewUserFree(customerType,1);
freeData = ConfigManager.getNewUserFree(customerType,2);
}
int chargePhone = totalPhone>freePhone?totalPhone-freePhone:0;int chargeMessage = totalMessage>freeMessage?totalMessage-freeMessage:0;
int chargeData = totalData>freeData?totalData-freeData:0;
//汇总打印:包括姓名,入网日期,统计月份,通话清单,费用清单,总费用。
System.out.println(name + "," + DateUtil.formatDateToDay(joinTime) + "入网.");
System.out.println(" 操作清单如下-----");
for(int i=0;i<actionRecords.size();i++){ System.out.println(" " + actionRecords.get(i)); }
System.out.println(" 统计清单如下-----");
System.out.println(" 通话:" + phoneRecords + "分钟:短信" + messageRecords + "条:数据" + dataRecords + "k");
System.out.println(" 通话累计:" + totalPhone + "分钟,减除新开户" + freePhone + "分钟,实际收费" + chargePhone + "分钟");
System.out.println(" 短信累计:" + totalMessage + "条,减除新开户" + freeMessage + "条,实际收费" + chargeMessage + "条");
System.out.println(" 数据累计:" + totalData + "k,减除新开户" + freeData + "k,实际收费" + chargeData + "k");
ComputeStrategy phoneStrategy = packStrategy.getValidComputeStrategy(currentMonth,0);
ComputeStrategy messageStrategy = packStrategy.getValidMessageComputeStrategy(currentMonth,1);
ComputeStrategy dataStrategy = packStrategy.getValidDataComputeStrategy(currentMonth,2);
int sum = 0; Rent rent = packStrategy.getValidRent(currentMonth); //VIP用户才有月租金或基本费
if(rent != null){
int rentMoney = rent.coputeRent(joinTime,currentMonth);sum += rentMoney;
System.out.println(" 月租费或基本费:" + rentMoney + "分钱");
}
sum += phoneStrategy.computeMoney(chargePhone)+messageStrategy.computeMoney(chargeMessage)+ dataStrategy.computeMoney(chargeData);
System.out.println(" 总计:" + sum + "分钱");
return sum;
}
普通用户类的randomOrderPack方法
public void randomOrderPack(Date month){
int rand = new Random().nextInt(3);
switch(rand){
case 0:
if(packStrategy.getOrderedPack(0)==null || packStrategy.getOrderedPack(0).getPackType() == 0){
packStrategy.orderPack(month,0);
System.out.println(name + "订购了" + "电话套餐" + "(从" + DateUtil.formatDateToMonth(month) + "开始)");
actionRecords.add(new ActionRecord("定电话套餐",""));
} break;
case 1:
if(packStrategy.getOrderedPack(1) == null || packStrategy.getOrderedPack(1).getPackType() == 0){
packStrategy.orderPack(month,1);
System.out.println(name + "订购了" + "短信套餐" + "(从" + DateUtil.formatDateToMonth(month) + "开始)");
actionRecords.add(new ActionRecord("定短信套餐",""));
} break;
case 2:
if(packStrategy.getOrderedPack(2) == null || packStrategy.getOrderedPack(2).getPackType() == 0){
packStrategy.orderPack(month,2);
System.out.println(name + "订购了" + "数据套餐" + "(从" + DateUtil.formatDateToMonth(month) + "开始)");
actionRecords.add(new ActionRecord("定数据套餐",""));
} break;
}
}
普通用户类的randomCancelPack方法
public void randomCancelPack(Date orderedMonth){
int rand = new Random().nextInt(3);
switch(rand){
case 0:
if(packStrategy.getOrderedPack(0) == null || packStrategy.getOrderedPack(0).getPackType() == 0){
System.out.println(name + "试图退订根本就没有订过的电话套餐"); return;
} packStrategy.cancelPack(orderedMonth,0);
System.out.println(name + "退订了" + "电话套餐" + "(从" + DateUtil.formatDateToMonth(orderedMonth) + "开始)");
actionRecords.add(new ActionRecord("退订电话套餐","")); break;
case 1:
if(packStrategy.getOrderedPack(1) ==null || packStrategy.getOrderedPack(1).getPackType() == 0){
System.out.println(name + "试图退订根本就没有订过的短信套餐"); return;
} packStrategy.cancelPack(orderedMonth,1);
System.out.println(name + "退订了" + "短信套餐" + "(从" + DateUtil.formatDateToMonth(orderedMonth) + "开始)");
actionRecords.add(new ActionRecord("退订短信套餐","")); break;
case 2:
if(packStrategy.getOrderedPack(2)==null || packStrategy.getOrderedPack(2).getPackType() == 0){
System.out.println(name + "试图退订根本就没有订过的数据套餐"); return;
} packStrategy.cancelPack(orderedMonth,2);
System.out.println(name + "退订了" + "数据套餐" + "(从" + DateUtil.formatDateToMonth(orderedMonth) + "开始)");
actionRecords.add(new ActionRecord("退订数据套餐","")); break;
}
}
VIP用户类的randomCancelPack方法
public class VIPCustomer extends Customer {
public VIPCustomer(String name,Date joinTime){
super(name,1,joinTime);
packStrategy = new PackStrategy(1,0,new Rent(200,RentUnit.DAY));
}
public void randomCancelPack(Date month){
if(packStrategy.getOrderedPack(0) ==null || packStrategy.getOrderedPack(0).getPackType() == 0){
System.out.println(name + "试图退订根本就没有订过的套餐");
return;
}
packStrategy.orderRent(orderedMonth,new Rent(200,RentUnit.DAY));
packStrategy.orderPack(orderedMonth,0,0);
packStrategy.orderPack(orderedMonth,0,1);
packStrategy.orderPack(orderedMonth,0,2);
System.out.println(name + "退订了" + "套餐" + "(从" + DateUtil.formatDateToMonth(orderedMonth) + "开始)");
actionRecords.add(new ActionRecord("退定套餐",""));
}
VIP用户类的randomOrderPack方法
public void orderPack1(Date month){
if(packStrategy.getOrderedPack(0)==null || packStrategy.getOrderedPack(0).getPackType() != 1){
packStrategy.orderRent(month,new Rent(10000,RentUnit.MONTH));
packStrategy.orderPack(month,1,0);packStrategy.orderPack(month,1,1);packStrategy.orderPack(month,1,2);
System.out.println(name+ "订购了套餐1" + "(从" + DateUtil.formatDateToMonth(month) + "开始)" );
actionRecords.add(new ActionRecord("订购套餐1",""));
}
}
public void orderPack2(Date month){
if(packStrategy.getOrderedPack(0) ==null || packStrategy.getOrderedPack(0).getPackType() != 2){
packStrategy.orderRent(month,new Rent(20000,RentUnit.MONTH));
packStrategy.orderPack(month,2,0);packStrategy.orderPack(month,2,1);packStrategy.orderPack(month,2,2)
System.out.println(name+ "订购了套餐2" + "(从" + DateUtil.formatDateToMonth(month) + "开始)" );
actionRecords.add(new ActionRecord("订购套餐2",""));
}
}
public void randomOrderPack(Date month){
//如果以前订购过某套餐,现在仍然可以重新订购该套餐
int randType = (new Random().nextInt(10))%2;
if(randType == 0){ orderPack1(month);
}else if(randType == 1){ orderPack2(month);
}
}
计算某项功能费用的策略类
public class ComputeStrategy {
//此处省略成员变量的定义….
public ComputeStrategy(int customerType, int packType,int entryType) {
this.customerType = customerType;
this.packType = packType;
this.entryType = entryType;
switch(entryType){
case 0:entryName = "电话";break;
case 1:entryName = "短信";break;
case 2:entryName = "数据";break;
}
}
public int computeMoney(int quantity){
int unitPrice = ConfigManager.getUnitPrice(customerType, packType,entryType);
int freeQuantity = ConfigManager.getPackFree(customerType, packType,entryType);
int packCharge = ConfigManager.getPackCharge(customerType, packType,entryType);
int charQuantity = quantity - freeQuantity;
if(chargeQuantity < 0){
chargeQuantity = 0;
}
int money = packCharge + price * chargeQuantity;
System.out.println(" " + entryName + "月功能费为:" + packCharge + "分钱,");
System.out.println(" 收费数量:" + quantity + "-" + freeQuantity + "=" + chargeQuantity + ",");
System.out.println(" 使用收费:" + chargeQuantity + "*" + price + "=" + price * chargeQuantity +"分钱,");
System.out.println(" 小计收费:" + packCharge + "+" + price * chargeQuantity + "分钱");
return money;
}
}
计算VIP用户月租费或月基本费的类
public class Rent {
//此处省略成员变量和构造方法的定义
public int coputeRent(Date startTime,Date currentMonth){
//首先应该想到去找开源的日期运算类
if(unit == RentUnit.DAY){
Calendar start = Calendar.getInstance();
start.setTime(startTime);
Calendar end = Calendar.getInstance();
end.setTime(currentMonth);
//将日期设置为当月的最后一天
end.set(Calendar.DAY_OF_MONTH, 1);
end.add(Calendar.MONTH, 1);
end.add(Calendar.DAY_OF_MONTH, -1);
int days = end.get(Calendar.DAY_OF_MONTH) ;
if(end.get(Calendar.MONTH) == start.get(Calendar.MONTH)){
days -= start.get(Calendar.DAY_OF_MONTH) + 1;
}
return price*days;
}
else{
return price;
}
}
}
存储用户的各项业务套餐策略的类
public class PackStrategy {
private int customerType;
private Rent rent;
private ComputeStrategy computeStrategy[] = new ComputeStrategy[3];
private OrderedStrategyHolder<Rent> orderedRent = new OrderedStrategyHolder<Rent>();
private OrderedStrategyHolder<ComputeStrategy>[] orderedStrategyHolder = new OrderedStrategyHolder<ComputeStrategy>[3];
public PackStrategy(int customerType,int packType,Rent rent){
this.customerType = customerType;
this.rent = rent;
for(int i=0;i<3;i++){
computeStrategy[i] = new ComputeStrategy(customerType,packType,i);
orderedStrategyHolder[i] = new OrderedStrategyHolder<ComputeStrategy>();
}
}
public Rent getValidRent(Date month){
Rent holderRent = orderedRent.getValidStrategy(month);
return holderRent==null?rent:holderRent;
}
public void orderRent(Date orderedMonth,Rent rent){
Rent oldRent = orderedRent.order(orderedMonth,rent);
if(oldRent != null){
this.rent = oldRent;
}
}
public void cancelRent(Date orderedMonth){
orderRent(orderedMonth,null);
}
public ComputeStrategy getValidComputeStrategy(Date month,int entryType){
ComputeStrategy orderedStrategy = orderedStrategyHolder[entryType].getValidStrategy(month);
return orderedStrategy==null?computeStrategy[entryType]:orderedStrategy;
}
public void orderPack(Date orderedMonth,int packType,entryType){
ComputeStrategy orderedStrategy = orderedStrategyHolder[entryType].order(
orderedMonth,new ComputeStrategy(customerType,packType,entryType));
if(orderedStrategy != null){
computeStrategy[entryType] = orderedStrategy;
}
}
public void cancelPack(Date orderedMonth,int entryType){
orderPack(orderedMonth, 0,entryType);
}
套餐订购记录类(存储一项业务套餐订购信息)
public class OrderedStrategyHolder<T> {
private Date orderedMonth;
private T strategy;
public T order(Date orderingMonth,T strategy){
T oldStrategy = null;
if((this.orderedMonth!=null) && this.orderedMonth.before(orderingMonth)){
oldStrategy = this.strategy;
}
this.orderedMonth = orderingMonth;
this.strategy = strategy;
return oldStrategy;
}
public T getValidStrategy(Date month){
if(orderedMonth!=null && (!orderedMonth.after(month))){
return strategy;
}
return null;
}
}