前言
关于此次题目集
这次的题目集包含了两种大作业类型:第一种是之前答题判题程序的延续,第二种则是新的家居强电电路模拟程序。第一种大作业发布时,我们并未学习继承和多态等面向对象的相关知识,因此最初的代码编写仅依赖于简单的语法。但是随着题目的逐步迭代,第四次作业的复杂度增加,已难以仅通过基本的语法知识来解决问题。为了解决这些复杂问题,我最终在部分类的设计中引入了继承和多态。而第二种大作业从一开始就要求使用继承和多态进行代码编写。
因此,这次题目集的主要知识点集中在继承和多态的设计与应用上。
虽然这次题目集的总题目数较上次有所减少,但由于大作业的题目要求更高、设计更复杂,花费的时间并没有减少。答题判题程序在最初并未采用继承和多态,随着任务的逐步复杂化,代码变得越来越杂乱,每次迭代都需要修改多个类中的代码,这导致代码不符合开闭原则。相反,家居强电电路模拟程序从一开始就采用了继承和多态的设计,这使得整体结构更加清晰,虽然代码行数较多,但因为设计逻辑明确,开发过程并没有预想中的那么复杂。而且,在迭代过程中,代码结构符合开闭原则,新增功能时并未对原有代码进行大规模修改,整体维护性和扩展性得到了显著提升。
设计与分析
作业4 7-3 答题判题程序-4
设计
思路
这次迭代在上次作业的基础上,对题目进行了类型划分,分为普通题目、多选题和填空题。此外,多选题和填空题还可能存在部分正确的情况。按照以往的做法,我需要为不同类型的题目分别创建多个数组进行存储,这样不仅代码编写复杂,实现困难,而且可读性和可维护性较差,违背了Java的七大设计原则。为了改进,我对部分代码进行了重构。具体来说,我为不同类型的题目创建了一个父类,各种题目类型继承该父类。这样,我就可以通过一个数组统一存储不同类型的题目,并且可以重写每种题目类型的正确性判定方法。通过Java的动态绑定机制,不同的子类会自动调用各自的实现方法,从而简化了不同题目类型的处理过程,提升了代码的可维护性和可扩展性。
类图
输出最后结果的时序图
分析
报表数据
通过报表数据可以发现这次作业存在不足,例如注释较少, 并且最大圈复杂度过高。
答卷类
在这次迭代中,我将原本用于存储答案的一维数组改为了二维数组,以更好地支持多选题和填空题中可能存在的多种答案存储方式。同时,我对答案判定方法进行了优化,不仅保留了传统的对错判定,还新增了部分正确答案的判断逻辑,从而提高了系统对复杂情况的适应性和准确性。
1 class AnswerSheet implements Comparable<AnswerSheet> { 2 protected int tot = 0; 3 protected Student stu; 4 protected ExaminationPaper examinationPaper = new ExaminationPaper();// 试卷 5 private ArrayList<ArrayList<String>> answer = new ArrayList<>();// 答案 6 protected ArrayList<Integer> result = new ArrayList<>();// 结果 0是错 1是对 2是半对 7 8 /* 9 其它方法 10 */ 11 }点击展开答卷类代码
题目类
将这个类修改为各种题目类型的父类,其作为一个通用模板,定义了所有题目类型共有的特性和行为。通过这个父类,可以做到对所有不同题目类型进行统一管理。
1 // 题目类 2 class Topic { 3 protected int type = 0;//题目类型 1是普通题 2是多选 3是填空 4 protected int topicID = -1;// 题号 5 protected String content = "0+0";// 内容 6 protected ArrayList<String> standardAnswer = new ArrayList<>();//答案 7 8 /* 9 其它方法 10 */ 11 12 //判断题目对错 13 public Integer Judge(ArrayList<String> answer) { 14 if (type == 1) { 15 if (answer.equals(standardAnswer)) 16 return 1; 17 return 0; 18 } else { 19 int sum = 0; 20 for (int i = 0 ; i < answer.size(); i++) { 21 if (standardAnswer.contains(answer.get(i).trim())) { 22 sum++; 23 } else { 24 return 0; 25 } 26 } 27 if (sum == standardAnswer.size()) 28 return 1; 29 else if (sum == 0) 30 return 0; 31 return 2; 32 } 33 } 34 35 }点击展开题目类
多选题类
多选题类通过继承题目类,能够复用其属性与方法。同时多选题类有自己特点的构造方法。这样,在处理不同类型的题目时,可以根据题目的种类选择相应的类构造函数来创建不同的题目对象,从而实现代码的高效复用和灵活扩展。
1 //多选题类 2 class MultipleChoiceQuestions extends Topic { 3 4 public MultipleChoiceQuestions() {} 5 6 /* 7 * 格式 8 * "#Z:"+题号+" "+"#Q:"+题目内容+" "#A:"+标准答案 9 */ 10 public MultipleChoiceQuestions(String str) { 11 type = 2; 12 String[] parts = str.split("#Z:"); 13 parts = parts[1].split("#Q:"); 14 super.topicID = Integer.valueOf(parts[0].trim()); 15 str = parts[1]; 16 parts = str.split("#A:"); 17 super.content = parts[0] ; 18 19 if (parts.length > 1) { 20 parts = parts[1].split(" "); 21 for (int i = 0; i < parts.length; i++) { 22 this.standardAnswer.add(parts[i] ); 23 } 24 } 25 } 26 }点击展开多选题类
填空题类
继承题目类的属性和方法,与多选题类相似。
1 //填空题类 2 class FillBlankQuestions extends Topic { 3 4 /* 5 * 格式 6 * "#k:"+题号+" "+"#Q:"+题目内容+" "#A:"+标准答案 7 */ 8 public FillBlankQuestions(String str) { 9 type = 3; 10 String[] parts = str.split("#K:"); 11 parts = parts[1].split("#Q:"); 12 super.topicID = Integer.valueOf(parts[0].trim()); 13 str = parts[1]; 14 parts = str.split("#A:"); 15 super.content = parts[0] ; 16 17 if (parts.length > 1) { 18 parts = parts[1].split("或"); 19 for (int i = 0; i < parts.length; i++) { 20 this.standardAnswer.add(parts[i] ); 21 } 22 } 23 } 24 }点击展开填空题类
试卷类
每个题目都拥有一个分数信息,并且相同的题目在不同的试卷中其分数是不相同的,故我们在试卷类中新增一个分数属性用于存储试卷中对应题目的分数信息,为了满足动态存储的需求,我们同样使用了ArrayList 作为属性的类型。由于对于每张试卷我们都需要判断其总分是否是 100 分,于是我们在试卷类中设计了一个checkTheExamPapers() 方法用于对试卷总分进行判断。
1 // 试卷类 2 class ExaminationPaper { 3 private int tot = 0; 4 private int examinationPaperID = 0; 5 private ArrayList<Topic> topics = new ArrayList<>();// 本张试卷的题目 6 private ArrayList<Integer> scores = new ArrayList<>();// 对应题目的分数 7 8 /* 9 其它一些方法 10 */ 11 12 //判断 13 public Integer Judge(int num, ArrayList<String> answer) { 14 return topics.get(num).Judge(answer); 15 } 16 17 public boolean checkTheExamPapers() { 18 // 判断是否满100分 19 int allScore = 0; 20 for (Integer score : scores) { 21 allScore += score; 22 } 23 if (allScore != 100) 24 return false; 25 return true; 26 } 27 }点击展开试卷类
试卷集类
与题目集类相似,每张答卷都对应了不同的编号试卷,并且试卷的编号是不连续的,而我们需要预先知道不同编号对应的是哪些试卷,所有我们同样写了一个试卷集类,通过类中设置 HashMap 类属性,对应程序中的每张试卷进行存储,当我们需要使用某张试卷时,我们只需要通过寻找相应的 Key 值即可。
1 // 试卷集 2 class ExaminationPapers { 3 private HashMap<Integer, ExaminationPaper> examinationPapers = new HashMap<>();// 编号对应的答卷 4 5 public HashMap<Integer, ExaminationPaper> getExaminationPapers() { 6 return examinationPapers; 7 } 8 9 public void addExaminationPaper(ExaminationPaper examinationPaper) { 10 examinationPapers.put(examinationPaper.getExaminationPaperID(), examinationPaper); 11 } 12 13 public void checkTheExamPapers() { 14 for (Map.Entry<Integer, ExaminationPaper> entry : examinationPapers.entrySet()) { 15 if (!entry.getValue().checkTheExamPapers()) 16 System.out.println("alert: full score of test paper" + entry.getKey() + " is not 100 points"); 17 18 } 19 } 20 }点击展开试卷集类代码
考试类
为了能够查找我们以及存储了哪些题目以及试卷,我们需要在考试类中分别创建题目集类以及试卷集类的属性,同时我们需要存储每张答卷的信息,于是我们需要再设置一个属性用于存储答卷,为了便于动态存储,我们需要使用 ArrayList 来进行存储,在我们输出信息时我们只需要调用每张答卷的方法即可。
1 // 考试类,包含所有题目以及试卷以及所有考卷 2 class Exam { 3 private Topics topics = new Topics();// 题目集,试卷中的题目是题目集的子集 4 private Students students = new Students();// 学生集,包含所有学生信息 5 private ExaminationPapers examinationPapers = new ExaminationPapers();// 试卷集 6 private ArrayList<AnswerSheet> answerSheets = new ArrayList<>(); 7 8 /* 9 其它一些属性和方法 10 */ 11 12 public void addExaminationPaper(String str) { 13 ExaminationPaper examinationPaper = new ExaminationPaper(); 14 String[] parts = str.split(" "); 15 16 for (String part : parts) { 17 if (part.contains("-")) { 18 String[] range = part.split("-"); 19 int topicNumber = Integer.valueOf(range[0].trim()); 20 int score = Integer.valueOf(range[1].trim()); 21 22 if (topics.getTopics().containsKey(topicNumber)) { 23 examinationPaper.addInfo(topics.getTopics().get(topicNumber), score); 24 } else { 25 examinationPaper.addInfo(new Topic(), 0); 26 } 27 28 } else if (part.startsWith("#T:")) { 29 examinationPaper.setExaminationPaperID(Integer.valueOf(part.substring(3).trim()));// 试卷编号 30 } 31 } 32 33 examinationPapers.addExaminationPaper(examinationPaper); 34 } 35 36 }点击展开考试类
作业5 7-1 家居强电电路模拟程序-1
设计
思路
本次作业涉及电路知识,首先我们可以想到为每种设备设计一个类。然而,不同设备往往具有一些相同的属性和行为,因此我们可以为它们创建一个共同的父类,将这些共享的属性和方法放在父类中。考虑到电路中常见的串联和并联情形,我们可以将串联或并联的电路视作一种设备,并让其继承自相同的父类,以便于编码与计算。根据电路的基本原理,每种设备的电阻是其固有属性,而设备通过的电流由其两端的电压决定。因此,我们可以通过已知的电流值来计算设备两端的电压,从而判断设备的工作状态。
虽然本次作业中并未涉及并联电路的实现,但这一设计方案符合开闭原则(Open/Closed Principle),为将来作业的扩展和迭代提供了极大的便利,能够在不修改现有代码的前提下,轻松添加新的功能或设备。
类图
计算电阻以及电流时序图
分析
报表数据
通过报表数据可以发现这次作业存在不足,例如注释较少, 并且最大圈复杂度过高。
电路设备类
将电路设备类设定为一个抽象类作为电路设备系统中的基础类,包含了电路设备共有的属性和方法。具体的电路设备(如风扇、开关、灯等)可以继承此类,并实现特定的行为。这个类的设计思想是通过抽象和继承来实现电路设备的多态性和灵活性,使得不同设备可以通过统一的接口进行管理和操作。
1 //电路设备 2 abstract class CircuitEquipment { 3 private CircuitEquipment[] pin = new CircuitEquipment[3]; 4 private int ID; 5 private String name; 6 private double voltage;//电压 7 private double resistance;//电阻 8 private double current;//电流 9 10 public static CircuitEquipment create(String str) { 11 if (str.equals("VCC")) 12 return new VCC(); 13 else if (str.charAt(0) == 'K') 14 return new Switch(str); 15 else if (str.charAt(0) == 'F') 16 return new GradeGovernor(str); 17 else if (str.charAt(0) == 'L') 18 return new ContinuousGovernor(str); 19 else if (str.charAt(0) == 'B') 20 return new IncandescentLamp(str); 21 else if (str.charAt(0) == 'R') 22 return new FluorescentLamp(str); 23 else if (str.charAt(0) == 'D') 24 return new CeilingFan(str); 25 else 26 return null; 27 } 28 29 /* 30 其它方法 31 */ 32 33 //电流从这个设备流向哪个设备 34 public void connect(String deviceA, CircuitEquipment circuitEquipment) { 35 String[] parts = deviceA.split("-"); 36 int pinIndex = Integer.parseInt(parts[1]); 37 pin[pinIndex] = circuitEquipment; 38 } 39 40 41 }点击展开电路设备类
控制设备类
该类继承自电路设备类,不仅继承了电路设备的属性和方法,还作为一个抽象类,用于定义控制设备的共有属性和方法。具体的控制设备可以基于此类进行扩展,并实现其特定的功能和行为。此外,该类还设定了一个抽象方法,要求子类必须实现该方法,从而确保不同控制设备能够提供定制化的操作。
1 //控制设备 2 abstract class ControlEquipment extends CircuitEquipment { 3 4 public abstract double getOutVoltage(double voltage); 5 6 @Override 7 public void setVoltage(double voltage) { 8 super.setVoltage(voltage); 9 } 10 11 @Override 12 public void setResistance(double resistance) { 13 super.setResistance(resistance); 14 } 15 16 @Override 17 public double getVoltage() { 18 return super.getVoltage(); 19 } 20 21 @Override 22 public double getResistance() { 23 return super.getResistance(); 24 } 25 26 @Override 27 public void setName(String name) { 28 super.setName(name); 29 } 30 31 @Override 32 public int getID() { 33 return super.getID(); 34 } 35 36 @Override 37 public void setID(int ID) { 38 super.setID(ID); 39 } 40 41 @Override 42 public String getName() { 43 return super.getName(); 44 } 45 }控制设备类
受控设备类
该类同样继承自电路设备类,同时也作为一个抽象类,用于定义受控设备(风扇、灯等)的共有属性和方法。具体的受控设备可以基于此类进行扩展,并实现其特定的功能和行为。
1 //受控设备 2 abstract class ControlledEquipment extends CircuitEquipment { 3 private int openOrClose; 4 private int LowerLimitOfOperatingVoltage; 5 private int UpperLimitOfOperatingVoltage; 6 7 public int getLowerLimitOfOperatingVoltage() { 8 return LowerLimitOfOperatingVoltage; 9 } 10 11 public void setLowerLimitOfOperatingVoltage(int lowerLimitOfOperatingVoltage) { 12 LowerLimitOfOperatingVoltage = lowerLimitOfOperatingVoltage; 13 } 14 15 public int getUpperLimitOfOperatingVoltage() { 16 return UpperLimitOfOperatingVoltage; 17 } 18 19 public void setUpperLimitOfOperatingVoltage(int upperLimitOfOperatingVoltage) { 20 UpperLimitOfOperatingVoltage = upperLimitOfOperatingVoltage; 21 } 22 23 @Override 24 public void setVoltage(double voltage) { 25 super.setVoltage(voltage); 26 } 27 28 @Override 29 public void setResistance(double resistance) { 30 super.setResistance(resistance); 31 } 32 33 @Override 34 public double getVoltage() { 35 return super.getVoltage(); 36 } 37 38 @Override 39 public double getResistance() { 40 return super.getResistance(); 41 } 42 43 @Override 44 public void setName(String name) { 45 super.setName(name); 46 } 47 48 @Override 49 public int getID() { 50 return super.getID(); 51 } 52 53 @Override 54 public void setID(int ID) { 55 super.setID(ID); 56 } 57 }点击展开受控设备类
串联电路类
控制电路类继承了电路设备类,这意味着串联电路也可以被视作一种电路设备进行编码。这种设计的核心思想是:在电路系统中,串联电路可以像其他用电器一样进行统一的计算和处理。通过将其抽象为电路设备,既简化了编码过程,又充分利用了工厂模式的优势,使得系统结构更加清晰和灵活。
作业6 7-1 家居强电电路模拟程序-2
设计
思路
这次作业在上次作业的基础上,新增了并联电路的处理。由于在上次作业中,我们已经将串联电路抽象为一种电路设备,因此在处理并联电路时,我们可以将每条支路视为一个独立的电路设备,这极大地方便了计算。更重要的是,我们只需新增一个并联电路类,无需修改其他现有类,这充分体现了Java的开闭原则和单一职责原则。此外,借助这种设计,我们也能够将并联电路视作一种电路设备,为下一次作业的迭代奠定了基础,使得系统更加灵活、易于扩展。
类图
并联电路计算数据时序图
分析
报表数据
通过报表数据可以发现这次作业存在不足,例如注释较少, 并且最大圈复杂度过高,但是平均圈复杂度比较低。
并联电路类
将并联电路设计为一个类,同时继承电路设备的属性和行为,即将其也视为一个电路设备。在计算电阻按照电路的规则,总电路等于分电阻倒数之和的倒数进行计算。
1 //并联电路 2 class ParallelCircuit extends CircuitEquipment { 3 4 ArrayList<CircuitEquipment> circuits = new ArrayList<>(); 5 6 public ParallelCircuit(String name) { 7 setName(name); 8 setID(Integer.parseInt(name.substring(1))); 9 } 10 11 public void create(String nameA, WayCircuit wayCircuit) { 12 CircuitEquipment deviceA = wayCircuit.getCircuitEquipment(nameA.split("-")[0]); 13 connect(deviceA); 14 } 15 16 public void connect(CircuitEquipment device) { 17 circuits.add(device); 18 } 19 20 public void calResistance() {//计算总电阻 21 double resistance = 0; 22 for (CircuitEquipment circuit : circuits) { 23 circuit.calResistance(); 24 resistance += 1.0 / circuit.getResistance(); 25 } 26 // resistance = 1.0 / resistance; 27 resistance = 100000 / (int)(resistance * 100000); 28 setResistance(resistance);//设置总电阻 29 } 30 31 public void calAnyVoltage() {//设置每个部件的电压 32 double v = getVoltage(); 33 for (CircuitEquipment circuit : circuits) { 34 circuit.setVoltage(v); 35 circuit.cal(); 36 } 37 } 38 39 public void cal() { 40 calResistance(); 41 calAnyVoltage(); 42 } 43 }点击展开并联电路
总电路类
在第一次迭代中,我将串联电路当作了总电路来进行计算,但是在第二次迭代中会发现,由于出现了并联电路,此时我们不再适合将串联电路当作一个总电路,因此我新创建了一个总电路类。在总电路类中存贮了出现的每种设备,并且按照题目规定顺序进行了排序,在计算电路时我们只需要找到VCC即可进行整个电路的遍历。
1 //总电路 2 class WayCircuit extends CircuitEquipment { 3 private TreeMap<String, CircuitEquipment> circuits = new TreeMap<>( 4 (a, b) -> { 5 // 定义排序顺序 6 String order = "KFLBRDAMTV"; 7 if (a.charAt(0) != b.charAt(0)) 8 return Integer.compare(order.indexOf(a.charAt(0)), order.indexOf(b.charAt(0))); 9 else 10 return a.compareTo(b); 11 } 12 ); 13 14 public TreeMap<String, CircuitEquipment> getCircuits() { 15 return circuits; 16 } 17 18 //找到对应设备 19 public CircuitEquipment getCircuitEquipment(String name) { 20 if (!circuits.containsKey(name)) {//如果之前没有这个设备就加入这个设备 21 circuits.put(name, create(name)); 22 } 23 return circuits.get(name); 24 } 25 26 public void adjust(String name, String operator) { 27 CircuitEquipment circuitEquipment = getCircuitEquipment(name); 28 circuitEquipment.adjust(operator); 29 } 30 31 public void print() { 32 CircuitEquipment cir = circuits.get("VCC").getPin()[1]; 33 cir.setVoltage(220); 34 cir.cal(); 35 36 for (CircuitEquipment circuit : circuits.values()) { 37 circuit.show(); 38 } 39 } 40 41 }点击展开总电路类
其它类
其它类与第一次迭代中的类基本保持一致,因为第一次迭代中的代码符合开闭原则,故类中代码并没有进行过多修改,只是在原有类的基础上新增添了两个新的类。
踩坑心得
关于总体框架
在开发答题判题程序时,由于我在初期设计阶段未能充分遵循 Java 的七大设计原则,导致程序在每次迭代中可读性和可维护性逐渐下降。每次修改时,我都需要调整多个类,修改过程既繁琐又低效。相比之下,在开发家具强电电路模拟程序时,我从一开始就将设计严格遵循 Java 的七大设计原则,这使得在第二次迭代时,只需新增两个类,而无需修改其他现有类,程序的更新变得简单而高效。因此,在设计程序时,我们应当提前规划好整体设计思路,并在初期就尽力将程序与 Java 的七大设计原则对接,这不仅能够显著提升程序的可读性和可维护性,还能大大方便后续的扩展和修改。
答题判题程序-4坑点
答案内容首尾带有多余的空格,应去除后再进行判断。但是在输出内容的时候还应该将空格输出,否则会导致格式错误。这个坑点非常难找,我询问了很多大佬才找到了这个坑点。
例如:
输入
/*
#N:1 #Q:1+1= #A:2
#Z:2 #Q:党十八大报告提出要加强()建设。A 政务诚信 B 商务诚信 C社会诚信 D司法公信 #A:A B C D
#T:1 1-5 2-9
#X:20201103 Tom
#S:1 20201103 #A:1-5 #A:2- A C
end
*/
错误输出
正确输出
家具强电电路模拟程序-2坑点
在这次作业中,为了计算方便,我将断开的开关的电阻设置成了一个很大值,而在计算并联电路电阻时,我是按照并联电路总电阻等于分电阻倒数之和的倒数进行计算的,但是这样就会因为浮点数计算会有误差,导致最后的结果出错。为了消除这种误差,我们可以只保留前面几位小数进行计算。
Q:如何保留小数?
A:我们可以将分子分母同时乘以100000,再将其化为整型,这样我们得到的计算结果就是只包含原本5位小数的计算结果,事实证明通过这样的方法可以得到较为正确的结果。
如图:
例如:
输入
/*
#T1:[IN K1-1] [K1-2 D2-1] [D2-2 OUT]
#T2:[IN K2-1] [K2-2 D1-1] [D1-2 OUT]
#M1:[T1 T2]
#T3:[VCC L1-1] [L1-2 M1-IN] [M1-OUT D3-1] [D3-2 GND]
#K1
#L1:1.00
end
*/
错误输出
正确输出
改进建议
在我们编写程序之前应该提前规划好思路,例如在这次的家具强电电路模拟程序中我们就可以使用工厂模式设计,通过这个设计可以让我们将电路简单化,很方便就可以处理串联、并联、串并联等情况。同时我们在设计代码的过程中应该尽可能贴合JAVA的七大设计原则,这样可以帮助我们编写结构清晰、逻辑分明的代码,使得他人(或者未来的自己)能够轻松理解代码的目的、流程和结构,并且在日后的迭代中可以做到不修改现有代码的基础上添加新功能,从而降低了维护成本并减少了引入 bug 的风险。
总结
学到了
在这几次的作业中,我逐渐深入理解了符合规范设计代码的重要性和好处,尤其是在进行家具强电电路模拟程序的迭代过程中。我深刻体会到,良好的设计不仅能提高代码的可维护性和可扩展性,还能显著提升开发效率。在此次迭代中,我通过仅仅添加了两个新类,就成功实现了程序的修改,整个过程既简洁又高效。这种高效的设计方式让我对面向对象的设计原则有了更深的理解和感悟,尤其是在如何通过模块化和解耦来避免程序复杂度的增加,以及如何通过合理的抽象和继承来确保代码的可扩展性。
这次作业还让我认识到了在计算过程中精确性的重要性。尤其是在处理强电电路模拟时,微小的误差可能会逐渐累积,导致最终结果的偏差,甚至引发程序错误。这让我意识到,程序中的每一步计算都应尽可能减少误差的来源,从而确保输出结果的精确性。在设计过程中,我开始更加关注数据处理的精度和算法的优化,以便在满足性能要求的同时,最大程度地降低计算误差。
不足
在第四次作业中,我逐渐意识到自己在代码设计中存在一些不足之处,尤其是在代码耦合度方面。我发现自己的代码并没有做到高内聚、低耦合,导致了模块之间的依赖关系过于紧密,影响了代码的可维护性和扩展性。同时,在处理某些功能模块时,我并未将不同的责任和功能明确地分开,而是将多个功能混合在同一类或方法中。这不仅使得代码的理解变得困难,也使得当需求发生变化时,我不得不对多个模块进行修改,这显然违背了“开放封闭原则”和“单一职责原则”。这些问题暴露了我在设计时对模块化和解耦的重视不足,也让我认识到高内聚、低耦合的重要性。
标签:总结,return,题目,int,电路,parts,程序设计,public From: https://www.cnblogs.com/tunecoming/p/18554548