移动业务资费问题分析与总结

移动业务资费问题分析与总结

前言:移动业务资费问题,主要是涉及座机,手机等不同设备,在不同地域通信的收费问题,

如省内省外通信,或出省漫游通信,不同设备,通信地点不同,收费规则也不同

而本次将对移动业务资费问题的三次作业进行分析,三次作业迭代,主要涉及多态,继承,抽象,SimpleDateFormat类等

 

题目整体分析

先看看题目

 

 

 

有两种机型,座机,手机,众所周知,座机不能移动,只能在南昌市拨打接听,

而手机则是我们每天带在身边的那种,当然是跟随我们移动的,

也就会出现市内,省内,省外,接听,拨打,3*2=6种情况,而手机还有发送信息的计费情况

 

1.0第一次

第一次全为对座机的计费

 

第一次题目笔者认为有以下几点比较重要

1.1确定要使用哪些类,以及它们之间的关系

其中我使用了用户类,通讯记录类,计费规则类,业务类

 

用户有自己的通讯记录,确定座机或手机后,对应有不同计费规则,体现策略模式

 

 座机下的计费规则

 

class LandPhoneInCityRule extends CallChargeRule{

@Override
public double calCost(ArrayList<CallRecord> callRecords) {
long difMin = 0;
double sumCost = 0;
for (CallRecord c : callRecords) {
difMin = (c.getEndTime().getTime() - c.getStartTime().getTime())/60/1000;
if ((c.getEndTime().getTime() - c.getStartTime().getTime())/60.0/1000.0 % 1 != 0) {
difMin = difMin + 1;
}
sumCost = sumCost + difMin * 0.1;
}
return sumCost;
}
}
class LandPhoneInProvinceRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
long difMin = 0;
double sumCost = 0;
for (CallRecord c : callRecords) {
difMin = (c.getEndTime().getTime() - c.getStartTime().getTime())/60/1000;
if ((c.getEndTime().getTime() - c.getStartTime().getTime())/60.0/1000.0 % 1 != 0) {
difMin = difMin + 1;
}
sumCost = sumCost + difMin * 0.3;
}
return sumCost;
}
}
class LandPhoneInLandRule extends CallChargeRule{
@Override
public double calCost(ArrayList<CallRecord> callRecords) {
long difMin = 0;
double sumCost = 0;
for (CallRecord c : callRecords) {
difMin = (c.getEndTime().getTime() - c.getStartTime().getTime())/60/1000;
if ((c.getEndTime().getTime() - c.getStartTime().getTime())/60.0/1000.0 % 1 != 0) {
difMin = difMin + 1;
}
sumCost = sumCost + difMin * 0.6;
}
return sumCost;
}
}

通讯记录类将市内,省内,省外的接听拨打,信息的发送接收分开存储

 

计费规则则是针对市内,省内,省外的接听拨打,信息的发送接收采取不同计费规则

 

而业务类则负责整个用户群体的信息记录,打印话费,余额

业务类中使用

 

记录用户,为什么选择TreeMap呢,

一是可以解决用户重复的问题,达到去重的效果

二则是对用户类实现了Comparable接口中的compareTo方法后可以自动依据用户号码对用户排序,

三便是将用户号码与用户对应,便于解决对应输入查找相应用户的问题

一举三得

 

1.2对输入信息格式的判定

输入格式可以说是房门钥匙,若输入不能准确判断,之后的运行过程中也会再出错

使用正则表达式,来排除错误的输入格式,使用SimpleDateFormat类来读取通话的日期

SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
String messageFormat = "t-0791\\d{7,8} \\d{10,12} " +
"[1-9]\\d*.([1-9]|10|11|12).([1-9]|[1-2]\\d|30|31) " +
"(0\\d|1\\d|2[0-3]):[0-5]\\d:[0-5]\\d " +
"[1-9]\\d*.([1-9]|10|11|12).([1-9]|[1-2]\\d|30|31) " +
"(0\\d|1\\d|2[0-3]):[0-5]\\d:[0-5]\\d";
String userFormat = "u-0791\\d{7,8} [0-2]";

 

1.3正确地创建用户,记录不同通话类型(市内,省内,省外的接听拨打)

public void addUser() {
Scanner in = new Scanner(System.in);
Date startDate = null;
Date endDate = null;
String userNumber;
String otherNumber;
String message;
SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
String messageFormat = "t-0791\\d{7,8} \\d{10,12} " +
"[1-9]\\d*.([1-9]|10|11|12).([1-9]|[1-2]\\d|30|31) " +
"(0\\d|1\\d|2[0-3]):[0-5]\\d:[0-5]\\d " +
"[1-9]\\d*.([1-9]|10|11|12).([1-9]|[1-2]\\d|30|31) " +
"(0\\d|1\\d|2[0-3]):[0-5]\\d:[0-5]\\d";
String userFormat = "u-0791\\d{7,8} [0-2]";
String userAccount;
do {
userAccount = in.nextLine();
if (userAccount.matches(userFormat)) {
User user = new User(userAccount.split(" ")[0].split("-")[1]);
switch (Integer.parseInt(userAccount.split(" ")[1])) {
case 0:
user.setChargeMode(new LandlinePhoneCharging());
break;
}
users.put(user.getNumber(), user);
}
} while (userAccount.matches(userFormat));
message = userAccount;
do {
if (message.matches(messageFormat)) {
userNumber = message.split(" ")[0].split("-")[1];
otherNumber = message.split(" ")[1];
if (users.get(userNumber) != null) {
try {
startDate = timeFormat.parse(message.split(" ")[message.split(" ").length-4] + " "
+ message.split(" ")[message.split(" ").length-3]);
endDate = timeFormat.parse(message.split(" ")[message.split(" ").length-2] + " "
+ message.split(" ")[message.split(" ").length-1]);
} catch (ParseException e) {
e.printStackTrace();
}

if (otherNumber.substring(0,4).matches("0791")) {
users.get(userNumber).getUserRecords().
addCallingInCityRecords(new CallRecord(startDate,endDate));
} else if (otherNumber.substring(0,4).matches("(079\\d|0701)")) {
users.get(userNumber).getUserRecords().
addCallingInProvinceRecords(new CallRecord(startDate,endDate));
} else {
users.get(userNumber).getUserRecords().
addCallingInLandRecords(new CallRecord(startDate,endDate));
}
}
}
message = in.nextLine();
} while (!message.equals("end"));
}

 

程序类图如下:

 

 

运行结果如下:

 

2.0第二次

在第一次基础上新增了对手机的计费

 

 

手机相比于座机要复杂得多

因为手机可以移动也就产生了多种情况

市内拨打市内电话

市内拨打省内电话

市内拨打省外电话

省内漫游打电话

省外漫游接听

省外漫游拨打

这些情况下计费方式各不相同,还多了对接听的记录

需要对不同情况细致分类

 

2.1不同情况使用不同正则表达式

        String messageFormatLL = "t-0791\\d{7,8} 0\\d{9,11} " +
                "[1-9]\\d*.([1-9]|10|11|12).([1-9]|[1-2]\\d|30|31) " +
                "(0\\d|1\\d|2[0-3]):[0-5]\\d:[0-5]\\d " +
                "[1-9]\\d*.([1-9]|10|11|12).([1-9]|[1-2]\\d|30|31) " +
                "(0\\d|1\\d|2[0-3]):[0-5]\\d:[0-5]\\d";
        String messageFormatLP = "t-0791\\d{7,8} 1\\d{10} 0\\d{2,3} " +
                "[1-9]\\d*.([1-9]|10|11|12).([1-9]|[1-2]\\d|30|31) " +
                "(0\\d|1\\d|2[0-3]):[0-5]\\d:[0-5]\\d " +
                "[1-9]\\d*.([1-9]|10|11|12).([1-9]|[1-2]\\d|30|31) " +
                "(0\\d|1\\d|2[0-3]):[0-5]\\d:[0-5]\\d";
        String messageFormatPL = "t-1\\d{10} 0\\d{2,3} 0791\\d{7,8} " +
                "[1-9]\\d*.([1-9]|10|11|12).([1-9]|[1-2]\\d|30|31) " +
                "(0\\d|1\\d|2[0-3]):[0-5]\\d:[0-5]\\d " +
                "[1-9]\\d*.([1-9]|10|11|12).([1-9]|[1-2]\\d|30|31) " +
                "(0\\d|1\\d|2[0-3]):[0-5]\\d:[0-5]\\d";
        String messageFormatPP = "t-1\\d{10} 0\\d{2,3} 1\\d{10} 0\\d{2,3} " +
                "[1-9]\\d*.([1-9]|10|11|12).([1-9]|[1-2]\\d|30|31) " +
                "(0\\d|1\\d|2[0-3]):[0-5]\\d:[0-5]\\d " +
                "[1-9]\\d*.([1-9]|10|11|12).([1-9]|[1-2]\\d|30|31) " +
                "(0\\d|1\\d|2[0-3]):[0-5]\\d:[0-5]\\d";

 

2.2分析不同情况,正确记录通信

对于不同情况的分析主要是对区号进行比较,

通过不同区号逐一,层层判断是否在市内,省内,是否是漫游状态

其中需要注意区号也存在三位区号的情况

不同情况下的判断如下代码中作不同注释

        do {
            if (message.matches(messageFormatLL) || message.matches(messageFormatLP)
                    || message.matches(messageFormatPL)|| message.matches(messageFormatPP)) {
                userNumber = message.split(" ")[0].split("-")[1];
                if (message.matches(messageFormatLL) || message.matches(messageFormatLP)) {
                    otherNumber = message.split(" ")[1];
                } else {
                    otherNumber = message.split(" ")[2];
                }
                if (users.containsKey(userNumber) || users.containsKey(otherNumber)) {
                    try {
                        startDate = timeFormat.parse(message.split(" ")[message.split(" ").length - 4] + " "
                                + message.split(" ")[message.split(" ").length - 3]);
                        endDate = timeFormat.parse(message.split(" ")[message.split(" ").length - 2] + " "
                                + message.split(" ")[message.split(" ").length - 1]);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    //座机打座机
                    if (message.matches(messageFormatLL)) {
                        if (otherNumber.substring(0,4).matches("0791")) {
                            if (users.containsKey(userNumber)) {
                                users.get(userNumber).getUserRecords().
                                        addCallingInCityRecords(new CallRecord(startDate,endDate,
                                                userNumber.substring(0,4),otherNumber.substring(0,4)));
                            }
                        } else if (otherNumber.substring(0,4).matches("(079\\d|0701)")) {
                            if (users.containsKey(userNumber)) {
                                users.get(userNumber).getUserRecords().
                                        addCallingInProvinceRecords(new CallRecord(startDate,endDate,
                                                userNumber.substring(0,4),otherNumber.substring(0,4)));
                            }
                        } else {
                            if (users.containsKey(userNumber)) {
                                users.get(userNumber).getUserRecords().
                                        addCallingInLandRecords(new CallRecord(startDate,endDate,
                                                userNumber.substring(0,4),otherNumber.substring(0,4)));
                            }
                        }
                        //座机打手机
                    } else if(message.matches(messageFormatLP)) {
                        if (message.split(" ")[2].matches("0791")) {
                            if (users.containsKey(userNumber)) {
                                users.get(userNumber).getUserRecords().
                                        addCallingInCityRecords(new CallRecord(startDate,endDate,
                                                userNumber.substring(0,4),message.split(" ")[2]));
                            }
                        } else if (message.split(" ")[2].matches("(079\\d|0701)")) {
                            if (users.containsKey(userNumber)) {
                                users.get(userNumber).getUserRecords().
                                        addCallingInProvinceRecords(new CallRecord(startDate,endDate,
                                                userNumber.substring(0,4),message.split(" ")[2]));
                            }
                        } else {
                            if (users.containsKey(userNumber)) {
                                users.get(userNumber).getUserRecords().
                                        addCallingInLandRecords(new CallRecord(startDate,endDate,
                                                userNumber.substring(0,4),message.split(" ")[2]));
                            }
                            if (users.containsKey(otherNumber)) {
                                users.get(otherNumber).getUserRecords().
                                        addAnswerInLandRecords(new CallRecord(startDate,endDate,
                                                userNumber.substring(0,4),message.split(" ")[2]));
                            }
                        }
                        //手机打座机
                    } else if (message.matches(messageFormatPL)) {
                        if (message.split(" ")[1].matches("0791")) {
                            if (users.containsKey(userNumber)) {
                                users.get(userNumber).getUserRecords().
                                        addCallingInCityRecords(new CallRecord(startDate,endDate,
                                                message.split(" ")[1],otherNumber.substring(0,4)));
                            }
                        } else if (message.split(" ")[1].matches("(079\\d|0701)")) {
                            if (users.containsKey(userNumber)) {
                                users.get(userNumber).getUserRecords().
                                        addCallingInProvinceRoamRecords(new CallRecord(startDate,endDate,
                                                message.split(" ")[1],otherNumber.substring(0,4)));
                            }
                        } else {
                            if (users.containsKey(userNumber)) {
                                users.get(userNumber).getUserRecords().
                                        addCallingInLandRoamRecords(new CallRecord(startDate,endDate,
                                                message.split(" ")[1],message.split(" ")[3]));
                            }
                        }
                        //手机打手机
                    } else {
                        if (message.split(" ")[1].matches("0791")
                                && message.split(" ")[3].matches("0791")) {
                            if (users.containsKey(userNumber)) {
                                users.get(userNumber).getUserRecords().
                                        addCallingInCityRecords(new CallRecord(startDate,endDate,
                                                message.split(" ")[1],message.split(" ")[3]));
                            }
                        } else if (message.split(" ")[1].matches("0791")
                                && message.split(" ")[3].matches("(079\\d|0701)")) {
                            if (users.containsKey(userNumber)) {
                                users.get(userNumber).getUserRecords().
                                        addCallingInProvinceRecords(new CallRecord(startDate,endDate,
                                                message.split(" ")[1],message.split(" ")[3]));
                            }
                        } else if (message.split(" ")[1].matches("0791")
                                && !message.split(" ")[3].matches("(079\\d|0701)")) {
                            if (users.containsKey(userNumber)) {
                                users.get(userNumber).getUserRecords().
                                        addCallingInLandRecords(new CallRecord(startDate,endDate,
                                                message.split(" ")[1],message.split(" ")[3]));
                            }
                            if (users.containsKey(otherNumber)) {
                                users.get(otherNumber).getUserRecords().
                                        addAnswerInLandRecords(new CallRecord(startDate,endDate,
                                                message.split(" ")[1],message.split(" ")[3]));
                            }
                        } else if (message.split(" ")[1].matches("(079\\d|0701)")
                                && !message.split(" ")[1].matches("0791")) {
                            if (users.containsKey(userNumber)) {
                                users.get(userNumber).getUserRecords().
                                        addCallingInProvinceRoamRecords(new CallRecord(startDate, endDate,
                                                message.split(" ")[1], message.split(" ")[3]));
                            }
                            if (!message.split(" ")[3].matches("(079\\d|0701)")) {
                                if (users.containsKey(otherNumber)) {
                                    users.get(otherNumber).getUserRecords().
                                            addAnswerInLandRecords(new CallRecord(startDate,endDate,
                                                    message.split(" ")[1],message.split(" ")[3]));
                                }
                            }
                        } else if (!message.split(" ")[1].matches("(079\\d|0701)")) {
                            if (users.containsKey(userNumber)) {
                                users.get(userNumber).getUserRecords().
                                        addCallingInLandRoamRecords(new CallRecord(startDate, endDate,
                                                message.split(" ")[1], message.split(" ")[3]));
                            }
                            if (!message.split(" ")[3].matches("(079\\d|0701)")) {
                                if (users.containsKey(otherNumber)) {
                                    users.get(otherNumber).getUserRecords().
                                            addAnswerInLandRecords(new CallRecord(startDate,endDate,
                                                    message.split(" ")[1],message.split(" ")[3]));
                                }
                            }
                        }
                    }
                }
            }
            message = in.nextLine();
        } while (!message.equals("end"));

 

类图如下:

 

 

运行结果如下:

 

 

3.0第三次

第三次相比第一次和第二次的计费,只计算手机间消息发送,接收的收费情况,较为简单

 

3.1也仅有3.1,对信息条数的正确判断

短信内容只能由数字、字母、空格、英文逗号、英文句号组成

短信内容中包含空格,也就直接导致不能使用空格分隔来确定短信条数

因为前端用户信息的字符个数已经确定,使用

就可以截取短信内容

之后通过

便可计算出短信条数

 

最后根据短信的条数分类

只有一条则直接添加一条记录,完毕

 

 

而存在多条短信,则使用循环,不断添加记录,并对最后一条短信单独添加

以免截取过多短信内容

如此便成功添加了所有短信

 

类图如下:

 

 

运行结果如下:

 

 

总结:

写代码之前理解类之间的关系,理解需求很重要,类之间的关系可以从上往下开始分析,

即先从Main开始,了解类之间整体的架构,他们之间是怎样联系起来的。

也可以从下往上分析,即先找到代码中最小的类,此时一般看类名也能了解它的具体用处,

再看看它是如何实现的,之后向上找它的父类,不断重复到Main

 

posted @ 2022-06-15 23:26  见光易分解  阅读(356)  评论(0)    收藏  举报