首页 > 其他分享 >OOP课程第二次blog—23201408—钱文浩

OOP课程第二次blog—23201408—钱文浩

时间:2024-06-03 19:55:22浏览次数:14  
标签:次大 代码 作业 blog 电路 并联 OOP 钱文浩 设计

本次blog,针对第4~6次大作业题目集进行总结,目的在于总结不足、得出经验教训以及做出未来规划。本次blog分为以下几个部分。
一、前言:
(1)第4次和第6次大作业难度较大,需要考虑的情况很复杂多样,而且对整体设计能力的要求很高,类间关系设计继承、依赖、关联等等,而且因为输入的数据很多,某一部分读取或者输入的代码只要位置有一点不同,结果差别很大(这个后面也会提到,很重要!!),这样的错误往往很难察觉。第6次题目还涉及到很多物理知识,如并联电路电阻的计算、串并联电路的模拟等等,相比第4、5次大作业,第6次大作业的应用性更强,和现实中的实例联系更密切,对设计者模拟一个复杂系统的要求自然更高。
(2)这三次题目集,无一例外都考察了多种类间关系的设计以及对系统的模拟能力,要设计出一个符合实际、简洁高效的模拟系统需要设计者具有很强的建模能力、阅读理解能力(需要模拟的信息都是以文字形式呈现,三次大作业的题面阅读量都很大,需要设计者精确捕捉到有用信息)。前几次题目集我较为忽视阅读理解能力这一点,其实这是相当重要的,如果从第一步阅读理解就出了问题,代码的功能必然会有缺陷(因为需求的提取有偏差或者有疏漏),相比代码的正确性和高效性、可复用性等,功能不完全是非常致命的。

二、设计与分析:
因为第4次大作业和第5、6次模拟对象不同,这里分为两部分讨论。
(1)


第4次相比第六次在逻辑层面的设计思路很简单,设计者只需要有基本的生活常识就能有大致思路,但第6次加入了物理学知识后让系统的设计必须符合客观事实,难度大大提高。

(2) 本次bolg重点对第6次大作业进行讲解。
以下是第6次的类图。

由类图可以看到,类间关系首先要符合题面的基本描述,有串联电路并联电路,并且要注意串并联的多重关系:串联电路中可以有并联电路,并联电路中必须有串联电路。而且设备必须要细分为控制电路和受控电路,两者要继承自不同的父类(两种电器的属性差别很大,控制电路的理论电压应该为0,电阻也为0)。
其他地方和第4次题目集大同小异,这里就不多赘述。
类图看着简单吗?也许还算简单(相比第4次),但这并不代表代码层面简单。
首先串联电路中有设备,设备必须要用List不能用普通数组,如下

点击查看代码
 private ArrayList<Equippment> equ=new ArrayList<>();
        public void add(Equippment equippment)
	    {
		    this.equ.add(equippment);
		
	    }

还有并联电路中的串联电路,如下

点击查看代码
  private ArrayList<SeriesCircuit> serCircuit=new ArrayList<>();
        public void add(SeriesCircuit circuit)
    	{
	    	this.serCircuit.add(circuit);
	    }
家用电器系统最难的部分还是电阻和电压的计算,以及多个串联电路、并联电路的模拟,而且之后迭代出现并联电路中包含并联电路,这种情况更棘手一些。一种解决办法是先画电路图,理清楚各个电路之间的关系,可以把某些并联电路等效为串联电路来处理,以下是根据并联电路通路个数分情况计算电阻。
点击查看代码
  if(cnt==sercnt-1)
		{
			for(int i=1;i<=3;i++)
			{
				partserCircuit[i].setVoltage(0);
			}
			for(int i=1;i<=2;i++)
			{
				paraCircuit[1].getSerCircuit().get(i).setVoltage(0);
			}
		}
        if(cnt!=sercnt-1)
		{
			double[] res=new double[20];
			double sum1=0;
			double rall = 0;
			for(int i=1;i<=sercnt-1;i++)
			{
				if(partserCircuit[i].getVoltage()!=0)
				{
					
					for(int j=0;j<partserCircuit[i].getEqu().size();j++)
					{
						res[i]+=partserCircuit[i].getEqu().get(j).getResistance();
					}
				}

			}
			for(int i=1;i<res.length;i++)
			{
				if(res[i]!=0)
				{
					sum1+=1/res[i];
				}
			}
			paraCircuit[1].setResistance(1/sum1);
			
			for(int i=0;i<partserCircuit[sercnt].getEqu().size();i++)
			{
				rall+=partserCircuit[sercnt].getEqu().get(i).getResistance();
			}
			rall+=paraCircuit[1].getResistance();
			
		
			for(int i=1;i<=sercnt-1;i++)
			{
					voltage=paraCircuit[1].getResistance()/rall*partserCircuit[sercnt].getVoltage();
					for(int j=0;j<partserCircuit[i].getEqu().size();j++)
					{
						partserCircuit[i].getEqu().get(j).setVoltage(voltage);
					}
			}
			
			for(int i=0;i<partserCircuit[sercnt].getEqu().size();i++)
			{
				voltage=partserCircuit[sercnt].getEqu().get(i).getResistance()/rall*partserCircuit[sercnt].getVoltage();
				partserCircuit[sercnt].getEqu().get(i).setVoltage(voltage);
			}
			for(int i=1;i<=sercnt;i++)
			{
				if(partserCircuit[i].getVoltage()!=0)
				{
					for(int j=0;j<partserCircuit[i].getEqu().size();j++)
					{
						voltage=partserCircuit[i].getEqu().get(j).getVoltage();
						if(partserCircuit[i].getEqu().get(j).getNamestr()=="B")
						{
							if(voltage>=0&&voltage<=9)
							{
								partserCircuit[i].getEqu().get(j).setBright(0);
							}
							else
							{
								bright=150/210*(voltage-10)+50;
								partserCircuit[i].getEqu().get(j).setBright(bright);
							}
							
						}
						if(partserCircuit[i].getEqu().get(j).getNamestr()=="R")
						{
							if(voltage==0)
							{
								partserCircuit[i].getEqu().get(j).setBright(0);
							}
							else partserCircuit[i].getEqu().get(j).setBright(180);
							
						}
						if(partserCircuit[i].getEqu().get(j).getNamestr()=="D")
						{
							if(voltage<80)
							{
								partserCircuit[i].getEqu().get(j).setFanSpeed(0);
							}
							else if(voltage>=80&&voltage<=150)
							{
								double fanspeed=280/70*(voltage-80)+80;
								partserCircuit[i].getEqu().get(j).setFanSpeed(fanspeed);
							}
							else 
							{
								partserCircuit[i].getEqu().get(j).setFanSpeed(360);
							}
							
						}
						if(partserCircuit[i].getEqu().get(j).getNamestr()=="A")
						{
							if(voltage<80)
							{
								partserCircuit[i].getEqu().get(j).setFanSpeed(0);
							}
							else if(voltage>=80&&voltage<100)
							{
								partserCircuit[i].getEqu().get(j).setFanSpeed(80);
							}
							else if(voltage>=100&&voltage<120)
							{
								partserCircuit[i].getEqu().get(j).setFanSpeed(160);
							}
							else if(voltage>=120&&voltage<140)
							{
								partserCircuit[i].getEqu().get(j).setFanSpeed(260);
							}
							else 
							{
								partserCircuit[i].getEqu().get(j).setFanSpeed(360);
							}
						}
					}
				
				}
			}

		}
不过还有一点很难,就是对输入信息的处理顺序要安排得当:比如控制设备中的开关,它的权重是非常高的,很多情况下开关需要首先去遍历,如果不单独提出来可能会出现开关明明断开了,但是分档调速器和连续调速器还能改变电路的电压(电压居然不为0),这是不符合实际情况的,如下单独对开关讨论,这一点在后面踩坑心得会细说。
点击查看代码
  for(int i=0;i<operation.size();i++)
		{
			str=operation.get(i);
			c=str.charAt(2);
			num=String.valueOf(c);
			number=Integer.parseInt(num);
			if(str.charAt(1)=='K')
			{
				for(int j=1;j<=sercnt;j++)
				{
					for(int t=0;t<partserCircuit[j].getEqu().size();t++)
					{
						if(partserCircuit[j].getEqu().get(t).getNamestr()=="K"&&partserCircuit[j].getEqu().get(t).getName().equals(num))
						{
							if(partserCircuit[j].getEqu().get(t).getIsOpen()==1)
							{
								partserCircuit[j].getEqu().get(t).setIsOpen(0);
								partserCircuit[j].getEqu().get(t).setVoltage(0);
							}
							else 
							{
								partserCircuit[j].getEqu().get(t).setIsOpen(1);
								partserCircuit[j].getEqu().get(t).setVoltage(220);
							}
						}
					}
				}
			}
		}
家用电器系统的迭代不只有答题程序中功能的增加,还有系统整体复杂度的提升,如果设计者没有过多的前瞻,并联电路的嵌套的出现可能让代码急需大规模的改动(比如并联电路电阻的计算),这也是前者大作业相比后者难度大大提升的原因。 本次有一个设计思路比较好,针对输出顺序,给各种设备设置权重,然后用Collections.sort,不过Compareto方法一定要重写,先把所有设备的信息存起来再进行排序,如下
点击查看代码
 for(int i=1;i<=sercnt;i++)
		{
			partserCircuit[i].setOrder();
			for(int j=0;j<partserCircuit[i].getEqu().size();j++)
			{
				mainEqu.add(partserCircuit[i].getEqu().get(j));
			}
		}
		//对设备按输出要求排序
				for(int i=0;i<mainEqu.size();i++)
				{
					Collections.sort(mainEqu);
				}
三、踩坑心得: (1)“**细节决定成败**”,编程的时候要一气呵成,不要再任何时候降低专注度,有一处bug:设备的编号和num相等,我失误写成了.get()==num这是极其低级的错误,“==”代表的不是值的相等,而是计算机中的地址相等,这一点和.equals()千差万别。已知num的值可以用“==”,但如果比较的是变量就一定要用后者!!
点击查看代码
			{
				for(int j=1;j<=sercnt;j++)
				{
					for(int t=0;t<partserCircuit[j].getEqu().size();t++)
					{
						**if(partserCircuit[j].getEqu().get(t).getNamestr()=="K"&&partserCircuit[j].getEqu().get(t).getName().equals(num))**
						{
							if(partserCircuit[j].getEqu().get(t).getIsOpen()==1)
							{
								partserCircuit[j].getEqu().get(t).setIsOpen(0);
								partserCircuit[j].getEqu().get(t).setVoltage(0);
							}
							else 
							{
								partserCircuit[j].getEqu().get(t).setIsOpen(1);
								partserCircuit[j].getEqu().get(t).setVoltage(220);
							}
						}
					}
				}
			}

(2)关键设备的提前遍历。对于开关这种直接决定电压是否为0的设备,一定要首先遍历,这样才能保证当电路电压为0时其他控制设备不会再改变电压。

点击查看代码
   for(int i=1;i<=sercnt;i++)
		{
			for(int j=0;j<partserCircuit[i].getEqu().size();j++)
			{
				if(partserCircuit[i].getEqu().get(j).getNamestr()=="K")
				{
					if(partserCircuit[i].getEqu().get(j).getIsOpen()==1)
					{
						partserCircuit[i].setVoltage(220);
					}
					else if(partserCircuit[i].getEqu().get(j).getIsOpen()==0)
					{
						partserCircuit[i].setVoltage(0);
					}
				}
			}
		}

(3)编程的连贯性。当程序很复杂的时候,思路一定要连贯,能一次性写完(对于某个模块)就要一次性写完,思路断了再写的时候会不知道从何写起,对于系统思维的建立很不利。
(4)独立解决问题不代表闷头死磕。适当的时候可以询问同学,看看其他同学有什么经验和建议。有时候同学的一句提示可能就是你思路的盲点。遇到无论如何都想不通、写不出的地方不要死磕,换一种方法去解决,比如我在计算并联电路电阻时,如果只有一条通路,就把并联电路作为串联并入串联电路。
(5)关于代码复用性。我承认目前我的设计能力还不够强,代码复用性相对较差,所以在对代码迭代时,不要死磕式修改旧的代码!!!这点非常重要!!!必要的时候可以选择重写,找bug改bug是一间费时费力的事,其实很多时候改bug的时间大于重写的时间,比如第6次大作业的电路编号是从1开始数的,但是我写数组的时候失误从0开始了,这就导致很多地方要把0改成1,改了好久还是有bug(越界报错,说明有地方还没改过来),这种时候就要果断选择重写,改写花的时间大概率会比改半天bug的时间短,如下

点击查看代码
  for(int i=0;i<operation.size();i++)
		{
			str=operation.get(i);
			c=str.charAt(2);
			num=String.valueOf(c);
			number=Integer.parseInt(num);
			if(str.charAt(1)=='F')
			{
				char d=str.charAt(3);
				
				for(int j=1;j<=sercnt;j++)
				{
					for(int t=0;t<partserCircuit[j].getEqu().size();t++)
					{
						if(partserCircuit[j].getEqu().get(t).getNamestr()=="F"&&partserCircuit[j].getEqu().get(t).getNamestr().equals(num))
						{
							if(d=='+'&&partserCircuit[j].getEqu().get(t).getPosition()<3)
							{
								partserCircuit[j].getEqu().get(t).upPosition();
								
							}
							else if(d=='-'&&partserCircuit[j].getEqu().get(t).getPosition()>0)
							{
								partserCircuit[j].getEqu().get(t).downPosition();
							}
						}
					}
				}
				
			}
			if(str.charAt(1)=='L')
			{
				
				tmp2=str.split(":");
				speed=Double.parseDouble(tmp2[1]);
				for(int j=1;j<=sercnt;j++)
				{
					for(int t=0;t<partserCircuit[j].getEqu().size();t++)
					{
						if(partserCircuit[j].getEqu().get(t).getNamestr()=="L"&&partserCircuit[j].getEqu().get(t).getName().equals(num))
						{
							partserCircuit[j].getEqu().get(t).setSpeed(speed);
						}
					}
				}
				
			}
		}
四、改进建议: (1)对于电压的计算,不要一开始赋值给用电器电压,要先赋值给电路电压,然后把电路电压再赋值给用电器电压。 (2)即便类图已经设计好了,也先不要急着编码,上文也提到了,电路系统的各个部分物理层免得关系有点复杂,写之前要多想想代码的顺序有没有问题,有哪些因素是要率先考虑的(就像开关的闭合和打开直接决定电路是否有电压) (3)心态好一点。一次性写完提交后得分不高其实很正常,接下来才是真正考验程序员的时候,需要你综合利用经验、debug能力等等来勘误,如果一次失败就心态爆炸,很可能错过了修改那个就在眼前的致命bug的机会(比如上文的.equals(),卡了我还蛮久的) (4)不要死磕!!!第6次大作业前期我死磕式修改代码花费了好多时间,最后还是不尽人意。这个时候应该认识到是设计出了问题(或者原代码复用性实在太差),千万不要死磕,最好的办法是重整思路然后重写这一部分,不要觉得重写很费时间,死磕浪费的时间往往更多。

五、总结:
(1)这三次大作业,我最大的收获就是对一个物理系统的模拟、设计能力提升。对于一个物理系统,基础的设计知识比如SRP、MVC是不够用的,充分理解物理系统的原理是必要条件。程序不仅要符合逻辑,也要严格符合物理规律。
(2)纵观我第6次大作业的完成情况,确实不算理想,我认为不只是设计能力,debug能力也几乎同等重要。对于一个模拟电路系统的复杂程序,只是具备细心度是远远不够的,还需要熟练操控eclipse的debug功能,而且始终保持系统思维,要清楚这部分代码是负责电路系统哪个模块的(模块与模块之间往往互相影响,如果没有系统思维那么很容易出现改了一个bug又有很多个bug出现的情况发生)
(3)代码的整合精简。目前第6次大作业中不少循环中的内容重复冗杂,当输入内容迭代时运行起来效率会很低,所以在编写代码之前就要有意识地精简、合并代码。
(4)大胆设计,小心编程。一开始编码时,我因为一直瞻前顾后、担心设计出问题而耽误了不少时间,结果最后设计还是有不少瑕疵,所以我认为可能没有最好的设计、不要过度犹豫。但是大胆设计不意味着草率设计,草率设计没有意义甚至还会有副作用,我们每次遇到的现实问题都不可能相同,但是把握好基础的设计原则,即使大胆设计也不会太大的问题。
(5)经验的积累通过这几次大作业,尤其是第6次,我认为每次大作业是积累编程经验的最好途径,大量的编程经验还是要从实践中获取,这些经验往往是细致入微的、实用的,这种经验也可以是某一套系统、某一个模型、某一种算法。

标签:次大,代码,作业,blog,电路,并联,OOP,钱文浩,设计
From: https://www.cnblogs.com/BlogsOfCollector/p/18227351

相关文章

  • 【大数据】Hadoop集群搭建(8249字)
    文章目录@[toc]NAT配置IP配置SecureCRT配置PropertiesTerminalEmulationAppearanceJava安装环境变量配置Hadoop1.0安装建立临时文件夹修改配置文件mastersslavescore-site.xmlmapred-site.xmlhdfs-site.xmlhadoop-env.sh环境变量配置Hadoop2.0安装修改配置文件ha......
  • NCHU-oop-6总结
    写在前面:自己一些杂乱的想法对于这两次写的关于电路设计的编程题,一开始我是抗拒的,这些源自于高中对物理的抗拒。不过还好,在自己又一定代码实现的基础上,合理运用上老师关于设计类的建议,这些代码可以很容易被实现,剩下的就是敲下代码的时间。怎么说呢?老师和同学们一直在强调说要做......
  • 23201228-第二次Blog
    一、前言:从上一次Blog到现在又完成了三次PTA大作业,这三次大作业相较于第一次Blog中的三次PTA作业而言平均难度要稍微低一点,除了本次的第一个大作业外其余两个都较为简单,也许是因为更清晰的理解了类与类之间的关系,本次的第一个大作业是基于第一次Blog中的题目迭代而来,相较于第一次......
  • PTA题目集4~6的总结性Blog
    一:前言:1.知识点总结:①:java面向对象类和对象的基本用法②:关联类,依赖类和组合等类间关系③:正则表达式的运用④:Comparator接口及比较器基本使用⑤:ArrayList的基本使用⑥:Collections.sort方法使用2.题量:较少,每次题目集不超过3题3.难度:由于题量少,所以每次题目集难度较大,......
  • 南昌航空大学大一下学期java题目集4-6总结性Blog-苏礼顺23201608
    一、前言——总结三次题目集的知识点、题量、难度等情况 关于知识点  这次的三次题目集更加进一步体现了面向对象程序设计的思想方法。主要是之前的三次题目集就只是利用了面向对象三大基础特性中的封装特性,而这三次的题目集增加了继承与多态,这正是面向对象设计的精髓所......
  • OOP课第二阶段总结
    OOP课第二阶段总结前言作为第二次3+1的总结,明显感受到了此次题目集越来越复杂,结合了实际的物理知识来解决现实中的电路问题。因为电路可以一直扩展下去,情况千变万化,难以像上次题目集一样找到一个呆板的做法。这次题目集,让很多人连题目都无法理解,代码也是无从下手,因为这些人......
  • 第二次Blog
    真是转瞬即逝啊,转眼间就已经又做了3次作业,按照惯例,我们还是得来“温故而知新”一下本次的4~6次的题目集。这次虽然也没有一次满分,但是我不会觉得是件坏事,并不是因为麻木了,而是我觉得我至少努力过,像第4次,第5次,都是差1,2分,我都是坚持到了最后才得的分数,那我也没理由说嫌弃,只不过得......
  • Hadoop安装及集群环境配置
    环境准备1.VMware虚拟机(Linux操作系统)2.Windows10~113.JDK4.Hadoop5.Xshell7(用于连接虚拟机与Windows)6.Xftp7(用于虚拟机与Windows之间传输文件)家庭/学校免费-NetSarangWebsitehttps://www.xshell.com/zh/free-for-home-school/一、虚拟机下Hadoop环境搭建 1、创......
  • 基于SpringBoot+Vue的在线BLOG网管理系统设计与实现毕设(文档+源码)
            目录一、项目介绍二、开发环境三、功能介绍四、核心代码五、效果图六、源码获取:        大家好呀,我是一个混迹在java圈的码农。今天要和大家分享的是一款基于SpringBoot+Vue的在线BLOG网管理系统,项目源码请点击文章末尾联系我哦~目前有各类......
  • oop第二次博客
    write_by_23201707_gongjunjie一:前言本次博客主要是对pta上4-6次题目集的总结这次的pta题目集将上次的答题判题的题目又迭代了一次,但是它还是永远的离开了我们~~那么后面两次题目集则是使用电路问题取代了我们又爱又恨的答题判题题目集那么废话不多说,下面正式进入我们对三次......