|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
Java的桌面程序开发在java程序员里通常叫swing开发,主要用的swing包里的类开发的,也就是通常说的c/s架构开发编程|原则Java编程原则内容摘录自:《Java编程头脑》第2版《附录CJava编程原则》/(美)埃克尔(Eckel,B)著;候捷译的,机器产业出书社,2002.9版权回原作者和原出书社。这份附录所供应的倡议,能够匡助你举行低阶的程序计划,并匡助你写码。固然,这些都只是一种目标而不是硬性划定规矩。你应当视它们为一种灵感来历。记着,某些情形下你必要加以变通或乃至冲破划定规矩。计划1.文雅必要支付价值。从短时间好处来看,对某个成绩提出文雅的办理办法,仿佛大概花你更多的工夫。但当它终究可以准确实行并可容易套用于新案例中,不必要花上数以时计,乃至以天计或以月计的辛劳价值时,你会看失掉先前所花工夫的报答(即便没有人能够权衡这一点)。这不但给你一个可更简单开辟和调试的程序,也更容易于了解和保护。这恰是它在款项上的代价地点。这一点有赖某种人生履历才干够懂得,由于当你勉力让某一段程序代码变得对照文雅时,你并非处于一种具临盆力的形态下。可是,请顺从那些敦促你赶工的人们,由于那末做只会减缓你的速率而已。2.先求能动,再求快。即便你已断定某段程序代码极其主要,并且是体系的主要瓶颈,这个原则仍然建立。尽量简化计划,让体系可以先准确举措。假如程序的实行不敷快,再量测其效能。几近你老是会发明,你所以为的"瓶颈"实在都不是成绩地点。把你的工夫花在刀口上吧。3.记着"各个击破"的道理。假如你所切磋的成绩过于混同,试着想像该成绩的基础举措会是甚么,并假定这一小块工具可以奇妙地处置失落最难的部分。这"一小块"工具实在就是对象--请撰写使用该对象的程序代码,然后检视对象,并将个中坚苦的部分再包装成其他对象,依此类推。4.辨别class开辟者和class利用者(利用端程序员)。Class利用者饰演着"客户"脚色,不必要(也不晓得)class的底层运作体例。Class开辟者必需是class计划专家,并撰写class,使它可以尽量被年夜多半老手程序员所用,并且在程序中可以妥当实行。一套程序库只要在具有通透性的情形下,利用起来才会简单。5.当你撰写class时,试着赐与了然易懂的称号,削减不用要的注解。你给客户端程序员的接口,应当坚持观点上的纯真性。不了这个目标,当函数的重载(overloading)合适制造出直觉、易用的接口时,请善加利用。6.也必你的剖析和计划必需让体系中的classes坚持起码,须让其Publicinterfaces坚持起码,和让这些classes和其他classes之间的联系关系性(特别是baseclasses)坚持起码。假如你的计划所得了局愈甚于此,叨教问本人,是不是个中每样工具在全部程序性命期中都富足代价?假如并不是云云,那末,保护它们会使你支付价值。开辟团队的成员都有不保护"不利于临盆力提拔"的任何工具的偏向;这是很多计划办法没法注释的征象。7.让一切工具只管主动化。先撰写测试用的程序代码(在你撰写class之前),并让它和class分离在一同。请利用makefile或相似工具,主动举行测试举措。经由过程这类体例,只需实行测试程序,一切的程序变化就能够主动取得考证,并且能够当即发明毛病。因为你晓得的测试架构所具有的平安性,以是当你发明新的需求时,你会更勇于举行周全修正。请记着,程序言语最年夜的改善,是来自型别反省、非常处置等机制所付与的内置测试举措。但这些功效只能帮忙你抵达某种水平。开辟一个安定体系时,你得本人考证本人的classes或程序的性子。8.在你撰写class之前先写测试码,以便考证你的class是不是计划完整。假如你没法撰写测试码,你便没法晓得你的class的大概长相。撰写测试码一般可以展现出分外的特征(features)或限定(constraints)__它们其实不必定老是可以在剖析和计划过程当中呈现。测试码也可做为展现class用法的示例程序。9.一切软件计划上的成绩,都能够经由过程"引进分外的观点性直接层(conceptualindirection)"加以简化。这个软件工程上的基本法例是笼统化观点的依据,而笼统化观点恰是面向对象程序计划的次要性子。10.直接层(indirection)应当要成心义(和原则-9致)。这里所指的意义能够像"将共用程序代码置于唯一函数"这么复杂。假如你到场的直接层(或笼统化、或封装等等)不具意义,它大概就和没有得当的直接层一样糟。11.让class尽量巨大而没法切割(atomic)。付与每一个class单一而分明的用处。假如你的classes或你的体系发展得过于庞大,请将庞大的classes切割成对照复杂的几个classes。最分明的一个判别指针就是class的巨细:假如它很年夜,那末它事情量过量的时机便可能很高,那就应当被切割。从头计划class的倡议线索是:1)庞大的switch语句:请思索使用多态(Polymorphism)。2)很多函数各自处置范例极其分歧的举措:请思索切割为多个分歧的(classes)。12.当心冗杂的引数列(argumentlists)。冗杂的引数列会使函数的挪用举措不容易撰写、浏览、保护。你应当试着将函数搬移到更得当的class中,并只管以对象为引数。13.不要几回再三反复。假如某段程序代码不休呈现于很多derivedclass函数中,请将该段程序代码置于某个baseclass函数内,然后在derivedclass函数中挪用。这么做不但能够省下程序代码空间,也能够让修正该段程序代码举措更容易于举行。偶然候找出此种共通程序代码还能够为接口增添有用功效。14.当心switch语句或成串的if-else子句。一般这类情形代表所谓的"type-checkcoding"。也就是说事实会实行哪一段程序代码,乃是根据某种型别信息来做决定(最后,切实型别大概不非常分明)。你一般可使用承继和多态来代替此类程序代码;Polymorphicalmethod(多态函数)的挪用会主动实行此范例别查验,并供应更牢靠更简单的扩大性。15.从计划概念来看,请找出变化的事物,并使它和稳定的事物分别。也就是说,找出体系中大概被你改动的元素,将它们封装于classes中。你能够在《ThinkinginPatternswithJava》(可收费下载于www.BruceEckel.com)大批进修到这类看法。16.不要使用subclassing来扩大基本功效。假如某个接口元素对class而言极主要,它应当被放在baseclass外头,而不是直到衍生(derivation)时才被到场。假如你在承继过程当中到场了函数,也许你应当从头思索全部计划。17.少就是多。从class的最小接口入手下手妨展,尽量在办理成绩的条件下让它坚持既小又纯真。不要事后考量你的class被利用的一切大概体例。一旦class被实践使用,你天然会晓得你得怎样扩大接口。不外,一旦class被利用后,你就没法在不影响客户程序代码的情形下缩减其接口。假如你要到场更多函数却是没有成绩--不会影响既有的客户程序代码,它们只需从头编译便可。但即便新函数代替了旧函数的功效,也请你保存既有接口。假如你得经由过程"到场更多引数"的体例来扩大既有函数的接口,请你以新引数写出一个重载化的函数;经由过程这类体例就不会影响既有函数的任何客户了。18.高声念出你的classes,确认它们切合逻辑。请baseclass和derivedclass之间的干系是"is-a"(是一种),让class和成员对象之间的干系是"has-a"(有一个)。19.当你优柔寡断于承继(inheritance)或分解(组合,composition)时,请你问问本人,是不是必要向上转型(upcast)为基本型别。假如不必要,请优先选择分解(也就是是利用成员对象)。这类作法能够打消"过量基本型别"。假如你接纳承继,利用者会以为他们应当能够向上转型。20.使用数据成员来暗示数值的变更,使用经由覆写的函数(overridedmethod)来代表举动的变更。也就是说,假如你找到了某个class,带有一些形态变量,而其函数会根据这些变量值切换分歧的举动,那末你也许就应当从头计划,在subclasses和覆写后的函数(overridedmethods)中展示举动止的差别。21.当心重载(overloading)。函数不该该根据引数值前提式地选择实行某一段程序代码。这类情形下你应当撰写两个或更多个重载函数(overloadedmethods)22.利用非常系统(exceptionhierarchies)__最好是从Java尺度非常系统中衍生特定的classes,那末,捕获非常的人即可以捕获特定非常,以后才捕获基础非常。假如你到场新的衍生非常,原本的客户端程序仍能经由过程其基本型别来捕获它。23.偶然候复杂的聚合(aggregation)就够了。飞机上的"搭客温馨体系"包含数个分别的元素:座椅、空调、视讯设备等等,你会必要在飞机上发生很多如许的工具。你会将它们声明为Private成员并开辟出一个全新的接口吗?不会的,在这个例子中,元素也是Public接口的一部分,以是仍旧是平安的。固然啦,复杂聚兼并不是一个常被使用的解法,但偶然候切实其实是。24.试着从客户程序员和程序保护的角度思索。你的class应当计划得尽量简单利用。你应当事后考量大概性有的变化,并针对这些大概的变化举行计划,使这些变化往后可容易完成。25.当心"伟大对象并发症"。这常常是刚踏OOP范畴的历程式(procedural)程序员的一个忧?,由于他们常常终极仍是写出一个历程式程序,并将它们摆放到一个或两个伟大对象中。注重,除applicationframework(使用程序框架,译注:一种很特别的、年夜型OO程序库,帮你架构程序本体)以外,对象代表的是程序中的看法,而不是程序自己。26.假如你得用某种丑恶的体例来告竣某个举措,请将丑恶的部分范围在某个class外头。27.假如你得用某种不成移植体例来告竣某个举措,请将它笼统化并范围于某个class外头。如许一个"分外直接层"可以避免不成移植的部分分散到全部程序。这类作法的详细出现即是Bridge计划形式(designpattern)。28.对象不该仅仅只用来持无数据。对象也应当具有界说明白界线分明的举动。偶然候利用"数据对象"是得当的,但只要在通用描述器不合用时,才合适决心以数据对象来包装、传输一群数据项。29.欲从既有的classes身上发生新的classes时,请以组合(composition)为优先考量。你应当只在需要时才利用承继。假如在组符合用的地方你却选择了承继,你的计划就渗杂了非需要的庞大性。30.使用承继和函数覆写机制来展示举动上的差别,使用fields(数据成员)来展示形态上的差别。这句话的极度例子,就是承继出分歧的classes体现各类分歧的色彩,而不利用"color"field.31.小心变同性(variance)。语意相异的两个对象具有不异的举措(或说义务)是大概的。OO天下中存在着一种生成的勾引,让人想要从某个class承继出另外一个subclass,为的是取得承继带来的福利。这即是所谓"变同性"。可是,没有任何合法来由足以让我们强制打造出某个实在其实不存在的superclass/subclass干系。对照好的办理体例是写出一个共用的baseclass,它为两个derivedclasses制造出共用接口--这类体例会耗用更多空间,但你能够如你所企望地从承继机制取得优点,并且也许可以在计划上取得严重发明。32.注重承继上的限定。最明晰易懂的计划是将功效加到承继得来的class外头;承继过程当中拿失落旧功效(而非增添新功效)则是一种可疑的计划。不外,划定规矩能够冲破。假如你所处置的是旧有的class程序库,那末在某个class的subclass限定功效,大概会比从头制订全部布局(俾使新class得以优秀地相当于旧class)无效率很多。33.利用计划形式(designpatterns)来削减"光秃秃无加掩盖的性能(nakedfunctionality)"。举个例子,假如你的class只应当产出唯一一个对象,那末请不要以加思考毫无计划的伎俩来完成它,然后撰写"只该发生一份对象"如许的注解就拍拍屁股走人。请将它包装成singleton(译注:一个着名的计划形式,可译为"单件")。假如主程序中有多而凌乱的"用以发生对象"的程序代码,请找出相似factorymethod如许的天生形式(creationalpatterns),使代价可用以封装天生举措削减"光秃秃无加掩盖的性能"(nakedfunctionality)不但可让你的程序更容易了解和保护,也能够制止出于美意却带来不测的保护者。34.小心"因剖析而招致的瘫痪(analysisparalysis)"。请记着,你常常必需在取得一切信息之前让项目持续行进。并且了解未知部分的最好也最快的体例,一般就是实践行进一步而不但是夸夸其谈。除非找到办理举措,不然没法晓得办理举措。Java具有内置的防火墙,请让它们发扬感化。你在单一class或一组classes中所犯的毛病,其实不会危险全部体系的完全性。35.当你以为你已取得一份优异的剖析、计划或完成时,请试着加以练习训练。将团队之外的某些人带出去-他不用非得是个参谋不成,他能够是公司其他团队的成员。请谁人人以奇怪的姿势审阅你们的功效,如许能够在尚可容易修正的阶段找出成绩,其劳绩会比因练习训练而支付的工夫和款项价值来得高。完成(Implementation)36.一样平常来讲,请恪守Sun的程序编写习气。代价能够在以下网址找到相干文档:java.sun.com/docs/codeconv/idex.html。本书尽量恪守这些习气。浩瀚Java程序员看到的程序代码,都有是由这些习气组成的。假如你刚强地停止在已往的编写作风中,你的(程序代码)读者会对照辛劳。不管你决意接纳甚么编写习气,请在全部程序中坚持分歧。你能够在home.wtal.de/software-solutions/jindent上找到一个用来重排Java程序的收费工具。37.不管利用何种编写作风,假如你的团队(或全部公司,那就更好了)可以加以尺度化,那末切实其实会带来明显效果。这代表每一个人都能够在其别人不恪守编写作风修正其作品,这是个公允的游戏。尺度化的代价在于,剖析程序代码时所花的脑力较小,因此能够用心于程序代码的本色意义。38.恪守尺度的巨细写标准。将class称号的第一个字母应为年夜写。数据成员、函数、对象(references)的第一个字母应为小写。一切辨认称号的每一个字都应当连在一起,一切非首字的第一个字母都应当年夜写。比方:ThisIsAClassNamethisIsAMethodOrFieldName假如你在staticfinal基础型其余界说处指定了常量初始式(constantinitializers),那末该辨认称号应当全为年夜写,代表一个编译期常量。Packages是个惯例,其称号皆为小写,即便非首字的字母亦是云云。域名(org,net,edu等等)皆应为小写。(这是Java1.1迁徙至Java2时的一项改动)39、不要本人创造"粉饰用的"Private数据成员称号。一般这类的情势是在最前端加上底线和其他字符,匈牙利定名法(Hungariannotation)是个中最差的树模。在这类定名法中,你得到场分外字符来暗示数据的型别、用处、地位等等。似乎你用的是汇编言语(assemblylanguage)而编译器没有供应任何协肋似的。如许的定名体例简单让人搅浑又难以浏览,也不容易奉行和保护。就让classes和packages来举行"称号上的局限制订(namescoping)"吧。40、当你制定通用性的class时,请恪守正轨情势(canonicalform)。包含equals()、hashCode()、clone()(完成出Cloneable),并完成出Comparable和Serialiable等等。41、关于那些"获得或改动Private数据值"的函数,请利用JavaBeans的"get"、"set"、"is"等定名习气,即便你事先不以为本人正在撰写JavaBean。这么做不但能够容易以Bean的使用体例来使用你的class,也是对此类函数的一种尺度定名体例,使读者更容易于了解。。42、关于你所制定的每个class,请思索为它到场staticpublictest(),个中含有class功效测试码。你不必要移除该测试便可将程序归入项目。并且假如有所变化,你能够容易从头实行测试。这段程序代码也能够做为class的利用示例。43、偶然候你必要经由过程承继,才得以会见baseclass的protected成员。这大概会激发对多重基类(multiplebasetypes)的熟悉需求。假如你不必要向上转型,你能够先衍生新的class发便实行protected会见举措,然后在"必要用到上述protected成员"的一切classes中,将新class声明为成员对象,而非间接承继。44、制止地道为了效力考量而利用final函数。只要在程序能动但实行不敷快时,并且效能量测工具(profiler)显现某个函数的挪用举措成为瓶颈时,才利用final函数。45、假如两个classes因某种功效性缘故原由而发生了联系关系(比方容器containers和迭代器iterators),那末请试着让个中某个class成为另外一个class的内隐类(innerclass)。这不但夸大两者间的联系关系,也是经由过程"将class称号嵌套置于另外一个class内"而使统一个class称号在单一Package中可被反复利用。Java容器库在每一个容器类中都界说了一个内隐的(inner)Iteratorclass,因此可以供应容器一份共通接口。使用内隐类的另外一个缘故原由是让它成为private完成物的一部分。在这里,内隐类会为信息埋没带来优点,而不是对上述的class联系关系性供应肋益,也不是为了避免定名空间净化成绩(namespacepollution)。46、任什么时候候你都要注重那些高度耦合(coupling)的classes.请思索内隐类(innerclasses)为程序制定和保护带来的优点。内隐类的利用并非要往除classes间的耦合,而是要让耦合干系更分明也更便当。47、不要成为"过早最好化"的就义品。那会让人神经庞杂。特别在体系建构早期,先别懊恼事实要不要撰写(或制止)原生函数(nativemethods)、要不要将某些数声明为final、要不要调校程序代码效力等等。你的次要成绩应当是先证实计划的准确性,除非计划自己必要某种水平的效力。48、让局限(感化域,scope)尽量愈小愈好,这么一来对象的可视局限和寿命都将尽量地小。这类作法可下降"对象被用于毛病场合,因此埋没难以发觉的臭虫"的时机。假定你有个容器,和一段访问该容器的程序片断。假如你复制该段程序代码,将它用于新的容器身上,你大概会不当心以旧容器的巨细做为新容器的访问下限值。假如旧容器已不在会见局限内,那末编译期即可找出如许的毛病。49、利用Java尺度程序库供应的容器。请熟习他们的用法。你将因而年夜幅提拔你的临盆力。请优先选择ArrayList来处置序列(sequences),选择HashSet来处置汇合(sets)、选择HashMap来处置联系关系式数组(associativearrays),选择Linkedlist(而不是Stack)来处置shacks和queues。50、对一个巩固的(robust)程序而言,每个构成都必需巩固。请在你所撰写的每一个class中使用Java供应的一切巩固提拔工具:会见权限、非常、型别查验等等。经由过程这类体例,你能够在建构体系时平安地移往笼统化的下一个条理。51、宁肯在编译期产生毛病,也不要在实行期产生毛病。试着在最接近成绩产生点的中央处置成绩。请优先在"掷出非常的地方"处置成绩,并在具有充足信息以处置非常的最靠近处置函数(handler)中捕获非常。请举行现阶段你可以对该非常所做的处置;假如你没法办理成绩,应当再次掷出非常。52、小心冗杂的函数界说。函数应当是一种冗长的、"形貌并完成class接口中某个可分别部分"的功效单位。太长且庞大的函数不但难以保护,保护价值也高。也许它实验做太多事变了。假如你发明这一类函数,代表它应当被切割成多相函数。这类函数也提示你也许得撰写新的class。小型函数一样可以在你的class中被反复使用。(偶然候函数必需很年夜才行,但它们应当只做一件事变。)53、尽量坚持"Private"。一旦你对外公然了程序库的概略(method、Class或field)。你便再也没法移除它们。由于假如移除它们,便会损坏某个现有的程序代码,使得它们必需从头被编写或从头计划。假如你只公然需要部分,那末你即可以改动其他工具而不形成危险。计划老是会演变,以是这是个非常主要的自在度。经由过程这类体例,完成码的更动对derivedclass酿成的打击会降最低。在多线程情况下,私密性情外主要-只要private数据可受回护而不被un-synchronized(未受同步把持)的使用所损坏。54、大批使用注解,并利用javadoc的"注解文档语法"来发生程序的申明文档。不外注解应当付与程序代码真实的意义;假如只是重申程序代码已明白暗示的内容,那是很烦人的。请注重,一般Javaclass和其函数的称号都很长,为的即是下降注解量。55、制止利用"把戏数字",也就是那种写逝世在程序代码外头的数字--假如你想改动它们,它们就会成为你的噩梦,由于你永久都没有举措晓得"100"事实代表"数组巨细"或其他工具。你应当发生具形貌性的常量度称号,并在程序中利用该常量称号。这使程序更容易于了解也更容易于保护。56、撰写机关函数时,请思索非常形态。最好情境下,机关函数不实行任何会掷出非常的举措。次佳情境下,class只承继自(或分解自)巩固的(robust)classes,以是若有任何非常被掷出,其实不必要清算。其他情形下,你就得在finally子句清算分解后的classes。假如某个机关函数必定会失利,得当的举措就是掷出非常,使挪用者不至于自觉以为对象已被准确发生而持续实行。57、假如你的class必要在"客户程序员用完对象"落后行清算举措,请将清算举措,放到单一而界说明白的函数中。最好令其称号为cleanup()以便可以将用处告知别人。别的请将boolean旗标放到class中,用以代表对象是不是已被清算,使finalize()得以查验其出生前提(请参考第4章)。58、finalize()只可用于对象出生前提的查验(请参考4章),俾无益于调试。特别情形下大概必要开释一些不会被渣滓接纳的内存。由于渣滓接纳器大概不会被唤起处置你的对象,以是你没法利用finalize()实行需要的清算举措。基于这个缘故原由,你得制定本人的"清算用"函数。在classfinalize()中,请反省确认对象切实其实已被清算,并在对象还没有被清算时,掷出衍生自RuntimeException的非常。利用这类架构前,请先确认finalize()在你的体系上可一般举措(这大概必要挪用System.gc()来确认)。59、假如某个对象在某个特定局限(scope)内必需被清算(cleanedup),而不是被渣滓接纳机制发出,请利用以下办法;将对象初始化,乐成后立即进进具有finally子句的一个try区段内。Finally子句会激发清算举措。60、当你在承继过程当中覆写了finalize(),请记得挪用super.finalize()。但假如你的"间接上一层superclass"是Object,,就不必要这个举措。你应当让super.finalize()成为被覆写(overridden)之finalize()的最初一个举措而不是第一个举措,用以确保baseclass的组件在你必要它们的时分仍旧可用。61、当你撰写流动巨细的对象容器,请将它们转换为数组--特别是从某个函数前往此一容器时。经由过程这类体例,你能够取得数组的"编译期型别查验"的优点,并且数组吸收者大概不必要"先将数组中的对象加以转型"便能加以利用。请注重,容器库的baseclass(Java.util.Collection)具有两个toArray(),可以到达这个目标。。62、在interface(接口)和abstractclass(笼统类)之间,优先选择前者。假如你晓得某些工具行将被计划为一个baseclass,你的第一选择应当是让它成为interface;只要在必定得放进函数或数据成员时,才应当将它改成abstractclass.Interface只和"客户端想举行甚么举措"有关,class则对照把重心放在完成细节上。63、在机关函数中只做唯一需要举措:将对象设定至得当形态。制止挪用其他函数(除final函数),由于这些函数大概会被其别人覆写因此使你在建构过程当中得不成预期的了局(请参考第7章以获得更具体的信息)。小型而复杂的机关函数对照不成能掷出非常或激发成绩。64、为了不一个非常使人气馁的履历,请确认你的classpath中的每一个称号,都只要一个未被放到packages外头class。不然编译器会先找到另外一个称号不异的class,并报答毛病动静。假如你嫌疑你的classpath出了成绩,试着从classpath中的每一个出发点查找同名的.class文件。最好仍是将一切classes都放到packages外头。65、寄望一不当心犯下的重载(overloading)毛病。假如你覆写baseclass函数时没有准确拼写其称号,那末便会增添一个新的函数,而不是覆写原本的函数。可是情形完整正当,以是你不会从编译器或实行期体系失掉任何毛病动静--你的程序代码只是没法准确感化,云云罢了。66、小心过早最好化。先让程序动起来,再让它快--但只要在你必需(也就是说只要在程序被证实在某段程序代码上遭受效能瓶颈)时才这么做。除非你已利用效能量测工具(profiler)找出瓶颈地点,不然你大概性只是在华侈你的工夫。效能调校的"埋没本钱"即是让你的程序代码变得更不成读、更难保持。67、记着,程序代码被浏览的工夫多于它被撰写的工夫。明晰的计划可以制造进来易懂的程序。注解、细节申明、示例都是无价的。这些工具可以匡助你和你的后继者。假如没有其他信息,那末Java线上文档找出一些有效的信息时,你所遭受的挫败应当足以让你信任这一点。
java比较简单,没有C++的烦琐,但学习时最好有C++为基础.与JSP和SQL起应用,功能强大. |
|