面向对象程序设计第三单元内容总结

前言:

  这一单元的学习主要以实践为主,围绕电信计费系统问题,基于给定类图实现功能,并迭代。


设计与分析:

第一次作业:

  

 

由于给出了类图,类的设计已完成,使用IDEA自动生成代码大大减少了实际编码量。这样就使得我可以把主要的精力放在了重要方法的实现上。

代码如下:

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static final String regStr1 = "u-0791\\d{7,8}\\s[0-2]";
    public static final String regStr = "t-0791\\d{7,8}\\s" + "0\\d{9,11}\\s" +
            "(((\\d{3}[1-9]|\\d{2}[1-9]\\d|\\d[1-9]\\d{2}|[1-9]\\d{3})\\.(((0?[13578]|1[02])\\.(0?" +
            "[1-9]|[12]\\d|3[01]))|(([469]|11)\\.([1-9]|[12]\\d|30))|(2\\.([1-9]|1\\d|2[0-8]))))|(((" +
            "\\d{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" +
            "\\s([0-1]?\\d|2[0-3]):([0-5]\\d):([0-5]\\d)\\s" +
            "(((\\d{3}[1-9]|\\d{2}[1-9]\\d|\\d[1-9]\\d{2}|[1-9]\\d{3})\\.((([13578]|1[02])\\.(" +
            "[1-9]|[12]\\d|3[01]))|(([469]|11)\\.([1-9]|[12]\\d|30))|(2\\.([1-9]|1\\d|2[0-8]))))|(((" +
            "\\d{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" +
            "\\s([0-1]?\\d|2[0-3]):([0-5]\\d):([0-5]\\d)";

    public static void main(String[] args) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        Scanner in = new Scanner(System.in);

        Pattern pattern = Pattern.compile(regStr1);
        String line = in.nextLine();
        Matcher matcher = pattern.matcher(line);

        ArrayList<User> users = new ArrayList<>();
        String[] userData = line.split(" ");
        int repeat = 0;
        while (!line.equals("end")) {
            if (line.startsWith("t-")){
                Pattern pattern1 = Pattern.compile(regStr);
                Matcher matcher1 = pattern1.matcher(line);
                if(matcher1.find())
                    break;
            }
            if (matcher.find()) {
                User newUser = new User(100, new LandlinePhoneCharging(), userData[0].substring(2));
                for (User user : users) {
                    if (user.getNumber().equals(newUser.getNumber()) || !user.getNumber().startsWith("0791")) {
                        repeat = 1;
                        break;
                    }
                }
                if (repeat == 0) {
                    users.add(newUser);
                }
                repeat = 0;
            }
            line = in.nextLine();
            userData = line.split(" ");
            matcher = pattern.matcher(line);
        }
        pattern = Pattern.compile(regStr);
        matcher = pattern.matcher(line);
        String callNumber;
        String answerNumber;
        while (!line.equals("end")) {
            if (matcher.find()) {
                String[] data = line.split(" ");
                callNumber = data[0].substring(2);
                answerNumber = data[1];
                try {
                    Date startDate = dateFormat.parse(data[2] + " " + data[3]);
                    Date endDate = dateFormat.parse(data[4] + " " + data[5]);
                    for (User user : users) {
                        if (user.getNumber().equals(callNumber)) {
                            int pos = judgePosition(user.getNumber(), answerNumber);
                            switch (pos) {
                                case 0:
                                    user.getUserRecords().addCallingInCityRecords(new CallRecord(callNumber, answerNumber, startDate, endDate));
                                    break;
                                case 1:
                                    user.getUserRecords().addCallingInProvinceRecords(new CallRecord(callNumber, answerNumber, startDate, endDate));
                                    break;
                                case 2:
                                    user.getUserRecords().addCallingInLandRecords(new CallRecord(callNumber, answerNumber, startDate, endDate));
                                    break;
                            }
                        }
                        if (user.getNumber().equals(answerNumber)) {
                            int pos = judgePosition(user.getNumber(), answerNumber);
                            switch (pos) {
                                case 0:
                                    user.getUserRecords().addAnswerInCityRecords(new CallRecord(callNumber, answerNumber, startDate, endDate));
                                    break;
                                case 1:
                                    user.getUserRecords().addAnswerInProvinceRecords(new CallRecord(callNumber, answerNumber, startDate, endDate));
                                    break;
                                case 2:
                                    user.getUserRecords().addAnswerInLandRecords(new CallRecord(callNumber, answerNumber, startDate, endDate));
                                    break;
                            }
                        }
                    }
                } catch (Exception e) {
                    line = in.nextLine();
                    matcher = pattern.matcher(line);
                    continue;
                }
            }
            line = in.nextLine();
            matcher = pattern.matcher(line);
        }
        Collections.sort(users);
        for (User user : users) {
            user.setBalance(user.calBalance());
            System.out.printf(user.getNumber() + " " + round(user.calCost()) + " " + round(user.getBalance()) + "\n");
        }
    }

    public static String round(double val) {
        BigDecimal bigDecimal = new BigDecimal(val);
        bigDecimal = bigDecimal.setScale(2, RoundingMode.HALF_UP);
        bigDecimal = bigDecimal.stripTrailingZeros();
        String ret = bigDecimal.toPlainString();
        if (!ret.contains(".")) {
            ret += ".0";
        }
        return ret;
    }

    public static int judgePosition(String callNumber, String answerNumber) {
        if (callNumber.substring(0, 4).equals(answerNumber.substring(0, 4))) {
            return 0;
        } else if ((callNumber.startsWith("0790")
                || callNumber.startsWith("0791")
                || callNumber.startsWith("0792")
                || callNumber.startsWith("0793")
                || callNumber.startsWith("0794")
                || callNumber.startsWith("0795")
                || callNumber.startsWith("0796")
                || callNumber.startsWith("0797")
                || callNumber.startsWith("0798")
                || callNumber.startsWith("0799")
                || callNumber.startsWith("0701")) && (
                answerNumber.startsWith("0790")
                        || answerNumber.startsWith("0791")
                        || answerNumber.startsWith("0792")
                        || answerNumber.startsWith("0793")
                        || answerNumber.startsWith("0794")
                        || answerNumber.startsWith("0795")
                        || answerNumber.startsWith("0796")
                        || answerNumber.startsWith("0797")
                        || answerNumber.startsWith("0798")
                        || answerNumber.startsWith("0799")
                        || answerNumber.startsWith("0701"))
        ) {
            return 1;
        } else {
            return 2;
        }
    }

    public static class MessageRecord extends CommunicationRecord {
        private String message;

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }
    }

    public static class User implements Comparable<User> {
        private UserRecords userRecords = new UserRecords();
        private double balance;
        private ChargeMode chargeMode;
        private String number;

        public User() {
        }

        public User(double balance, ChargeMode chargeMode, String number) {
            this.balance = balance;
            this.chargeMode = chargeMode;
            this.number = number;
        }

        public double calCost() {
            return chargeMode.calCost(userRecords);
        }

        public double calBalance() {
            return balance - calCost() - chargeMode.getMonthlyRent();
        }

        public UserRecords getUserRecords() {
            return userRecords;
        }

        public void setUserRecords(UserRecords userRecords) {
            this.userRecords = userRecords;
        }

        public double getBalance() {
            return balance;
        }

        public void setBalance(double balance) {
            this.balance = balance;
        }

        public ChargeMode getChargeMode() {
            return chargeMode;
        }

        public void setChargeMode(ChargeMode chargeMode) {
            this.chargeMode = chargeMode;
        }

        public String getNumber() {
            return number;
        }

        public void setNumber(String number) {
            this.number = number;
        }

        public int compareTo(User user) {
            int result = this.getNumber().compareTo(user.getNumber());
            switch (result) {
                case 0:
                    return 0;
                case 1:
                    return 1;
                default:
                    return -1;
            }
        }
    }

    public static class UserRecords {
        private final ArrayList<CallRecord> callingInCityRecords = new ArrayList<>();
        private final ArrayList<CallRecord> callingInProvinceRecords = new ArrayList<>();
        private final ArrayList<CallRecord> callingInLandRecords = new ArrayList<>();
        private final ArrayList<CallRecord> answerInCityRecords = new ArrayList<>();
        private final ArrayList<CallRecord> answerInProvinceRecords = new ArrayList<>();
        private final ArrayList<CallRecord> answerInLandRecords = new ArrayList<>();
        private final ArrayList<MessageRecord> sendMessageRecords = new ArrayList<>();
        private final ArrayList<MessageRecord> receiveMessageRecords = new ArrayList<>();

        public void addCallingInCityRecords(CallRecord callRecord) {
            if (!checkRepeat(callRecord, getCallingInCityRecords()))
                callingInCityRecords.add(callRecord);
        }

        public void addCallingInProvinceRecords(CallRecord callRecord) {
            if (!checkRepeat(callRecord, getCallingInProvinceRecords()))
                callingInProvinceRecords.add(callRecord);
        }

        public void addCallingInLandRecords(CallRecord callRecord) {
            if (!checkRepeat(callRecord, getCallingInLandRecords()))
                callingInLandRecords.add(callRecord);
        }

        public void addAnswerInCityRecords(CallRecord answerRecord) {
            if (!checkRepeat(answerRecord, getAnswerInCityRecords()))
                answerInCityRecords.add(answerRecord);
        }

        public void addAnswerInProvinceRecords(CallRecord answerRecord) {
            if (!checkRepeat(answerRecord, getAnswerInProvinceRecords()))
                answerInProvinceRecords.add(answerRecord);
        }

        public void addAnswerInLandRecords(CallRecord answerRecord) {
            if (!checkRepeat(answerRecord, getAnswerInLandRecords()))
                answerInLandRecords.add(answerRecord);
        }

        public void addSendMessageRecords(MessageRecord messageRecord) {
            sendMessageRecords.add(messageRecord);
        }

        public void addReceiveMessageRecords(MessageRecord messageRecord) {
            receiveMessageRecords.add(messageRecord);
        }

        public ArrayList<CallRecord> getCallingInCityRecords() {
            return callingInCityRecords;
        }

        public ArrayList<CallRecord> getCallingInProvinceRecords() {
            return callingInProvinceRecords;
        }

        public ArrayList<CallRecord> getCallingInLandRecords() {
            return callingInLandRecords;
        }

        public ArrayList<CallRecord> getAnswerInCityRecords() {
            return answerInCityRecords;
        }

        public ArrayList<CallRecord> getAnswerInProvinceRecords() {
            return answerInProvinceRecords;
        }

        public ArrayList<CallRecord> getAnswerInLandRecords() {
            return answerInLandRecords;
        }

        public ArrayList<MessageRecord> getSendMessageRecords() {
            return sendMessageRecords;
        }

        public ArrayList<MessageRecord> getReceiveMessageRecords() {
            return receiveMessageRecords;
        }

        public boolean checkRepeat(CallRecord record, ArrayList<CallRecord> records) {
            if (record.getCallingNumber().equals(record.getAnswerNumber())){
                return true;
            }
            for (CallRecord rd : records) {
                if (rd.getStartTime() == record.getStartTime() && rd.getEndTime() == record.getEndTime()) {
                    return true;
                }
                if (record.getCallingNumber().equals(record.getAnswerNumber())) {
                    return true;
                }
                if (record.getStartTime().getTime() - record.getEndTime().getTime() > 0) {
                    return true;
                }
            }
            return false;
        }
    }

    public static class LandPhoneInProvinceRule extends CallChargeRule {
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            long diff = 0;
            long minutes = 0;
            long second = 0;
            double result = 0;
            for (CallRecord callRecord : callRecords) {
                diff = callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime();
                minutes = diff / (1000 * 60);
                second = (diff - minutes * (1000 * 60)) / (1000);
                if (second != 0) {
                    minutes++;
                }
                result += minutes * 0.3;
            }
            return result;
        }
    }

    public static class LandPhoneInlandRule extends CallChargeRule {
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            long diff = 0;
            long minutes = 0;
            long second = 0;
            double result = 0;
            for (CallRecord callRecord : callRecords) {
                diff = callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime();
                minutes = diff / (1000 * 60);
                second = (diff - minutes * (1000 * 60)) / (1000);
                if (second != 0) {
                    minutes++;
                }
                result += minutes * 0.6;
            }
            return result;
        }
    }

    public static class LandPhoneInCityRule extends CallChargeRule {
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            long diff = 0;
            long minutes = 0;
            long second = 0;
            double result = 0;
            for (CallRecord callRecord : callRecords) {
                diff = callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime();
                minutes = diff / (1000 * 60);
                second = (diff - minutes * (1000 * 60)) / (1000);
                if (second != 0) {
                    minutes++;
                }
                result += minutes * 0.1;
            }
            return result;
        }
    }

    public static class LandlinePhoneCharging extends ChargeMode {
        private final double monthlyRent = 20;

        public LandlinePhoneCharging() {
            getChargeRules().add(new LandPhoneInCityRule());
            getChargeRules().add(new LandPhoneInlandRule());
            getChargeRules().add(new LandPhoneInProvinceRule());
        }

        @Override
        public double calCost(UserRecords userRecords) {
            double cost = 0;
            cost += getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords());
            cost += getChargeRules().get(1).calCost(userRecords.getCallingInLandRecords());
            cost += getChargeRules().get(2).calCost(userRecords.getCallingInProvinceRecords());
            return cost;
        }

        @Override
        public double getMonthlyRent() {
            return monthlyRent;
        }
    }

    public abstract static class CommunicationRecord {
        protected String callingNumber;
        protected String answerNumber;

        public String getCallingNumber() {
            return callingNumber;
        }

        public void setCallingNumber(String callingNumber) {
            this.callingNumber = callingNumber;
        }

        public String getAnswerNumber() {
            return answerNumber;
        }

        public void setAnswerNumber(String answerNumber) {
            this.answerNumber = answerNumber;
        }
    }

    public abstract static class ChargeRule {
        abstract double calCost(ArrayList<CallRecord> callRecords);
    }

    public abstract static class ChargeMode {
        private ArrayList<ChargeRule> chargeRules = new ArrayList<>();

        public ArrayList<ChargeRule> getChargeRules() {
            return chargeRules;
        }

        public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
            this.chargeRules = chargeRules;
        }

        public abstract double calCost(UserRecords userRecords);

        public abstract double getMonthlyRent();
    }

    public static class CallRecord extends CommunicationRecord {
        private Date startTime;
        private Date endTime;
        private String callingAddressAreaCode;
        private String answerAddressAreaCode;

        public CallRecord(String callNumber, String answerNumber, Date startTime, Date endTime) {
            setCallingNumber(callNumber);
            setAnswerNumber(answerNumber);
            this.startTime = startTime;
            this.endTime = endTime;
            callingAddressAreaCode = callNumber.substring(0, 4);
            answerAddressAreaCode = answerNumber.substring(0, 4);
        }

        public Date getStartTime() {
            return startTime;
        }

        public void setStartTime(Date startTime) {
            this.startTime = startTime;
        }

        public Date getEndTime() {
            return endTime;
        }

        public void setEndTime(Date endTime) {
            this.endTime = endTime;
        }

        public String getCallingAddressAreaCode() {
            return callingAddressAreaCode;
        }

        public void setCallingAddressAreaCode(String callingAddressAreaCode) {
            this.callingAddressAreaCode = callingAddressAreaCode;
        }

        public String getAnswerAddressAreaCode() {
            return answerAddressAreaCode;
        }

        public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
            this.answerAddressAreaCode = answerAddressAreaCode;
        }
    }

    public abstract static class CallChargeRule extends ChargeRule {
        abstract double calCost(ArrayList<CallRecord> callRecords);
    }
}
View Code

  在实现方法的过程中主要有以下几个问题:第一,类图中给出的方法不足以满足题目的需求,需要给个别类合理添加方法来实现需求,例如,校验用户重复,校验通话记录重复。第二,在计费算法的实现过程中需要获取时间差,这里我选用了SimpleDateFormat类来获取所需的时间。第三,在设计Main类中需要合理规划IPO,对于输入用户和输入通话记录要有所区分,并且大量使用正则表达式。

  在第一次的实现中,并没有考虑仔细输入用户与输入通话记录的分界点,把它们放在两个循环里读入,很难完美选择跳出循环的条件。


 

 第二次作业

  在第一次作业的基础上,新增了手机用户。这一次的迭代中需要我按照座机收费的类编写手机用户所需要的各种类。

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws ParseException {
        Controller controller = new Controller();
        Scanner in = new Scanner(System.in);
        ArrayList<User> users = new ArrayList<>();

        String line = in.nextLine();
        // 判断时间输入的正则表达式
        String datePatten = "(((\\d{3}[1-9]|\\d{2}[1-9]\\d|\\d[1-9]\\d{2}|[1-9]\\d{3})\\.(((0?[13578]|1[02])\\.(" +
                "[1-9]|[12]\\d|3[01]))|(([469]|11)\\.([1-9]|[12]\\d|30))|(2\\.([1-9]|1\\d|2[0-8]))))|(((" +
                "\\d{2})([48]|[2468][048]|[13579][26])|(([48]|[2468][048]|[3579][26])00))\\.2\\.29))" +
                "\\s([0-1]?\\d|2[0-3]):([0-5]\\d):([0-5]\\d)";

        //座机开户
        String Account1 = "u-0791\\d{7,8}\\s0";
        //手机开户
        String Account2 = "u-13\\d{9}\\s1";

        //座机打座机
        String Mode1 = "t-0791\\d{7,8}\\s" + "0\\d{9,11}\\s" + datePatten + "\\s" + datePatten;

        //座机打手机
        String Mode2 = "t-0791\\d{7,8}\\s" + "1\\d{10}\\s" + "0\\d{2,3}\\s" + datePatten + "\\s" + datePatten;
        //手机打座机
        String Mode3 = "t-1\\d{10}\\s" + "0\\d{2,3}\\s" + "0\\d{10,11}\\s" + datePatten + "\\s" + datePatten;
        //手机打手机
        String Mode4 = "t-1\\d{10}\\s" + "0\\d{2,3}\\s" + "1\\d{10}\\s" + "0\\d{2,3}\\s" + datePatten + "\\s" + datePatten;

        while (!line.equals("end")) {
            String[] data = line.split(" +");
            if (line.matches(Account1)) {
                controller.addLandLineUser(users, data);
            } else if (line.matches(Account2)) {
                controller.addCellPhoneUser(users, data);
            } else if (line.matches(Mode1)) { // 座机打座机
                controller.addLandLineCallRecord(users, data);
            } else if (line.matches(Mode2)) { // 座机打手机
                controller.addLandLineToCellPhoneRecord(users, data);
            } else if (line.matches(Mode3)) {
                controller.addCellPhoneToLandLineRecord(users, data);
            } else if (line.matches(Mode4)) {
                controller.addCellPhoneToCellPhoneRecord(users, data);
            }
            line = in.nextLine();
        }
        Collections.sort(users);
        for(User user:users){
            user.setBalance(user.calBalance());
            System.out.printf(user.getNumber() + " " + round(user.calCost()) + " " + round(user.getBalance()) + "%n");
        }
    }
    public static String round(double val) {
        BigDecimal bigDecimal = new BigDecimal(val);
        bigDecimal = bigDecimal.setScale(2, RoundingMode.HALF_UP);
        bigDecimal = bigDecimal.stripTrailingZeros();
        String ret = bigDecimal.toPlainString();
        if (!ret.contains(".")) {
            ret += ".0";
        }
        return ret;
    }

    public static class MessageRecord extends CommunicationRecord{
        private String message;
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    }

    public static class UserRecords {
        private ArrayList<CallRecord> callingInCityToProvinceRecords = new ArrayList<>();
        private ArrayList<CallRecord> callingInCityToLandRecords = new ArrayList<>();
        private ArrayList<CallRecord> callingInCityRecords= new ArrayList<>();
        private ArrayList<CallRecord> callingInProvinceRecords= new ArrayList<>();
        private ArrayList<CallRecord> callingInLandRecords= new ArrayList<>();
        private ArrayList<CallRecord> answerInCityRecords= new ArrayList<>();
        private ArrayList<CallRecord> answerInProvinceRecords= new ArrayList<>();
        private ArrayList<CallRecord> answerInLandRecords= new ArrayList<>();
        private ArrayList<MessageRecord> sendMessageRecords= new ArrayList<>();
        private ArrayList<MessageRecord> receiveMessageRecords= new ArrayList<>();
    
        public ArrayList<CallRecord> getCallingInCityToProvinceRecords() {
            return callingInCityToProvinceRecords;
        }
    
        public void addCallingInCityToProvinceRecords(CallRecord callRecord) {
            if (!checkRepeat(callRecord, getCallingInCityToProvinceRecords()))
              callingInCityToProvinceRecords.add(callRecord);
        }
    
        public ArrayList<CallRecord> getCallingInCityToLandRecords() {
            return callingInCityToLandRecords;
        }
    
        public void addCallingInCityToLandRecords(CallRecord callRecord) {
            if (!checkRepeat(callRecord, getCallingInCityToLandRecords())){
                callingInCityToLandRecords.add(callRecord);
            }
        }
    
        public void addCallingInCityRecords(CallRecord callRecord){
            if (!checkRepeat(callRecord, getCallingInCityRecords()))
                callingInCityRecords.add(callRecord);
        }
    
        public void addCallingInProvinceRecords(CallRecord callRecord){
            if (!checkRepeat(callRecord, getCallingInProvinceRecords()))
                callingInProvinceRecords.add(callRecord);
        }
    
        public void addCallingInLandRecords(CallRecord callRecord){
            if (!checkRepeat(callRecord, getCallingInLandRecords()))
                callingInLandRecords.add(callRecord);
        }
    
        public void addAnswerInCityRecords(CallRecord answerRecord){
            if (!checkRepeat(answerRecord, getAnswerInCityRecords()))
                answerInCityRecords.add(answerRecord);
        }
    
        public void addAnswerInProvinceRecords(CallRecord answerRecord){
            if (!checkRepeat(answerRecord, getAnswerInProvinceRecords()))
                answerInProvinceRecords.add(answerRecord);
        }
    
        public void addAnswerInLandRecords(CallRecord answerRecord){
            if (!checkRepeat(answerRecord, getAnswerInLandRecords()))
                answerInLandRecords.add(answerRecord);
        }
    
        public void addSendMessageRecords(MessageRecord messageRecord){
            sendMessageRecords.add(messageRecord);
        }
    
        public void addReceiveMessageRecords(MessageRecord messageRecord){
            receiveMessageRecords.add(messageRecord);
        }
    
        public ArrayList<CallRecord> getCallingInCityRecords() {
            return callingInCityRecords;
        }
    
        public ArrayList<CallRecord> getCallingInProvinceRecords() {
            return callingInProvinceRecords;
        }
    
        public ArrayList<CallRecord> getCallingInLandRecords() {
            return callingInLandRecords;
        }
    
        public ArrayList<CallRecord> getAnswerInCityRecords() {
            return answerInCityRecords;
        }
    
        public ArrayList<CallRecord> getAnswerInProvinceRecords() {
            return answerInProvinceRecords;
        }
    
        public ArrayList<CallRecord> getAnswerInLandRecords() {
            return answerInLandRecords;
        }
    
        public ArrayList<MessageRecord> getSendMessageRecords() {
            return sendMessageRecords;
        }
    
        public ArrayList<MessageRecord> getReceiveMessageRecords() {
            return receiveMessageRecords;
        }
    
        public boolean checkRepeat(CallRecord record, ArrayList<CallRecord> records){
            for (CallRecord rd:records){
                if (rd.getStartTime() == record.getStartTime() && rd.getEndTime() == record.getEndTime()){
                    return true;
                }
                if (record.getCallingNumber().equals(record.getAnswerNumber())){
                    return true;
                }
            }
            return false;
        }
    }

    public static class User implements Comparable<User>{
        private UserRecords userRecords = new UserRecords();
        private double balance;
        private ChargeMode chargeMode;
        private String number;
    
        public User(){}
    
        public User(double balance, ChargeMode chargeMode, String number) {
            this.balance = balance;
            this.chargeMode = chargeMode;
            this.number = number;
        }
    
        public double calCost(){
            return chargeMode.calCost(userRecords);
        }
    
        public double calBalance(){
            return balance - calCost() - chargeMode.getMonthlyRent();
        }
    
        public UserRecords getUserRecords() {
            return userRecords;
        }
    
        public void setUserRecords(UserRecords userRecords) {
            this.userRecords = userRecords;
        }
    
        public double getBalance() {
            return balance;
        }
    
        public void setBalance(double balance) {
            this.balance = balance;
        }
    
        public ChargeMode getChargeMode() {
            return chargeMode;
        }
    
        public void setChargeMode(ChargeMode chargeMode) {
            this.chargeMode = chargeMode;
        }
    
        public String getNumber() {
            return number;
        }
    
        public void setNumber(String number) {
            this.number = number;
        }
    
        public int compareTo(User user) {
            return getNumber().compareTo(user.getNumber());
        }
    }

    public static class LandPhoneInProvinceRule extends CallChargeRule{
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            long diff = 0;
            long minutes = 0;
            long second = 0;
            double result = 0;
            for (CallRecord callRecord:callRecords){
                diff = callRecord.getStartTime().getTime() - callRecord.getEndTime().getTime();
                minutes = diff / (1000 * 60);
                second = (diff - minutes * (1000 * 60)) / (1000);
                if ( second != 0){
                    minutes--;
                }
                result += - minutes * 0.3;
            }
            return result;
        }
    }

    public static class LandPhoneInlandRule extends CallChargeRule{
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            long diff = 0;
            long minutes = 0;
            long second = 0;
            double result = 0;
            for (CallRecord callRecord:callRecords){
                diff = callRecord.getStartTime().getTime() - callRecord.getEndTime().getTime();
                minutes = diff / (1000 * 60);
                second = (diff - minutes * (1000 * 60)) / (1000);
                if ( second != 0){
                    minutes--;
                }
                result += - minutes * 0.6;
            }
            return result;
        }
    }

    public static class LandPhoneInCityRule extends CallChargeRule{
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            long diff = 0;
            long minutes = 0;
            long second = 0;
            double result = 0;
            for (CallRecord callRecord:callRecords){
                diff = callRecord.getStartTime().getTime() - callRecord.getEndTime().getTime();
                minutes = diff / (1000 * 60);
                second = (diff - minutes * (1000 * 60)) / (1000);
                if ( second != 0){
                    minutes--;
                }
                result += - minutes * 0.1;
            }
            return result;
        }
    }

    public static class LandlinePhoneCharging extends ChargeMode{
        private double monthlyRent = 20;
    
        public LandlinePhoneCharging(){
            getChargeRules().add(new LandPhoneInCityRule());
            getChargeRules().add(new LandPhoneInlandRule());
            getChargeRules().add(new LandPhoneInProvinceRule());
        }
    
        @Override
        public double calCost(UserRecords userRecords) {
            double cost = 0;
            cost += getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords());
            cost += getChargeRules().get(1).calCost(userRecords.getCallingInLandRecords());
            cost += getChargeRules().get(2).calCost(userRecords.getCallingInProvinceRecords());
            return cost;
        }
    
        @Override
        public double getMonthlyRent() {
            return monthlyRent;
        }
    }

    public static class Controller {
        /**
         * CellPhone to CellPhone
         * @param users
         * @param data
         */
        public void addCellPhoneToCellPhoneRecord(ArrayList<User> users, String[] data) throws ParseException{
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
            Date StartDate;
            Date EndDate;
            String callNumber = data[0].substring(2);
            String answerNumber = data[2];
            StartDate = dateFormat.parse(data[4] + " " + data[5]);
            EndDate = dateFormat.parse(data[6] + " " + data[7]);
            CallRecord record = new CallRecord(callNumber, answerNumber, StartDate, EndDate);
            record.setCallingAddressAreaCode(data[1]);
            record.setAnswerAddressAreaCode(data[3]);
            for(User user:users){
                if (user.getNumber().equals(callNumber)){
                    int callPos = judgePos(record.getCallingAddressAreaCode());
                    int answerPos = judgePos(record.getAnswerAddressAreaCode());
                    if (callPos == 1 && answerPos == 1){
                        user.getUserRecords().addCallingInCityRecords(record);
                    } else if (callPos == 1 && answerPos == 2){
                        user.getUserRecords().addCallingInCityToProvinceRecords(record);
                    } else if (callPos == 2){
                        user.getUserRecords().addCallingInProvinceRecords(record);
                    } else if (callPos == 3) {
                        user.getUserRecords().addCallingInLandRecords(record);
                    } else if (callPos == 1 && answerPos == 3){
                        user.getUserRecords().addCallingInCityToLandRecords(record);
                    }
                }
                if (user.getNumber().equals(answerNumber)){
                    int pos = judgePos(record.getAnswerAddressAreaCode());
                    if (pos == 3){
                        user.getUserRecords().addAnswerInLandRecords(record);
                    }
                }
            }
        }
    
        /**
         * CellPhone to LandLine
         * @param users
         * @param data
         * @throws ParseException
         */
        public void addCellPhoneToLandLineRecord(ArrayList<User> users, String[] data) throws ParseException{
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
            Date StartDate;
            Date EndDate;
            String callNumber = data[0].substring(2);
            String answerNumber = data[2];
            StartDate = dateFormat.parse(data[3] + " " + data[4]);
            EndDate = dateFormat.parse(data[5] + " " + data[6]);
            CallRecord record = new CallRecord(callNumber, answerNumber, StartDate, EndDate);
            record.setCallingAddressAreaCode(data[1]);
            for (User user:users){
                if (user.getNumber().equals(callNumber)){
                    int answerPos = judgePos(record.getAnswerAddressAreaCode());
                    int callPos = judgePos(record.getCallingAddressAreaCode());
                    if (answerPos == 1 && callPos  == 1){
                        user.getUserRecords().addCallingInCityRecords(record);
                    } else if (callPos == 1 && answerPos == 2){
                        user.getUserRecords().addCallingInCityToProvinceRecords(record);
                    } else if (callPos == 2){
                        user.getUserRecords().addCallingInProvinceRecords(record);
                    } else if (callPos == 3){
                        user.getUserRecords().addCallingInLandRecords(record);
                    } else if (callPos == 1 && answerPos == 3){
                        user.getUserRecords().addCallingInCityToLandRecords(record);
                    }
                }
            }
    
        }
    
        /**
         * Landline to CellPhone
         * @param users
         * @param data
         * @throws ParseException
         */
        public void addLandLineToCellPhoneRecord(ArrayList<User> users, String[] data) throws ParseException {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
            Date StartDate;
            Date EndDate;
            String callNumber = data[0].substring(2);
            String answerNumber = data[1];
            StartDate = dateFormat.parse(data[3] + " " + data[4]);
            EndDate = dateFormat.parse(data[5] + " " + data[6]);
            CallRecord record = new CallRecord(callNumber, answerNumber, StartDate, EndDate);
            record.setAnswerAddressAreaCode(data[2]);
            for (User user: users){
                if (user.getNumber().equals(callNumber)){
                    int pos = judgePos(record.getAnswerAddressAreaCode());
                    switch (pos){
                        case 1:user.getUserRecords().addCallingInCityRecords(record);break;
                        case 2:user.getUserRecords().addCallingInProvinceRecords(record);break;
                        case 3:user.getUserRecords().addCallingInLandRecords(record);break;
                    }
                }
                if (user.getNumber().equals(answerNumber)){
                    int pos = judgePos(record.getAnswerAddressAreaCode(), record.getCallingAddressAreaCode());
                    switch (pos){
                        case 1: user.getUserRecords().addAnswerInCityRecords(record);break;
                        case 2: user.getUserRecords().addAnswerInProvinceRecords(record);break;
                        case 3: user.getUserRecords().addAnswerInLandRecords(record);break;
                    }
                }
            }
        }
    
        /**
         * Landline to Landline
         * @param users
         * @param data
         * @throws ParseException
         */
        public void addLandLineCallRecord(ArrayList<User> users, String[] data) throws ParseException {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
            Date StartDate;
            Date EndDate;
            String callNumber = data[0].substring(2);
            String answerNumber = data[1];
            StartDate = dateFormat.parse(data[2] + " " + data[3]);
            EndDate = dateFormat.parse(data[4] + " " + data[5]);
            CallRecord record = new CallRecord(callNumber, answerNumber, StartDate, EndDate);
            for (User user:users){
                if (user.getNumber().equals(callNumber)){
                    int pos = judgePos(record.getAnswerAddressAreaCode());
                    switch (pos){
                        case 1:user.getUserRecords().addCallingInCityRecords(record);break;
                        case 2:user.getUserRecords().addCallingInProvinceRecords(record);break;
                        case 3:user.getUserRecords().addCallingInLandRecords(record);break;
                    }
                }
            }
        }
    
        public  void addLandLineUser(ArrayList<User> users, String[] data) {
            if (!UserRepeat(data[0].substring(2), users)){
                User user = new User(100, new LandlinePhoneCharging(), data[0].substring(2));
                users.add(user);
            }
        }
    
        public boolean UserRepeat(String Number, ArrayList<User> users){
            for (User user: users){
                if (user.getNumber().equals(Number)){
                    return true;
                }
            }
            return false;
        }
    
        public  int judgePos(String AnswerNumber){
            if (AnswerNumber.matches("0791")) {
                return 1;
            }else if (AnswerNumber.matches("07(9[0|2-9]|01)")) {
                return 2;
            }else {
                return 3;
            }
        }
    
        public int judgePos(String answerAddressAreaCode, String callingAddressAreaCode){
            if (answerAddressAreaCode.matches("0791") && callingAddressAreaCode.matches("0791")){
                return 1;
            } else if (answerAddressAreaCode.matches("07(9[0|1-9]|01)")
                    && callingAddressAreaCode.matches("07(9[0|1-9]|01)")){
                return 2;
            } else {
                return 3;
            }
        }
    
        public void addCellPhoneUser(ArrayList<User> users, String[] data) {
            if (!UserRepeat(data[0].substring(2), users)){
                User user = new User(100, new CellPhoneCharging(), data[0].substring(2));
                users.add(user);
            }
        }
    }

    public abstract static class CommunicationRecord {
        protected String callingNumber;
        protected String answerNumber;
    
        public String getCallingNumber() {
            return callingNumber;
        }
    
        public void setCallingNumber(String callingNumber) {
            this.callingNumber = callingNumber;
        }
    
        public String getAnswerNumber() {
            return answerNumber;
        }
    
        public void setAnswerNumber(String answerNumber) {
            this.answerNumber = answerNumber;
        }
    }

    public abstract static class ChargeRule {
        abstract double calCost(ArrayList<CallRecord> callRecords);
    }

    public abstract static class ChargeMode {
        private ArrayList<ChargeRule> chargeRules = new ArrayList<>();
    
        public ArrayList<ChargeRule> getChargeRules() {
            return chargeRules;
        }
    
        public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
            this.chargeRules = chargeRules;
        }
    
        public abstract double calCost(UserRecords userRecords);
    
        public abstract double getMonthlyRent();
    }

    public static class CellPhoneInProvinceRule extends CallChargeRule{
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            long diff = 0;
            long minutes = 0;
            long second = 0;
            double result = 0;
            for (CallRecord callRecord:callRecords){
                diff = callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime();
                minutes = diff / (1000 * 60);
                second = (diff - minutes * (1000 * 60)) / (1000);
                if ( second != 0){
                    minutes++;
                }
                result += minutes * 0.3;
            }
            return result;
        }
    }

    public static class CellPhoneInLandRule extends CallChargeRule{
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            long diff = 0;
            long minutes = 0;
            long second = 0;
            double result = 0;
            for (CallRecord callRecord:callRecords){
                diff = callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime();
                minutes = diff / (1000 * 60);
                second = (diff - minutes * (1000 * 60)) / (1000);
                if ( second != 0){
                    minutes++;
                }
                result += minutes * 0.6;
            }
            return result;
        }
    }

    public static class CellPhoneInCityToProvinceRule extends CallChargeRule{
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            long diff = 0;
            long minutes = 0;
            long second = 0;
            double result = 0;
            for (CallRecord callRecord:callRecords){
                diff = callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime();
                minutes = diff / (1000 * 60);
                second = (diff - minutes * (1000 * 60)) / (1000);
                if ( second != 0){
                    minutes++;
                }
                result += minutes * 0.2;
            }
            return result;
        }
    }

    public static class CellPhoneInCityToLandRule extends CallChargeRule{
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            long diff = 0;
            long minutes = 0;
            long second = 0;
            double result = 0;
            for (CallRecord callRecord:callRecords){
                diff = callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime();
                minutes = diff / (1000 * 60);
                second = (diff - minutes * (1000 * 60)) / (1000);
                if ( second != 0){
                    minutes++;
                }
                result += minutes * 0.3;
            }
            return result;
        }
    }

    public static class CellPhoneInCityToCityRule extends CallChargeRule{
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            long diff = 0;
            long minutes = 0;
            long second = 0;
            double result = 0;
            for (CallRecord callRecord:callRecords){
                diff = callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime();
                minutes = diff / (1000 * 60);
                second = (diff - minutes * (1000 * 60)) / (1000);
                if ( second != 0){
                    minutes++;
                }
                result += minutes * 0.1;
            }
            return result;
        }
    }

    public static class CellPhoneCharging extends ChargeMode {
        private double MonthlyRent = 15;
    
        public CellPhoneCharging(){
            getChargeRules().add(new CellPhoneInCityToCityRule());
            getChargeRules().add(new CellPhoneInCityToProvinceRule());
            getChargeRules().add(new CellPhoneInCityToLandRule());
            getChargeRules().add(new CellPhoneInProvinceRule());
            getChargeRules().add(new CellPhoneInLandRule());
            getChargeRules().add(new AnswerOutOfProvinceRule());
        }
    
        @Override
        public double calCost(UserRecords userRecords) {
            double cost = 0;
            cost += getChargeRules().get(0).calCost(userRecords.getCallingInCityRecords());
            cost += getChargeRules().get(1).calCost(userRecords.getCallingInCityToProvinceRecords());
            cost += getChargeRules().get(2).calCost(userRecords.getCallingInCityToLandRecords());
            cost += getChargeRules().get(3).calCost(userRecords.getCallingInProvinceRecords());
            cost += getChargeRules().get(4).calCost(userRecords.getCallingInLandRecords());
            cost += getChargeRules().get(5).calCost(userRecords.getAnswerInLandRecords());
            return cost;
        }
    
        @Override
        public double getMonthlyRent() {
            return MonthlyRent;
        }
    }

    public static class CallRecord extends CommunicationRecord {
        private Date startTime;
        private Date endTime;
        private String callingAddressAreaCode;
        private String answerAddressAreaCode;
        public CallRecord(String callNumber, String answerNumber, Date startTime, Date endTime){
            setCallingNumber(callNumber);
            setAnswerNumber(answerNumber);
            this.startTime = startTime;
            this.endTime = endTime;
            callingAddressAreaCode = callNumber.substring(0, 4);
            answerAddressAreaCode = answerNumber.substring(0, 4);
        }
    
        public Date getStartTime() {
            return startTime;
        }
    
        public void setStartTime(Date startTime) {
            this.startTime = startTime;
        }
    
        public Date getEndTime() {
            return endTime;
        }
    
        public void setEndTime(Date endTime) {
            this.endTime = endTime;
        }
    
        public String getCallingAddressAreaCode() {
            return callingAddressAreaCode;
        }
    
        public void setCallingAddressAreaCode(String callingAddressAreaCode) {
            this.callingAddressAreaCode = callingAddressAreaCode;
        }
    
        public String getAnswerAddressAreaCode() {
            return answerAddressAreaCode;
        }
    
        public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
            this.answerAddressAreaCode = answerAddressAreaCode;
        }
    }

    public abstract static class CallChargeRule extends ChargeRule {
        abstract double calCost(ArrayList<CallRecord> callRecords);
    }

    public static class AnswerOutOfProvinceRule extends AnswerChargeRule{
        @Override
        double calCost(ArrayList<CallRecord> callRecords) {
            long diff = 0;
            long minutes = 0;
            long second = 0;
            double result = 0;
            for (CallRecord callRecord:callRecords){
                diff = callRecord.getEndTime().getTime() - callRecord.getStartTime().getTime();
                minutes = diff / (1000 * 60);
                second = (diff - minutes * (1000 * 60)) / (1000);
                if ( second != 0){
                    minutes++;
                }
                result += minutes * 0.3;
            }
            return result;
        }
    }

    public abstract static class AnswerChargeRule extends ChargeRule {
        abstract double calCost(ArrayList<CallRecord> callRecords);
    }
}

 

  这一次迭代由于初代版本已经做好了相应的拓展性,并没有花费太多的时间。吸取第一次Main类的设计失误,这次对Main类进行了重构,新增了Controller类用作解耦合。main方法中的代码更加简洁。在这次迭代中主要的难点在于对呼叫用户和接听用户的类型进行分类,并对每一种通话类型进行地区分类,再收录进相应的record。最后进行计算。

 


第三次作业:

  第三次作业是对短信的单独计费,难度在于计费算法以及识别合法短信的正则表达式。

  1 import java.math.BigDecimal;
  2 import java.math.RoundingMode;
  3 import java.util.ArrayList;
  4 import java.util.Collections;
  5 import java.util.Scanner;
  6 
  7 public class Main {
  8     public static void main(String[] args) {
  9         Controller controller = new Controller();
 10         Scanner in = new Scanner(System.in);
 11         ArrayList<User> users = new ArrayList<>();
 12 
 13         String Account = "u-1\\d{10}\\s3";
 14         String Message = "^m-1\\d{10} 1\\d{10}\\s[\\w\\d\\s,.]+$";
 15 
 16         String line = in.nextLine();
 17 
 18         while (!line.equals("end")){
 19             if (line.matches(Account)){
 20                 controller.addCellPhoneUser(users, line);
 21             } else if (line.matches(Message)){
 22                 controller.addMessage(users, line);
 23             }
 24             line = in.nextLine();
 25         }
 26         Collections.sort(users);
 27         for(User user:users){
 28             user.setBalance(user.calBalance());
 29             System.out.printf(user.getNumber() + " " + round(user.calCost()) + " " + round(user.getBalance()) + "%n");
 30         }
 31     }
 32 
 33     public static String round(double val) {
 34         BigDecimal bigDecimal = new BigDecimal(val);
 35         bigDecimal = bigDecimal.setScale(2, RoundingMode.HALF_UP);
 36         bigDecimal = bigDecimal.stripTrailingZeros();
 37         String ret = bigDecimal.toPlainString();
 38         if (!ret.contains(".")) {
 39             ret += ".0";
 40         }
 41         return ret;
 42     }
 43 
 44     public static class MessageChargeRule extends ChargeRule{
 45     
 46         @Override
 47         double calCost(ArrayList<MessageRecord> messageRecords) {
 48             double cost = 0;
 49             double fee = 0;
 50             int n = 0;
 51             for (MessageRecord record:messageRecords){
 52                 if (record.getMessage().length() < 10){
 53                     n++;
 54                 } else {
 55                     int text = 0;
 56                     text = record.getMessage().length() / 10;
 57                     int length = record.getMessage().length();
 58                     int mod = record.getMessage().length() % 10;
 59                     if (record.getMessage().length() % 10 != 0){
 60                         text++;
 61                     }
 62                     n += text;
 63                 }
 64             }
 65             if (n < 3){
 66                 fee = 0.1;
 67                 cost = n * fee;
 68             } else if (n < 5){
 69                 fee = 0.2;
 70                 cost = 0.1 * 3 + 0.2 * (n - 3);
 71             } else {
 72                 fee = 0.3;
 73                 cost = 0.1 * 3 + 0.2 * 2 + 0.3 * (n - 5);
 74             }
 75     
 76             return cost;
 77         }
 78     }
 79 
 80     public static class MessageRecord extends CommunicationRecord{
 81         private String message;
 82     
 83         public String getMessage() {
 84             return message;
 85         }
 86     
 87         public void setMessage(String message) {
 88             this.message = message;
 89         }
 90     }
 91 
 92     public static class User implements Comparable<User>{
 93         private UserRecords userRecords = new UserRecords();
 94         private double balance;
 95         private ChargeMode chargeMode;
 96         private String number;
 97     
 98         public User(){}
 99     
100         public User(double balance, ChargeMode chargeMode, String number) {
101             this.balance = balance;
102             this.chargeMode = chargeMode;
103             this.number = number;
104         }
105     
106         public double calCost(){
107             return chargeMode.calCost(userRecords);
108         }
109     
110         public double calBalance(){
111             return balance - calCost() - chargeMode.getMonthlyRent();
112         }
113     
114         public UserRecords getUserRecords() {
115             return userRecords;
116         }
117     
118         public void setUserRecords(UserRecords userRecords) {
119             this.userRecords = userRecords;
120         }
121     
122         public double getBalance() {
123             return balance;
124         }
125     
126         public void setBalance(double balance) {
127             this.balance = balance;
128         }
129     
130         public ChargeMode getChargeMode() {
131             return chargeMode;
132         }
133     
134         public void setChargeMode(ChargeMode chargeMode) {
135             this.chargeMode = chargeMode;
136         }
137     
138         public String getNumber() {
139             return number;
140         }
141     
142         public void setNumber(String number) {
143             this.number = number;
144         }
145     
146         public int compareTo(User user) {
147             return getNumber().compareTo(user.getNumber());
148         }
149     }
150 
151     public static class UserRecords {
152         private ArrayList<MessageRecord> sendMessageRecords= new ArrayList<>();
153         private ArrayList<MessageRecord> receiveMessageRecords= new ArrayList<>();
154     
155         public ArrayList<MessageRecord> getSendMessageRecords() {
156             return sendMessageRecords;
157         }
158     
159         public ArrayList<MessageRecord> getReceiveMessageRecords() {
160             return receiveMessageRecords;
161         }
162     
163         public void addSendMessageRecords(MessageRecord messageRecord){
164             sendMessageRecords.add(messageRecord);
165         }
166     
167         public void addReceiveMessageRecords(MessageRecord messageRecord){
168             receiveMessageRecords.add(messageRecord);
169         }
170     }
171 
172     public static class Controller {
173         public void addCellPhoneUser(ArrayList<User> users, String line) {
174             String[] data = line.split(" +");
175             if (!UserRepeat(data[0].substring(2), users)){
176                 User user = new User(100, new CellPhoneMessageCharging(), data[0].substring(2));
177                 users.add(user);
178             }
179         }
180     
181         public boolean UserRepeat(String Number, ArrayList<User> users){
182             for (User user: users){
183                 if (user.getNumber().equals(Number)){
184                     return true;
185                 }
186             }
187             return false;
188         }
189     
190         public void addMessage(ArrayList<User> users, String line){
191             String[] data = line.split(" +");
192             String Sender = data[0].substring(2);
193             String Receiver = data[1];
194             String text = line.substring(26);
195             MessageRecord messageRecord = new MessageRecord();
196             messageRecord.setMessage(text);
197             messageRecord.setCallingNumber(Sender);
198             messageRecord.setAnswerNumber(Receiver);
199             for (User user:users){
200                 if (user.getNumber().equals(Sender)){
201                     user.getUserRecords().addSendMessageRecords(messageRecord);
202                 }
203                 if (user.getNumber().equals(Receiver)){
204                     user.getUserRecords().addReceiveMessageRecords(messageRecord);
205                 }
206             }
207         }
208     }
209 
210     public abstract static class CommunicationRecord {
211         protected String callingNumber;
212         protected String answerNumber;
213     
214         public String getCallingNumber() {
215             return callingNumber;
216         }
217     
218         public void setCallingNumber(String callingNumber) {
219             this.callingNumber = callingNumber;
220         }
221     
222         public String getAnswerNumber() {
223             return answerNumber;
224         }
225     
226         public void setAnswerNumber(String answerNumber) {
227             this.answerNumber = answerNumber;
228         }
229     }
230 
231     public abstract static class ChargeRule {
232         abstract double calCost(ArrayList<MessageRecord> messageRecords);
233     }
234 
235     public abstract static class ChargeMode {
236         private ArrayList<ChargeRule> chargeRules = new ArrayList<>();
237     
238         public ArrayList<ChargeRule> getChargeRules() {
239             return chargeRules;
240         }
241     
242         public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
243             this.chargeRules = chargeRules;
244         }
245     
246         public abstract double calCost(UserRecords userRecords);
247     
248         public abstract double getMonthlyRent();
249     }
250 
251     public static class CellPhoneMessageCharging extends ChargeMode {
252         private double MonthlyRent = 0;
253     
254         public CellPhoneMessageCharging(){
255             getChargeRules().add(new MessageChargeRule());
256         }
257         @Override
258         public double calCost(UserRecords userRecords) {
259             double cost = 0;
260             cost += getChargeRules().get(0).calCost(userRecords.getSendMessageRecords());
261             return cost;
262         }
263     
264         @Override
265         public double getMonthlyRent() {
266             return MonthlyRent;
267         }
268     }
269 }

踩坑心得:

  没有提前设计好main方法导致的一系列问题,各种问题堆叠在一起后就不得不重构代码,花费大量时间。编写核心代码不能浮躁,各种情况都要考虑到,不然核心代码出现问题后main函数基本要重构。


改进建议:

  对于简单的函数可以使用自动生成代码, 对于关联比较复杂的方法就需要自己动手编写,以防自动生成的代码有参数上的不一致。分配好设计与编码的比例,应该以设计为主,编码所需的时间应该适当降低,说不定能起到事半功倍的效果。


总结:

  在代码量提升后,面向对象程序设计原则的优越性就体现出来了。符合设计原则的代码能有很高的复用率,也更容易发现问题。在大量代码面前,统一的规范是必须的。这三次的迭代对我来说就是加强了对代码设计自我的要求,更严格的去按照所学的设计原则设计和编写代码,使得代码更加规范和美观。

posted @ 2022-06-15 23:38  哦嘞里个嘞  阅读(29)  评论(0)    收藏  举报