面向对象设计与构造 —— 第四至六次作业(数字电路仿真单元)总结

前言
本阶段三次作业以数字电路仿真为核心主题,沿着 “基础门电路→中规模器件扩展→子电路层次化建模” 的路径逐步迭代,整体难度与代码规模呈阶梯式上升。三次作业覆盖的核心知识点包括:面向对象的抽象与封装、组合逻辑电路的信号传播算法、文本解析与正则应用、电路合法性校验、层次化系统建模方法,同时兼顾了代码鲁棒性、边界处理与错误处理的工程能力训练。
从题量与难度来看:
第四次作业(基础门电路):核心实现 5 种基础逻辑门(与、或、非、异或、同或)的稳态仿真,代码规模约 300 行,重点考察面向对象基础封装与信号传播逻辑的实现,入门门槛较低,但输入格式边界条件较多。
第五次作业(中规模器件扩展):在基础门之上新增三态门、译码器、多路选择器、数据分配器 4 种器件,代码规模约 550 行,重点考察设计的可扩展性与事件驱动仿真算法的应用,器件引脚定义与逻辑规则容易出现理解偏差。
第六次作业(子电路嵌套与错误校验):新增子电路定义与嵌套功能,同时增加 5 类电路合法性错误检测,代码规模约 800 行,重点考察层次化建模能力与拓扑排序算法的应用,引脚方向判断、命名空间处理与错误优先级是主要难点。
整体而言,本单元作业从 “实现单一功能” 向 “构建小型系统” 过渡,对面向对象设计的抽象能力、工程化思维提出了更高要求。相较于前序的表达式求导、电梯调度单元,本单元更侧重层次化系统的建模与拓展能力,更贴近真实工程中的模块化开发场景。
一、设计与分析
本部分针对三次作业的源码设计、类结构、代码复杂度逐一展开分析,结合 Metrics 度量指标与类图结构说明设计思路与存在的问题,所有复杂度指标均基于 SourceMonitor 的计算规则统计。
1.1 第四次作业:基础门电路仿真
设计思路
本次作业核心目标是实现组合逻辑电路的稳态值计算,输入为电路的输入引脚信号、元件连接关系,输出为所有门电路的输出引脚值。整体采用迭代轮询的信号传播方案:
逐行解析输入文本,识别输入引脚的信号值与引脚连接关系,根据门名称正则匹配创建对应的门电路对象;
循环遍历所有门电路,若其所有输入引脚已有确定信号,则计算输出值;
将输出值通过连接关系传递到下游门的输入引脚,重复上述过程直到本轮没有新的信号更新;
按 “与门→或门→非门→异或门→同或门” 的类型顺序、同类型按 ID 升序输出所有门的输出引脚值。
类结构说明
本次作业采用单 Main 类 + 内部抽象类的结构,UML 类图核心结构如下:
Main:主类,承担输入解析、电路构建、仿真计算、结果输出全部职责,内部维护 5 个 HashMap 分别存储不同类型的门电路,同时管理引脚信号表与连接关系表。
Gate:抽象内部类,定义门的名称属性与抽象方法getOutput(Map<String, Integer> pinSignal),所有具体门电路继承该类,统一对外接口。
AndGate/OrGate/NotGate/XorGate/XnorGate:具体门电路类,继承Gate,各自实现getOutput()方法,封装对应逻辑运算规则。
该设计的优点是结构简单、上手快,符合初次接触电路仿真的实现思路;缺点是主类职责过重,门电路分散在多个 HashMap 中,统一管理不便。
复杂度度量分析
核心方法与类的复杂度统计如下:
表格
方法 ev (G) 本质复杂度 iv (G) 设计复杂度 v (G) 圈复杂度
Main.main() 3 8 10
Main.parseAndCreateGate() 3 4 7
AndGate.getOutput() 2 2 3
OrGate.getOutput() 2 2 3
NotGate.getOutput() 1 1 2
XorGate.getOutput() 1 2 2
XnorGate.getOutput() 1 2 2
表格
类 OCavg 平均圈复杂度 WMC 总圈复杂度
Main 3.8 42
Gate 及子类 1.2 12
从复杂度数据可以看出核心问题:Main类职责过重,WMC(类总圈复杂度)高达 42,几乎所有业务逻辑都集中在主类中,不符合单一职责原则。其中main方法圈复杂度达到 10,原因是同时包含了输入解析、循环仿真、结果排序输出多段逻辑,分支与循环嵌套较多,调试时难以定位问题。
此外,迭代轮询的仿真方案在电路规模较小时可以正常运行,但对于大规模复杂电路,存在重复计算多、效率低的问题,且终止条件判断容易出现疏漏,这也是后续复杂电路用例出现结果错误的核心隐患之一。
类图

屏幕截图 2026-06-24 135148

测试结果分析
本次作业共 34 个测试用例,其中基础元件用例正确率约 75%,复杂电路用例正确率仅约 30%。错误主要集中在两类:
基础边界用例错误(case6、case11、case14):根源是正则解析对多位 ID、多位输入参数的门名称匹配存在疏漏,部分特殊命名的门无法被正确识别,导致器件未创建,输出缺失。
复杂电路错误(case25、case26、case28 等):一方面是迭代轮询的终止条件判断存在疏漏,长路径信号未完全传播就提前终止;另一方面是信号传递时的引脚映射错误,导致下游门输入值不正确。
1.2 第五次作业:中规模器件扩展
设计思路
本次作业在基础门之上新增 4 种中规模器件,同时优化信号传播算法,采用事件驱动的队列仿真替代轮询方案,核心思路如下:
统一器件模型,用Component类封装所有类型的器件,通过枚举ComponentType区分器件类型,替代分散的多个门类。
采用 “就绪计数” 机制:每个器件维护输入引脚总数与已就绪输入数,当所有输入全部就绪时,将器件加入计算队列。
依次取出队列中的器件计算输出,将输出信号传递到下游器件的输入引脚,更新下游器件的就绪计数;若下游器件所有输入就绪,则加入计算队列。
队列为空时仿真结束,按指定规则输出所有器件的结果。
类结构说明
本次作业仍采用单 Main 类结构,核心内部类为Component,UML 类图核心结构如下:
Main:主类,全局维护器件表、引脚 - 器件映射表、输出 - 输入连接表、引脚信号值、计算队列五大核心数据结构,承担解析、仿真、输出全部职责。
ComponentType:枚举类型,定义 9 种器件类型(AND、OR、NOT、XOR、XNOR、TRI、DECODER、MUX、DEMUX)。
Component:静态内部类,封装器件的类型、ID、参数、总输入数、就绪输入数、输入值映射、输出值映射。
相较于第一次作业,本次取消了门电路的继承结构,改用统一的 Component 类 + switch 分支实现不同器件的计算逻辑,虽然减少了类的数量,实现更直接,但也牺牲了可扩展性,新增器件需要修改核心计算方法。
复杂度度量分析
核心方法与类的复杂度统计如下:
表格
方法 ev (G) 本质复杂度 iv (G) 设计复杂度 v (G) 圈复杂度
Main.main() 4 9 12
Main.parseComponent() 3 5 7
Main.processComponent() 9 16 21
Main.setInputPinValue() 2 3 4
表格
类 OCavg 平均圈复杂度 WMC 总圈复杂度
Main 4.2 63
从复杂度数据可以看出,processComponent方法的圈复杂度高达 21,远超良好代码的通用标准(通常建议 v (G)≤10)。该方法包含 9 个器件类型的 switch 分支,每个分支内部又有循环、多层条件判断,逻辑高度耦合,是 bug 的高发区域。同时,Main 类的 WMC 上升到 63,代码可维护性进一步下降。
设计上的进步在于:采用事件驱动仿真后,算法时间复杂度从轮询的 O (N*M)(N 为门数,M 为路径长度)优化到 O (V+E)(V 为引脚数,E 为连接数),仿真效率大幅提升,也从机制上避免了轮询的提前终止问题。
类图

屏幕截图 2026-06-24 135436

测试结果分析
本次作业共 34 个测试用例,整体正确率约 65%。错误主要分为三类:
器件逻辑定义错误:部分器件的引脚定义、使能逻辑与题目要求不符,例如译码器的使能端电平、输出有效电平的偏差,导致涉及该类器件的用例全部错误。
就绪计数维护错误:复杂电路中,一个输出引脚连接多个下游输入时,部分下游器件的就绪计数未正确累加,导致器件永远无法进入计算队列,输出缺失。
运行时异常(非零返回):当输入引脚不存在、器件未创建时,代码未做空值判断,直接调用方法导致空指针异常,触发非零返回。
1.3 第六次作业:子电路嵌套与错误校验
设计思路
本次作业新增子电路层次化建模与电路合法性校验功能,核心采用拓扑排序实现层次化电路的信号传播,整体流程分为四个阶段:
两阶段解析:先解析所有子电路定义块(Cx:到endc),保存每个子电路的输入输出引脚、内部连接、内部器件;再解析主电路的输入信号与连接关系。
错误校验:分为两个层级 —— 子电路内部连接校验、主电路连接校验,检测多输入、无输入、无输出、顺序错误四类连接问题;再进行信号冲突检测,校验同一输入引脚是否被多个输出驱动。
拓扑建图:将所有引脚(包括子电路内部引脚)作为图的节点,连接关系作为有向边,构建有向无环图,维护每个节点的入度。
拓扑仿真:从主输入引脚出发,按拓扑顺序传播信号,遇到器件则计算输出,遇到连线则直接传递信号,直到所有可计算节点都处理完毕。
类结构说明
本次作业新增子电路类,形成两级内部类结构,UML 类图核心结构如下:
Main:主类,全局维护子电路表、主电路数据、图结构与仿真逻辑,承担解析、校验、仿真、输出全部职责。
SubCircuit:静态内部类,封装子电路的 ID、输入引脚集合、输出引脚集合、内部连接列表、内部器件名称集合。
Component:静态内部类,封装门电路的类型、ID、输入数、输出引脚、输入引脚列表,支持带前缀的子电路内部器件命名。
该设计通过 “前缀命名空间” 的方式实现子电路内部引脚的隔离,将子电路内部的所有引脚前加上Cx-前缀,统一纳入全局拓扑图中计算,实现思路简洁,避免了递归仿真的复杂度。
复杂度度量分析
核心方法与类的复杂度统计如下:
表格
方法 ev (G) 本质复杂度 iv (G) 设计复杂度 v (G) 圈复杂度
Main.main() 7 18 24
Main.checkConnectionInMain() 4 7 9
Main.checkConnectionInSub() 4 7 9
Main.extractComponentName() 2 2 3
Main.computeOutput() 3 3 5
表格
类 OCavg 平均圈复杂度 WMC 总圈复杂度
Main 4.7 89
SubCircuit 1.1 8
Component 1.3 11
从复杂度数据看,Main 类的 WMC 已经达到 89,main 方法圈复杂度 24,代码的可维护性已经较差。核心原因是解析、校验、建图、仿真、输出全部逻辑都集中在主类中,分支嵌套多,逻辑链条长,新增功能时极易引入新 bug。
设计上的亮点在于:错误校验模块独立度较高,异常用例的正确率达到 100%;拓扑排序的仿真方案保证了组合逻辑仿真的正确性与效率,不会出现传播不完整的问题。
类图

屏幕截图 2026-06-24 140153

测试结果分析
本次作业共 43 个测试用例,整体正确率约 70%。其中异常检测用例全部正确,单子电路用例正确率约 80%,多子电路用例正确率约 50%。错误主要集中在:
多子电路场景的引脚映射错误:子电路嵌套时,引脚名称的前缀拼接、拆分逻辑存在边界漏洞,导致部分引脚无法正确映射到对应器件,仿真结果错误。
输出排序规则不符:器件输出的排序逻辑(主电路与子电路器件的先后顺序)与题目要求存在偏差,导致输出顺序错误被判错。
运行时异常:部分边界场景下子电路 ID 不存在、引脚为空,导致空指针异常,触发非零返回。
二、采坑心得
本阶段三次作业的调试过程中,遇到了大量共性与特性问题,以下结合具体测试用例、代码结构与测试结果,总结核心踩坑点与真实心得。
2.1 文本解析:正则与字符串拆分的边界陷阱
文本解析是整个电路仿真的入口,也是最容易出现隐蔽 bug 的环节,三次作业中超过 30% 的错误都源于解析逻辑的边界疏漏。
具体问题:
第四次作业中,门名称正则^([AO])\((\d+)\)(\d+)$看似可以匹配所有与门、或门名称,但实际测试中,当输入参数或 ID 为多位数(如A(12)34)时,正则本身可以匹配,但后续的引脚拆分如果误用indexOf('-')而非lastIndexOf('-'),在子电路场景下就会出现严重错误。
第六次作业中,子电路内部引脚的命名格式为C1-A(2)3-1,包含多个-字符,如果使用indexOf('-')拆分器件名与引脚号,会得到错误的拆分结果,导致器件无法识别,输入信号无法传递。
现象与数据:第六次作业的多子电路用例(case26、case28)错误,经定位,核心原因就是引脚拆分时的索引选择错误,导致子电路内部器件的输入引脚无法正确关联到器件,约 40% 的多子电路错误都与此相关。
心得:
对于层级化的命名规则,拆分字符串时必须明确分隔符的语义,优先使用lastIndexOf处理最右侧的分隔符,避免前缀中包含相同分隔符导致拆分错误。
正则表达式编写完成后,必须覆盖所有边界场景测试:单数字、多数字、特殊参数、极值情况,不能只满足样例输入就认为解析正确。
2.2 信号传播:算法选择与状态维护的细节疏漏
信号传播算法是电路仿真的核心,从轮询到事件驱动再到拓扑排序,三次迭代中踩了不同的坑,也对不同算法的适用场景有了更深刻的理解。
具体问题 1:轮询算法的终止条件
第四次作业采用迭代轮询,最初的终止条件是 “本轮没有信号更新”,但实际实现中,由于信号更新的判断逻辑有误(比较 Integer 对象用了==而非equals),导致部分信号更新未被识别,提前终止仿真,长路径的信号无法传播到末端。
现象与数据:第四次作业的复杂电路用例中,路径深度超过 5 层的电路几乎全部错误,占复杂电路错误总数的 60% 以上,根源就是信号传播不完整。
具体问题 2:事件驱动的就绪计数维护
第五次作业采用事件驱动队列,就绪计数的维护是核心。最初实现中,当一个输出引脚连接到同一个器件的多个输入引脚时,就绪计数会重复累加,导致器件提前就绪,输入不全就开始计算,结果完全错误。
现象与数据:case25、case29 等包含扇出的复杂电路,出现大量输出值错误,经逐引脚调试发现,就是就绪计数重复累加导致的。
心得:
组合逻辑仿真的最优方案是拓扑排序,既能保证一次遍历完成计算,效率最高,也能天然避免轮询的终止问题、事件驱动的计数维护问题,前期多花一点时间建图,后期调试会省很多精力。
状态变量的维护必须考虑所有边界场景:一对多连接、多对一连接、悬空引脚等,不能只假设理想的一对一连接,否则复杂场景下必然出问题。
2.3 器件定义:引脚与逻辑的一致性偏差
数字电路器件的引脚定义、逻辑规则有严格的规范,一旦理解偏差,会导致整类器件的用例全部错误,这是第五次作业最惨痛的教训。
具体问题:
译码器的使能端逻辑:题目中译码器的使能端为 S1、S2、S3,最初实现时误将使能条件写反(低有效写成高有效),导致所有涉及译码器的用例输出完全相反。
三态门的输出引脚编号:误将输出引脚编号写为 2,而题目要求为 0,导致输出引脚不匹配,结果无法被正确识别。
现象与数据:第五次作业中,涉及译码器、三态门的测试用例正确率不足 30%,单个器件定义错误导致超过 10 个用例失分,占总失分的 40% 以上。
心得:
开始编码前,必须逐字核对题目中所有器件的引脚定义、逻辑规则、有效电平,最好整理成表格,避免凭印象编码。一个细节理解错,后面所有工作都是无用功。
单个器件的单元测试是最低成本的验证方式:写完一个器件的逻辑后,先单独测试所有输入组合,确认正确后再集成到整体电路中,避免集成后难以定位 bug。
2.4 错误校验:信号方向的判断逻辑
第六次作业的错误校验中,最容易混淆的就是 “输入引脚” 与 “输出引脚” 的方向,尤其是子电路的端口,在不同视角下方向完全相反。
具体问题:
子电路的 INPUT 引脚,在子电路内部视角是信号源(驱动端),驱动内部的器件输入;在主电路视角是接收端,接收外部信号。如果方向判断错误,就会出现 “多输入” 的误判,或者信号传播方向反转。
最初实现的isInputInSub方法就混淆了方向,把子电路的 INPUT 引脚当成了输入端,导致连接检查全部错误。
现象与数据:最初版本的连接检查用例正确率为 0,修正方向判断逻辑后,所有异常用例正确率达到 100%。
心得:
处理层次化系统时,必须明确 “视角”:内部视角与外部视角的端口方向可能完全相反,最好用统一的 “驱动端 - 接收端” 语义替代 “输入 - 输出”,避免方向混淆。
错误校验模块必须先于仿真逻辑完成,先保证合法的电路才能进入仿真,既符合工程逻辑,也能避免非法电路导致仿真崩溃。
2.5 鲁棒性:空值判断与异常处理
三次作业中都出现了 “非零返回” 的错误,全部是运行时异常导致的,包括空指针、数组越界、数字格式异常等,都是完全可以避免的低级错误。
具体问题:
当输入的器件名称不合法时,parseComponent返回 null,后续调用其属性时触发空指针。
当译码器的参数过大时,输出引脚数超过预期,数组访问越界。
当子电路 ID 不存在时,subCircuits.get()返回 null,访问其属性触发空指针。
现象与数据:三次作业分别有 1、1、3 个用例出现非零返回,占总错误用例的 15% 左右,都是因为没有做基础的合法性校验导致的。
心得:
所有外部输入的数据都不能信任,解析时必须做合法性校验,捕获可能的格式异常。
所有 Map 的 get 操作后,都要做空值判断,尤其是用户输入的 key,不能假设一定存在。
不要用System.exit()粗暴终止程序,最好用异常机制统一处理错误,既便于调试,也能保证程序退出的规范性。
三、改进建议
结合三次作业的设计缺陷与 bug 经验,从架构、算法、错误处理、测试、代码质量五个维度提出可持续的改进方案,确保代码可迭代、可扩展、可维护。
3.1 架构重构:拆分职责,告别 “一 Main 到底”
当前三次作业的最大问题是职责不分离,所有逻辑都集中在 Main 类中,可维护性、可扩展性差。重构方向如下:
分层拆分类:按照职责拆分为五大模块
parser包:CircuitParser类,专门负责输入文本解析,输出电路模型对象,与仿真逻辑完全解耦。
model包:抽象Component基类,派生出Gate(基础门)、MSIDevice(中规模器件)、SubCircuit(子电路)子类,每个器件自行实现compute()方法,用多态替代 switch 分支。
simulate包:CircuitSimulator类,专门负责拓扑排序与信号传播,仅依赖模型层的接口,与具体器件无关。
checker包:CircuitChecker类,专门负责电路合法性校验,输出错误信息。
Main类:仅作为程序入口,调用上述模块完成流程,不包含任何业务逻辑。
引入工厂模式:实现ComponentFactory,根据器件名称创建对应的 Component 对象,新增器件时只需添加子类与工厂方法,无需修改原有代码,符合开闭原则。
重构后,每个类的职责单一,单个类的 WMC 可以控制在 20 以内,单个方法的圈复杂度不超过 10,可维护性与可扩展性大幅提升。
3.2 算法优化:完善仿真能力,支持时序扩展
当前的组合逻辑仿真已经基本成型,但仍有优化与扩展空间:
引入环路检测:在拓扑排序阶段检测组合环路,若存在则抛出错误,避免非法电路导致死循环或错误结果。
支持延迟仿真:为每个器件添加传播延迟属性,改用优先队列(事件队列)按时间顺序处理信号变化,支持时序逻辑仿真,为后续扩展触发器、寄存器等时序器件预留空间。
增量仿真:支持修改部分输入信号后,仅重新计算受影响的路径,无需全量重算,提升大规模电路的仿真效率。
3.3 错误处理:完善异常体系,提升调试体验
当前的错误处理比较粗糙,改进方向:
自定义异常体系:定义CircuitException基类,派生出ParseException、ConnectionException、ConflictException等子类,每个异常携带错误行号、错误描述、错误位置等信息,方便定位问题。
错误收集模式:支持 “全部检测后统一输出” 模式,一次性列出所有错误,而非遇到第一个就终止,方便用户批量修正。
增加校验维度:新增悬空引脚检测、器件参数合法性检测、子电路递归嵌套检测等,进一步提升电路校验的全面性。
3.4 测试体系:构建自动化测试框架
当前的测试依赖 OJ 用例,自主性不足,容易遗漏边界场景,需要构建完整的测试体系:
单元测试:为每个器件类编写 JUnit 单元测试,覆盖所有输入组合与边界情况,确保单个器件逻辑 100% 正确。
集成测试:构造典型电路测试用例,包括级联电路、扇出电路、最大规模电路、子电路嵌套电路,验证整体仿真逻辑。
自动化对拍:编写 Python 参考实现或调用开源电路仿真库作为基准,自动生成随机测试用例,批量对比输出结果,快速发现隐藏 bug。
3.5 代码质量:降低复杂度,规范编码
拆分长方法:单个方法长度不超过 50 行,超过则拆分为多个子方法,每个方法只做一件事。
消除魔法值:所有器件类型字符、引脚编号、错误信息都定义为常量,避免硬编码,减少拼写错误。
规范命名:变量、方法命名遵循见名知意原则,避免缩写、歧义命名,提升代码可读性。
四、总结
本阶段三次数字电路仿真作业,从基础门电路到层次化子电路,逐步构建了一个组合逻辑电路仿真器的雏形,整个过程既是对面向对象设计能力的锻炼,也是对工程化思维、系统建模能力的提升。
4.1 核心收获
第一,抽象建模能力的提升。从一个个具体的逻辑门,到统一的器件模型,再到层次化的子电路,我逐渐学会了从具体需求中抽象出共性,用封装、继承的方式组织代码,而不是堆砌逻辑。尤其是子电路的实现,让我对 “层次化系统的命名空间、端口映射” 有了直观的理解,这是大型系统开发的基础能力。
第二,算法选型的工程思维。三次作业分别用了轮询、事件驱动、拓扑排序三种信号传播算法,每一次迭代都是对前一种方案缺陷的修正。这个过程让我明白,没有绝对最优的算法,只有最适合场景的算法:简单电路用轮询实现最快,中等规模用事件驱动效率足够,大规模层次化电路用拓扑排序最稳定。在开发中,要根据需求规模选择合适的方案,不要过度设计,也不要贪图简单留下隐患。
第三,对细节决定成败的深刻体会。一个引脚编号的错误、一个正则的疏漏、一个空指针的遗漏,都会导致大量用例失分。数字电路仿真本身就是对精度要求极高的场景,差之毫厘谬以千里。这也提醒我,软件开发中,边界处理、鲁棒性和核心逻辑同等重要,尤其是面向用户的系统,任何一个低级错误都会影响用户体验。
第四,测试是质量的底线。本次作业中很多 bug,如果提前做好单元测试、边界测试,完全可以避免。之前总觉得测试是 “浪费时间”,但实际调试中,定位一个集成后的 bug 花费的时间,远多于写单元测试的时间。测试驱动开发不是口号,而是实实在在提升开发效率的方法。
4.2 不足与后续方向
当然,本阶段的作业也暴露了很多不足:
一是设计模式的应用还很生疏。全程没有合理使用工厂模式、策略模式等设计模式,导致代码扩展性差,新增器件需要修改大量原有代码。后续会深入学习设计模式,并主动在代码中实践,提升设计能力。
二是架构设计的前瞻性不足。每次作业迭代都几乎重构了核心代码,没有提前预留扩展空间。比如第一次作业的继承结构,第二次作业反而改成了统一类 + switch,走了回头路。后续做设计时,要先预判需求的扩展方向,预留好扩展点,避免反复重构。
三是代码质量管控意识薄弱。很多方法圈复杂度严重超标,命名、注释都不规范,“能跑就行” 的心态比较明显。后续会严格要求自己,遵循代码规范,控制复杂度,写 “可维护的代码” 而不是 “能跑的代码”。
后续,我会按照改进建议重构本单元的代码,完善测试体系,进一步优化架构。同时也会继续学习数字电路仿真的相关知识,尝试支持时序逻辑、波形输出等功能,把这个作业项目做成一个完整的仿真工具,真正把课程知识转化为实践能力。
整体来看,本单元的作业虽然踩了很多坑,也有不少用例没有拿到满分,但收获的经验和能力,远比分数更有价值。这也正是 OO 课程的意义所在:在一次次迭代、踩坑、重构中,真正理解面向对象的思想,提升工程化能力。

posted @ 2026-06-24 14:02  kskblbb  阅读(2)  评论(0)    收藏  举报