实训设计与模式当你开始学习这本书时应该已经写过上万行代码了吧_第1页
实训设计与模式当你开始学习这本书时应该已经写过上万行代码了吧_第2页
实训设计与模式当你开始学习这本书时应该已经写过上万行代码了吧_第3页
实训设计与模式当你开始学习这本书时应该已经写过上万行代码了吧_第4页
实训设计与模式当你开始学习这本书时应该已经写过上万行代码了吧_第5页
已阅读5页,还剩66页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1以及怎么做,设计能力的缺失导致了大量冗余、低效、充满Bug且不易的代码,甚至在更短的时间内编写出更高质量的代码。有统计数据,一个高级程序员与一个平庸程10:1,显然企业更愿意使用高级程序员以节省成本。1拿到了别人的代码要在其基础上修改以添加功能这时发现原来的代码结构,bug。在重构领域,最具的著作当数MartinFowler所写的《重构——改善既有代码的重构的各种技术。 2MartinFowler下面展示了一个简单的个人所得据打印的例子。Tax类代表申信息,包括了,月收入两个属性,ReportPrintusingnamespace{publicclass{privatestringname;publicstringName{get{returnname;}set{name=value;}}privatedoublesaraly;publicdoubleSaraly{get{returnsaraly;}set{saraly=value;}}public{}publicTax(stringname,double{=name;this.saraly=}}}代码演示:重构前——ReportusingnamespaceCom.{publicclass{publicvoidPrint(Tax{ ine("个人所得税申报收据Console.Write("申报日期:"+DateTime.Now.ToString("yyyy-MM-dd")); ine("\t操作人:"); ine("缴税人:\t{0}",tax.Name); ine("缴税人月收入:\t{0:c2}元",tax.Saraly);intlevel=0;if(tax.Saraly>2000)level=1;if(tax.Saraly>4000)level=

if(tax.Saraly>6000)level=3;if(tax.Saraly>8000)level=4;if(tax.Saraly>10000)level=5; ine("应缴税级别:\tlevel级");doublet=0;switch{caset=case1:t=tax.Saraly*0.05;caset=tax.Saraly*0.08;caset=tax.Saraly*0.10;caset=tax.Saraly*0.15;caset=tax.Saraly*0.20;} }}}usingnamespaceCom.{publicclass{publicstaticvoidMain(string[]{Taxtax=newTax("",3500);Reportreport=newReport();}}}图 重构第一次重构:拆分大方PrintPrintHeader和PrintContent两个方法,将大的方法拆分为小的方法,可以增加方法被复用的机率,每个方Report类代码如下:usingnamespaceCom.{publicclass{publicvoidPrint(Tax{}publicvoid{ ine("个人所得税申报收据Console.Write("申报日期:"+DateTime.Now.ToString("yyyy-MM-dd")); ine("\t操作人:"); }

publicvoidPrintContent(Tax{ ine("缴税人:\t{0}",tax.Name); ine("缴税人月收入:\t{0:c2}元",tax.Saraly);intlevel=0;if(tax.Saraly>2000)level=1;if(tax.Saraly>4000)level=2;if(tax.Saraly>6000)level=3;if(tax.Saraly>8000)level=4;if(tax.Saraly>10000)level=5; ine("应缴税级别:\tlevel级");doublet=0;switch{caset=case1:t=tax.Saraly*0.05;caset=tax.Saraly*0.08;caset=tax.Saraly*0.10;caset=tax.Saraly*0.15;caset=tax.Saraly*0.20;} ine("应缴收税额:\t{0:c2}元}}}第二次重构:方法只实现单PrintConent方法,其中包含了打式改变后不会影响到打印功能,改变Report类代码如下:usingnamespaceCom.{publicclass{publicvoidPrint(Tax{}publicvoid{ ine("个人所得税申报收据Console.Write("申报日期:"+DateTime.Now.ToString("yyyy-MM-dd")); ine("\t操作人:"); }

publicvoidPrintContent(Tax{ ine("缴税人:\t{0}",tax.Name); ine("缴税人月收入:\t{0:c2}元",tax.Saraly);intlevel=CountLevel(tax); ine("应缴税级别:\tlevel级");doublet=CountTax(tax,level); ine("应缴收税额:\t{0:c2}元}publicintCountLevel(Tax{intlevel=if(tax.Saraly>2000)level=1;if(tax.Saraly>4000)level=2;if(tax.Saraly>6000)level=3;if(tax.Saraly>8000)level=4;if(tax.Saraly>10000)level=5;returnlevel;}publicdoubleCountTax(Taxtax,int{doublet=0;switch{caset=case1:t=tax.Saraly*0.05;caset=tax.Saraly*0.08;caset=tax.Saraly*0.10;caset=tax.Saraly*0.15;caset=tax.Saraly*0.20;}return}}}第三次重构:方法按逻辑归能。ReportReport类中只应该包含打印相关的方法税务相关的方法应该转移到Tax类中观察下面更改后的TaxReport类的代码,会发现将方法转移到应该归属的类后,方法的参数也变得更加简单:usingnamespaceCom.{publicclass{privatestringname;publicstringName{get{returnname;}set{name=value;}}privatedoublesaraly;publicdoubleSaraly{get{returnsaraly;}set{saraly=value;}}public{}publicTax(stringname,double{=name;this.saraly=}publicint{intlevel=if(this.Saraly>2000)level=1;if(this.Saraly>4000)level=2;if(this.Saraly>6000)level=3;if(this.Saraly>8000)level=4;if(this.Saraly>10000)level=5;returnlevel;}publicdouble{doublet=switch(CountLevel()){caset=case1:t=this.Saraly*0.05;caset=this.Saraly*0.08;caset=this.Saraly*0.10;caset=this.Saraly*0.15;caset=this.Saraly*0.20;}return}}}usingnamespaceCom.XinZhanedu.{publicclass{publicvoidPrint(Tax{}publicvoid{ ine("个人所得税申报收据Console.Write("申报日期:"+DateTime.Now.ToString("yyyy-MM-dd")); ine("\t操作人:"); }

publicvoidPrintContent(Tax{ ine("缴税人:\t{0}",tax.Name); ine("缴税人月收入:\t{0:c2}元",tax.Saraly); ine("应缴税级别:\t{0}级",tax.CountLevel()); ine("应缴收税额:\t{0:c2}元",tax.CountTax());}}}第四次重构:替换switch语句:usingnamespace{publicclass{privatestringname;publicstringName{get{returnname;}set{name=value;}}privatedoublesaraly;publicdoubleSaraly{get{returnsaraly;}set{saraly=value;}}public{}publicTax(stringname,double{=name;this.saraly=}privatedouble[]rates=newdouble[]{0,0.05,0.08,0.1,0.15,publicint{intlevel=if(this.Saraly>2000)level=1;if(this.Saraly>4000)level=2;if(this.Saraly>6000)level=3;if(this.Saraly>8000)level=4;if(this.Saraly>10000)level=5;returnlevel;}publicdouble{returnthis.Saraly*}}}MartinFowlerMartinFowler的带领下更深入的了解重构的各种吧(在课件的“代码演示”中有《重构》一书的免费章节和96K追求的则是可性。2002年曾经有人对的商业应用程序进行过统计,在软件开发上每投入1,就将花费2用于。也就是说软件的代价是开发的2倍,从企ABR类的代码,AR类的代码。B类的业务并没有变化,但对R类所做的修改同样反映到了B类,反而使B类原有的业务需开放封闭原则(OCP原则开放封闭原则(OpenClosedPrinciple)BertrandMeyer博士提出,是所有类的设计OCP原则演化而来。BertrandOCPsoftwareentities(classes,modules,functions,etc.)shouldbeopenforextension,butclosedformodification.软件实体(类,模块,方法等)OCPOCPOCPpublicclass{publicvoid{ }publicvoid{ }}ShapeDemoOCP原则,无论是修改已有的画图功能还是扩展新的功能(比 { void}publicclassCircle {publicoverridevoid{ }}publicclassSquare {publicoverridevoid{ }}OCP原则,首先需要修改已有的画图功能时不会影响其他类,其次OCPC#语言OCPC#的多态层定义的方法OCP下面我们再通过一个生活中的实例来进一步说明这个问题,比如:家刚装完了插座,很方便,当然可能不好看…….NetFrameworkOCPIEnumerable接口作为抽象层定义了集合的外部特征,Hashtable、SortedList等作为实现类提供了不同的内在特性,如果需要IEnumerable接口即可。IO流、异常结构等设计。依赖倒转原则(DIP原则抽象耦合:一个类另一个抽象类或接口,称之为抽象耦合具体耦合:一个类直接另一个具体类,称之为具体耦合OCP原则,一个类产生变化时往往会波及到相耦合DIP原则中有如下两段描述:High-levelmodulesshouldnotdependonlow-levelmodules.Bothshoulddependon高等级模块不应依赖于级模块,而应依赖于抽象层Programtoaninterface,notan针对接口(抽象层)针对接口编程指应当使用接口或抽象类进行变量类型参数类型或方法返回类型,而不是使用具体实现类。比如定义集合时应使用IListlist=newArrayList()这种形式ArrayListv=newArrayList(),前者提供了更高的灵活性。接口分离原则(ISP原则接口分离原则(InterfaceSegregationPrinciple)关注与接口的设计,要求使用多个ISPISPAppleiPod系列产品,第一版中我们让所有的iPod系列器都实现同一接口:1对iPod这种设计存在两个缺陷,首先并非所有的iPod都具有(shuffle不可以)和触法将各个产品区分开,如设计一个方法传入可的iPod对其进行操作,方法参数只2ISP最少知识原则(LKP原则Demeter,比如A类提供了Exit(退出程序)方法,但A实例的获取比较麻烦,为简化操作,B类ExitBA类。,通用闭命名空间原(CommonClosure 原则,无环依赖原无环依赖原则指应避免命名空间之间的循环依赖,如命名空间A依赖于命名空间B,命名空间B依赖于命名空间C,命名空间C又依赖于命名空间A。当循环依赖产生时,会对修设计模式的招式,它也是一种经验性的总结。比如在太极拳中有一式叫“铁牛耕地是这样用的:A在B的过程中,如果A有机会闪到B的后面,就可以从后面勾住对方的脖子,然后快速用力向后拖,目标是要用B的后脑勺去“耕地(相当啊这样最终达到一1ABAB境。一般认为,GoF(GangofFour,指G ,Helm,JohnsonVli es与Addison-Wesley四位大师级的人物)于1995年的《设计模式——可复用面向对象软件的基23种可性。API。实际上每一种设计模式都没有固定的实现方法,每一种模式都有自身的适用范围,学习设计模式时,不求死记硬背,理解模式背景以及所解决的问会遇到些,比如学习工厂模式时实现代码简单但设计思想复杂,学习模式时设计再谈简单工厂模式(Simple图2楼房的过如图3所示,在一个类F中,如果既有可能会调用到A类的对象,也有可能调用到B类用,即在运行时使用A与B的对象具有同等的机会,而在设计时是无法确定的,这时,在F3(或接口)1:publicclassTest{publicvoid{Config.OperType="*";IOperoper=doubled=oper.Cal(25,36); }}publicstaticclassConfig{publicstaticstringOperType=}publicclass{publicstaticIOper{stringtypeConfig.OperType;switch(type){casereturnnewAddOper();case"-":returnnewSubOper();case"*":returnnewMulOper();case"/":returnnewDivOper();thrownewException("}}}publicinterfaceIOper{doubleCal(doublei,double}publicclass{publicdoubleCal(doublei,double{returni+}}publicclassSubOper:{publicdoubleCal(doublei,double{returni-}}publicclassMulOper:{publicdoubleCal(doublei,double{returni*}}publicclassDivOper:{publicdoubleCal(doublei,double{if(j==thrownewException("0不能做除数!");returni/j;}}在上述代码实现了一个类似于计算器的功能,AddOper用于实现加运算,SubOper用于实现减运算,MulOper用于实现乘运算,DivOper用于实现除运算,Test类用于模拟调用这算或减运算,这里就出现了一个问题,如果在Test类的CalTest方法中,调用了AddOper类TestAddOperSubOper类绑定过死,即耦合度过高。Factory为工厂类,由于通过它可以得到具体的产品,所以也可以称为实后在CalTest方法中,调用IOperCal方法实现计算。当然在计算之间要为IOper做具体的IOper的对象指向AddOperCal将实现加运算,SubOperCal将实现减运算等等,这是一种典型的多态的应用。至于要实现何种运算完全可以由用户在界面上的操作来决定然后这种操作于配置文件或一个全局性的静态变量中,然后在工厂类Factory中,这一配置,根据不部调用。再如当需要扩展新的计算时,只要增加新的计算类,并实现IOper接口,然后在.TestIOperFactory.GetOper方法通过反射机制得到具体的类型等,这样可以使Factory类中的代码具有更强的可伸缩性,类似的应用在下一小厂、父类(或接口)及具体类(或实现类)141工厂方法模式(Factory厂类中得到的,就像图2所示的开发商一样,如果一开始,该开发商只做居民房销售,比如除了居民品外还在做写字楼、商铺等等的开发,那么一个销售部门肯定是不够的,5所示。525所示中,居民房销售分部、写字楼销售分部以及商铺销售分部统归销售总部管简单工厂内的代码也会变得越来越复杂而难以同时将属于不同模块的产品类组合在一2:publicclass{publicvoid{Factoryfactory=newIOperoper=factory.GetOper();doublem=oper.Cal(25,36); }}publicinterfaceIOper{doubleCal(doublei,double} class{ IOper}publicclassAddFactory:{publicoverrideIOper{returnnew}}publicclassSubFactory:{publicoverrideIOper{returnnew}}publicclassAddOper:{publicdoubleCal(doublei,double{returni+}}publicclassSubOper:{publicdoubleCal(doublei,double{returni-}}代码中有两个工厂类,AddFactorySubFactory,它们分别用于得到AddOperSubOper对象,然后在客户调用程序Test中,采用IFactory接口对象接收了一个AddFactory对象,并IOperAddOper对象,并最终实现加运算。这里,我们IOper我们称为抽象产品AddOperSubOper称为具体类,也即实体产品而将AddFactory和SubFactory称为实体工厂这些实体工厂有一个统一的父类Factory,Factory中为这些实体工厂制作操作的规则。(类。也就是说,工厂方法模式将简单工厂中可能存在的代码如增加新的计算类要修改客户调用程序与具体类的耦合度,以增强程序的可扩展性、可性等。(3:22usingusingSystem.Reflection;namespaceFactoryMethod{publicclass{staticvoid{Factoryfactory=(Factory)Assembly.Load("FactoryMethod").CreateInstance(Config.FactoryType);IOperoper=factory.GetOper();doublem=oper.Cal(25,36);}}publicstaticclassConfig{publicstaticstringFactoryType="}}26QQ老师,在工厂Factory到了什么抽象工厂模式 体工厂提供规则定义。就像图4所示的开发商的案例中,销售总部负责为各销售分部定以在这里预定只是批发商和生产商的一种事先约定。而香肠由于产业规模做的很大,7套为Access,一套为SQLServer,并且在程序中应该能够随时按照用户要求,通过界面上的AccessSQLServer数据库中的操作方式,4:AccessSQLServer两套数788中,StuInfoManager为解决方案名称,BLL为业务规则层项目,用于管理各个模块夹下,为各个模块Access数据库的数据类,SQLServer文件夹下为各个模块SQLServer数据库的数据类;DBFactory为工厂类所在的项目,管理各抽象工厂类和各个Config中,实际应用中可改用配置文件或其它方式。4publicclassInfoManager{publicintDeleteInfoData(string{Factory对象得到IInfoIInfoFactoryfactory=new IInfoinfo=factory.GetInfoService();returninfo.DeleteInfoData(stuID);}}publicinterfaceIInfo{intDeleteInfoData(string}/*****************模块数据类//学员基本信息模块的Access数据库的数据publicclass{publicintDeleteInfoData(string{…}}//学员基本信息模块的SQLServer数据库的数据publicclass{publicintDeleteInfoData(string{…}} classFactory{ IInfoGetInfoService();}//得到Access数据库的数据类(实体产品)的工厂类(实体工厂publicclassAccessFactory:{publicoverrideIInfo{returnnew}}//得到SQLServer数据库的数据类(实体产品)的工厂类(实体工厂publicclassSQLServerFactory:{publicoverrideIInfo{returnnew}}我们先来复下我们前面讲过的一些OOP原则PrinciplePrinciple编程。对于不同层次的编程,次给低层次的应当只是接口,而不是它的具体类。DemeterFactory类是一个工厂类,我们称为抽象工厂类,因为它不产生实际的产品,只是用于获得或指向实体工厂当增加新的产品族产品时如再增加一套Oracle数据库的数据OracleFactory就可以了,所以此处符合开闭原则。但是我们再增加一个新的产品时,如增加一关于学员成绩模块的相关内容,则可能需要操作IScores接口,用以定publicIScoresGetScoresService();在上述实现代码中,AccessFactory和SQLFactory分别为得到Access数据库的数据类(实体产品)和SQLServer数据库的数据类(实体产品)的实体工厂,由于得DAL.Access.InfoService和DAL.SQLServer.InfoService属性同一模块两套数据库的两套944Factory5:44publicclassInfoManager{publicintDeleteInfoData(string{Factoryfactory=Factory.CreateFactory();IInfoinfo=factory.GetInfoService();returninfo.DeleteInfoData(stuID);}}publicinterfaceIInfo{intDeleteInfoData(string}/*****************模块数据类//学员基本信息模块的Access数据库的数据publicclass{publicintDeleteInfoData(string{…}}//学员基本信息模块的SQLServer数据库的数据publicclass{publicintDeleteInfoData(string{…}}publicstaticclass{//操作类型。DBFactory.AccessFactory:Access;当前库为publicstaticstringFactoryType="DBFactory.SQLServerFactory} classFactory{publicstaticFactory{stringfactoryType=Config.FactoryType;Factoryfactory=returnfactory; IInfo}//得到Access数据库的数据类(实体产品)的工厂类(实体工厂publicclassAccessFactory:{publicoverrideIInfo{returnnew}}//得到SQLServer数据库的数据类(实体产品)的工厂类(实体工厂publicclassSQLServerFactory:{publicoverrideIInfo{returnnew}}单例模式有一个,可以使用单例模式描述,避免的发生。代码演示:单例模式(饿汉式publicclass{privateTest(){privatestaticTesttest=newTest();publicstaticTestGetInstance(){return}}代码演示:单例模式(懒汉式publicclass{privateTest(){privatestaticTesttest=null;publicstaticTest{lock(typeof(Test)){if(test=={test=newTest();returntest;}return}}},,QQ老师,为什么懒汉式中的GetInstance方法中要加上lock(typeof(Test句A懒汉式的GetInstance方法要首先判断唯一实例是否存在,不存在则创建。在判程锁定机制也会降低并 的效率设计模式模板模式 如连锁品牌“街客”以提供现做的饮料而闻名,大部分“街客”的加盟店都是街1“街客”的就在于可复用的流程和节点,虽然提供数十种不同的饮品,但制作流21:usingnamespaceTem{class{staticvoidMain(string[]{Console.Wriine("草莓刨冰:");drinknew草莓刨冰();Console.Wriine("凤梨刨冰:");drink=new凤梨刨冰();}} class{protectedvoid碎冰{ ine("30克冰块。}protectedvoid加水{ } void加果汁 void装杯publicvoid制作(){碎冰加水加果汁装杯}}class草莓刨冰:{protectedoverridevoid加果汁{ }protectedoverridevoid装杯{ }}class凤梨刨冰:{protectedoverridevoid加果汁{ }protectedoverridevoid装杯{ }}}刨冰饮料drink=new草莓刨冰(); drink=new凤梨刨冰(); QQ老师,为什么在抽象类“刨冰饮料”中protected修饰流程节点的方法都A使用protected修饰的方法只能被本包和子 ,因为流程节点不需要对外Q老师,在“制作”方法中,调用了“加果汁”和“装杯”这两个抽象方法,抽A银行计算利息案3门面模式因为爱听音乐,买了一套7.1的音响系统,由左右前置音箱、左右后置音箱、左右环绕音箱和低音组成,使用时发现要调整音量非常麻烦,需要分别调整7个音箱的音量,47为了方便调整音量,又买了一个中控台,现在只需要对中控台发出音量调整的指7个音箱,如下图所示:图5只需要调整中控在此例中,中控台就是门面模式的实际应用,使用中控台,不需要再与7个音箱台)为用户提供了粗粒度的操作,封装了细粒度的操作。门面模式符合迪法则,用户QQ usingSystem;namespaceFacadeDemo{class{staticvoidMain(string[]{ControlFacadecontrolFacade=newControlFacade(); }}

publicclass{SoundBox1box1=newSoundBox1();SoundBox2box2=newSoundBox2();SoundBox3box3=newSoundBox3();SoundBox4box4=newSoundBox4();SoundBox5box5=newSoundBox5();SoundBox6box6=newSoundBox6();SoundBox7box7=newpublicvoid{}publicvoid{}}publicclass{publicvoid{ }publicvoid{ }}publicclass{publicvoid{ }publicvoid{ }}publicclass{publicvoid{ }publicvoid{ }}publicclass{publicvoid{ }publicvoid{ }}publicclass{publicvoid{ }publicvoid{ }}publicclass{publicvoid{ }publicvoid{ }}publicclass{publicvoid{ }publicvoid{ }}}策略模式OOP设计原则下,使用者可以灵活的选择具体的策2:usingnamespace{class{staticvoidMain(string[]{doubleoldPrice=DiscountContextcontextnew if(DateTime.Now.Month==5&&DateTime.Now.Day=={context.SetDiscountType(new}elseif(DateTime.Now.Month==10&&DateTime.Now.Day=={context.SetDiscountType(new}doublerealPrice=context.Discount(oldPrice); ine(":"+oldPrice.ToString()); ine("折扣价:realPrice.ToString());}}publicclassDiscountContext{privateDiscountpublicDiscountContext(Discount{this.discount=}publicvoidSetDiscountType(Discount{this.discount=}publicdoubleDiscount(double{return}}//抽象策略(通过抽象策略具体策略 class{ doubleDisc(double}public mon:{publicoverridedoubleDisc(double{returnd*}}publicclassDiscount_51:{publicoverridedoubleDisc(double{returnd*}}//10.1节的折扣策略(具体策略publicclassDiscount_101:{publicoverridedoubleDisc(double{returnd*}}}上述代码实现了平常日期、5.1劳动节及10.1节三个具体的折扣策略(分别Discount_101(Discount了一个使用上下文DiscountContext,该类封装了通过抽象策略实现折扣计算。在调用程序桂枝为臣药辅助发汗,杏仁为佐药平喘,为使药调、臣、使三者的药性;如果认为汗,、生姜、大枣为使药调和各药的药性。下面是两个情景的示意类图:34设计模式1.模式的类模式就是通过增加对象将对象间的直接形式改为间接形式所谓对象间的直接,指对象A持有对象B的实例,然后通过该实例调用对象B中的方法;而对象间的间接,指对象A持有对象C的实例,当对象A调用对象C的方法时对象C委托对象B中的方法进行功能实现,一般来说,对象C应与对象B“兼容(实现同一接口或集成同一父类,使对象A(实例持有者)体会不到对象B与对象C的区别,如图1对象直接与间接的区图2对象C也可以多个目标对将对象的形式由直接变为间接后,对象C(称为对象,)能够B(称为目标对象,Target)B提供保护,或提供额外的操作对象的功能不同,可以将模式划分为以下几个种类保Web开发中,一般可将安全防护分为三个级别,即页面级安全、方法级安全和数据级安全。页面级安全我们都很熟悉,往往通过Session获取用户名后检查其是否具有该至于数据级安全则取决于业务需求,比如销售系统中,销售员只能查看个人的,不能查看其他销售员的就是一种数据级的安全需求。智虚、的加载或应用程序加载数据时,当操作比较消耗资源时通过虚拟实现提示用、。(Ambassador,而不是的,而对象承担了大部分的网络通信工作Cache为某一个目标操作的结果提供临时的空间,以便多个客户端可以共享这些结果保护目标,不让用户接近同步使几个用户能够同时使用一个对象而没有在所有种类的模式中,虚拟(Virtual)、(Remote)、智能代理(SmartReference)和保护(ProtectorAccess)是最为常见的模式。判断下面的情景是否使用了模式,是哪种类型的模式图 2.模式的实在模式的实现中,最的部分就是创建对象。一般要求对象和目标对象的使用

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论