前腐后继 发表于 2006-12-8 19:50:00

Source Code Standards

<strong><br/><br/></strong>Source&nbsp;Code&nbsp;Standards&nbsp; <p></p><p>TIdStrings&nbsp;/&nbsp;TIdStringList&nbsp;-&nbsp;Use&nbsp;these&nbsp;insetad&nbsp;-&nbsp;unless&nbsp;you&nbsp;need&nbsp;sorting.&nbsp;<br/>No&nbsp;assembly&nbsp;-&nbsp;Assembly&nbsp;language&nbsp;is&nbsp;prohibited&nbsp;because&nbsp;it&nbsp;will&nbsp;act&nbsp;differently&nbsp;in&nbsp;Linux&nbsp;than&nbsp;in&nbsp;Win32.&nbsp;Assembly&nbsp;language&nbsp;is&nbsp;also&nbsp;more&nbsp;prone&nbsp;to&nbsp;errors&nbsp;than&nbsp;Pascal.&nbsp;There&nbsp;are&nbsp;few&nbsp;exceptions&nbsp;but&nbsp;those&nbsp;are&nbsp;done&nbsp;after&nbsp;much&nbsp;discussion,&nbsp;ONLY&nbsp;for&nbsp;specific&nbsp;reasons,&nbsp;and&nbsp;only&nbsp;if&nbsp;they&nbsp;do&nbsp;not&nbsp;compromise&nbsp;cross-platform&nbsp;compatibility.&nbsp;<br/>No&nbsp;Goto&nbsp;Statements&nbsp;-&nbsp;Goto&nbsp;statements&nbsp;are&nbsp;prohibited&nbsp;because&nbsp;they&nbsp;often&nbsp;render&nbsp;code&nbsp;unreadable&nbsp;and&nbsp;encourage&nbsp;spaghetti&nbsp;code.&nbsp;Goto&nbsp;is&nbsp;basically&nbsp;a&nbsp;hold&nbsp;over&nbsp;from&nbsp;GWBASIC&nbsp;and&nbsp;the&nbsp;original&nbsp;basic&nbsp;authors&nbsp;had&nbsp;depreciated&nbsp;that&nbsp;feature&nbsp;because&nbsp;it&nbsp;encouraged&nbsp;sloppy&nbsp;programming.&nbsp;<br/>Always&nbsp;use&nbsp;begin..end&nbsp;-&nbsp;All&nbsp;"if",&nbsp;"whiles",&nbsp;"for"&nbsp;must&nbsp;include&nbsp;a&nbsp;"begin...end"&nbsp;even&nbsp;if&nbsp;there&nbsp;was&nbsp;only&nbsp;one&nbsp;line&nbsp;of&nbsp;code&nbsp;in&nbsp;the&nbsp;condition.&nbsp;This&nbsp;is&nbsp;required&nbsp;because&nbsp;we&nbsp;often&nbsp;might&nbsp;have&nbsp;to&nbsp;add&nbsp;something&nbsp;else&nbsp;to&nbsp;conditional&nbsp;execution&nbsp;later&nbsp;on.&nbsp;In&nbsp;addition,&nbsp;compound&nbsp;lines&nbsp;(if&nbsp;condition&nbsp;then&nbsp;exit)&nbsp;can&nbsp;cause&nbsp;unexpected&nbsp;jumps&nbsp;during&nbsp;tracing.&nbsp;<br/>Uses&nbsp;in&nbsp;interface&nbsp;section&nbsp;-&nbsp;Unless&nbsp;there&nbsp;is&nbsp;something&nbsp;in&nbsp;a&nbsp;unit's&nbsp;interface&nbsp;which&nbsp;depends&nbsp;on&nbsp;another&nbsp;unit,&nbsp;the&nbsp;unit&nbsp;should&nbsp;be&nbsp;moved&nbsp;to&nbsp;the&nbsp;implementation&nbsp;uses&nbsp;clause.&nbsp;This&nbsp;increases&nbsp;efficiency&nbsp;in&nbsp;the&nbsp;compiler.&nbsp;<br/>Comments&nbsp;of&nbsp;quirks&nbsp;-&nbsp;If&nbsp;there&nbsp;is&nbsp;an&nbsp;odd&nbsp;quirk&nbsp;or&nbsp;bug&nbsp;in&nbsp;an&nbsp;API&nbsp;that&nbsp;an&nbsp;Indy&nbsp;developer&nbsp;is&nbsp;working&nbsp;around,&nbsp;this&nbsp;should&nbsp;be&nbsp;noted&nbsp;in&nbsp;a&nbsp;comment&nbsp;above&nbsp;the&nbsp;relevant&nbsp;code.&nbsp;This&nbsp;is&nbsp;important&nbsp;in&nbsp;case&nbsp;the&nbsp;developer&nbsp;later&nbsp;forgets&nbsp;or&nbsp;someone&nbsp;else&nbsp;has&nbsp;to&nbsp;work&nbsp;on&nbsp;the&nbsp;unit&nbsp;and&nbsp;may&nbsp;not&nbsp;know&nbsp;about&nbsp;the&nbsp;quirk.&nbsp;Remember&nbsp;that&nbsp;people&nbsp;involved&nbsp;with&nbsp;Indy&nbsp;can&nbsp;come&nbsp;and&nbsp;go.&nbsp;This&nbsp;can&nbsp;also&nbsp;be&nbsp;helpful&nbsp;if&nbsp;the&nbsp;reason&nbsp;for&nbsp;the&nbsp;work-around&nbsp;no-longer&nbsp;exists&nbsp;(a&nbsp;bug&nbsp;was&nbsp;fixed&nbsp;in&nbsp;a&nbsp;patch&nbsp;or&nbsp;years&nbsp;later,&nbsp;it&nbsp;is&nbsp;no&nbsp;longer&nbsp;relevant&nbsp;because&nbsp;support&nbsp;for&nbsp;that&nbsp;API&nbsp;was&nbsp;dropped).&nbsp;<br/>Compiler&nbsp;warnings&nbsp;and&nbsp;hints&nbsp;-&nbsp;There&nbsp;should&nbsp;never&nbsp;be&nbsp;any&nbsp;compiler&nbsp;warnings&nbsp;or&nbsp;hints.&nbsp;This&nbsp;is&nbsp;important&nbsp;because&nbsp;some&nbsp;things&nbsp;could&nbsp;have&nbsp;unintended&nbsp;consequences&nbsp;such&nbsp;as&nbsp;operands&nbsp;being&nbsp;widened,&nbsp;code&nbsp;optimized&nbsp;out&nbsp;by&nbsp;the&nbsp;compiler&nbsp;even&nbsp;if&nbsp;the&nbsp;code&nbsp;was&nbsp;doing&nbsp;something&nbsp;necessary,&nbsp;and&nbsp;some&nbsp;people&nbsp;might&nbsp;assume&nbsp;there&nbsp;was&nbsp;some&nbsp;sloppiness&nbsp;and&nbsp;get&nbsp;a&nbsp;bad&nbsp;impression.&nbsp;<br/>Use&nbsp;of&nbsp;ancestor&nbsp;code&nbsp;-&nbsp;If&nbsp;code&nbsp;is&nbsp;used&nbsp;in&nbsp;more&nbsp;than&nbsp;one&nbsp;place,&nbsp;it&nbsp;should&nbsp;be&nbsp;placed&nbsp;in&nbsp;an&nbsp;ancestor&nbsp;class.&nbsp;For&nbsp;example,&nbsp;TIdQuotD&nbsp;and&nbsp;TIdDayTime&nbsp;simply&nbsp;connect&nbsp;to&nbsp;the&nbsp;server&nbsp;and&nbsp;retrieve&nbsp;data&nbsp;until&nbsp;the&nbsp;connection&nbsp;closes.&nbsp;Thus,&nbsp;the&nbsp;TIdTCPClient&nbsp;has&nbsp;a&nbsp;method&nbsp;called&nbsp;ConnectAndGetAll&nbsp;which&nbsp;does&nbsp;this.&nbsp;Thus,&nbsp;the&nbsp;main&nbsp;difference&nbsp;between&nbsp;TIdQuotD&nbsp;and&nbsp;TIdDayTime&nbsp;is&nbsp;simply&nbsp;a&nbsp;name&nbsp;of&nbsp;function&nbsp;and&nbsp;a&nbsp;different&nbsp;default&nbsp;port.&nbsp;This&nbsp;reduces&nbsp;errors&nbsp;and&nbsp;helps&nbsp;optimize&nbsp;code&nbsp;as&nbsp;well&nbsp;as&nbsp;fixing&nbsp;a&nbsp;bug&nbsp;in&nbsp;several&nbsp;places.&nbsp;<br/>No&nbsp;private&nbsp;sections&nbsp;-&nbsp;Nothing&nbsp;in&nbsp;Indy&nbsp;is&nbsp;ever&nbsp;placed&nbsp;in&nbsp;the&nbsp;component's&nbsp;private&nbsp;section.&nbsp;Some&nbsp;things&nbsp;which&nbsp;are&nbsp;not&nbsp;used&nbsp;outside&nbsp;of&nbsp;the&nbsp;component&nbsp;are&nbsp;placed&nbsp;in&nbsp;the&nbsp;protected&nbsp;section&nbsp;so&nbsp;they&nbsp;can&nbsp;be&nbsp;used&nbsp;by&nbsp;descendant&nbsp;classes.&nbsp;In&nbsp;addition,&nbsp;most&nbsp;methods&nbsp;should&nbsp;be&nbsp;virtual&nbsp;so&nbsp;descendant&nbsp;classes&nbsp;can&nbsp;override&nbsp;them&nbsp;if&nbsp;necessary.&nbsp;<br/>Low&nbsp;Level&nbsp;Code&nbsp;-&nbsp;Low&nbsp;level&nbsp;functionality&nbsp;code&nbsp;(such&nbsp;as&nbsp;calling&nbsp;socket&nbsp;function)&nbsp;should&nbsp;not&nbsp;be&nbsp;used&nbsp;directly&nbsp;by&nbsp;high-level&nbsp;classes.&nbsp;They&nbsp;should&nbsp;be&nbsp;accessed&nbsp;through&nbsp;intermediate&nbsp;classes&nbsp;such&nbsp;as&nbsp;TIdSocketHandle.&nbsp;The&nbsp;reason&nbsp;is&nbsp;so&nbsp;that&nbsp;any&nbsp;changes&nbsp;we&nbsp;need&nbsp;at&nbsp;a&nbsp;low&nbsp;level&nbsp;would&nbsp;only&nbsp;require&nbsp;adjustments&nbsp;to&nbsp;the&nbsp;intermediate&nbsp;class's&nbsp;code.&nbsp;<br/>Variable&nbsp;prefixes&nbsp;-&nbsp;Arguments&nbsp;are&nbsp;prefixed&nbsp;with&nbsp;A,&nbsp;unless&nbsp;they&nbsp;are&nbsp;var&nbsp;arguments&nbsp;which&nbsp;are&nbsp;prefixed&nbsp;by&nbsp;V.&nbsp;Member&nbsp;variables&nbsp;are&nbsp;prefixed&nbsp;by&nbsp;F,&nbsp;global&nbsp;variables&nbsp;(not&nbsp;constants)&nbsp;by&nbsp;G,&nbsp;Local&nbsp;variables&nbsp;are&nbsp;prefixed&nbsp;by&nbsp;L,&nbsp;except&nbsp;for&nbsp;general&nbsp;purpose&nbsp;integers&nbsp;(i,&nbsp;j,&nbsp;k,&nbsp;...)&nbsp;and&nbsp;general&nbsp;purpose&nbsp;strings&nbsp;(s,&nbsp;t,&nbsp;u,&nbsp;...)&nbsp;<br/>IFDEFs&nbsp;-&nbsp;IFDEFs&nbsp;are&nbsp;not&nbsp;permitted&nbsp;in&nbsp;any&nbsp;unit&nbsp;except&nbsp;for&nbsp;IdGlobals.&nbsp;This&nbsp;also&nbsp;means&nbsp;that&nbsp;all&nbsp;platform&nbsp;specific&nbsp;code&nbsp;must&nbsp;exist&nbsp;in&nbsp;IdGlobal.&nbsp;The&nbsp;only&nbsp;exception&nbsp;to&nbsp;this&nbsp;is&nbsp;the&nbsp;stack&nbsp;(IdStackWinsock,&nbsp;IdStackLinux)&nbsp;units.&nbsp;<br/>FreeAndNil&nbsp;-&nbsp;FreeAndNil&nbsp;should&nbsp;always&nbsp;be&nbsp;used,&nbsp;except&nbsp;when&nbsp;it&nbsp;cannot&nbsp;be&nbsp;used.&nbsp;Such&nbsp;cases&nbsp;where&nbsp;it&nbsp;cannot&nbsp;be&nbsp;used&nbsp;are&nbsp;in&nbsp;a&nbsp;with&nbsp;statement&nbsp;that&nbsp;uses&nbsp;a&nbsp;constructor&nbsp;as&nbsp;its&nbsp;object.&nbsp;(with&nbsp;tlist.create&nbsp;do&nbsp;try....&nbsp;finally&nbsp;Free;&nbsp;end).&nbsp;<br/>Alphabetization&nbsp;-&nbsp;Units&nbsp;in&nbsp;uses&nbsp;clauses&nbsp;are&nbsp;alphabetized&nbsp;(by&nbsp;first&nbsp;letter&nbsp;only).&nbsp;Variables,&nbsp;properties&nbsp;and&nbsp;methods&nbsp;are&nbsp;also&nbsp;alphabetized&nbsp;in&nbsp;the&nbsp;interface&nbsp;and&nbsp;var&nbsp;sections.&nbsp;Methods&nbsp;need&nbsp;not&nbsp;be&nbsp;alphabetized&nbsp;in&nbsp;the&nbsp;implementation&nbsp;section.&nbsp;<br/>TIdBaseComponent&nbsp;-&nbsp;All&nbsp;Indy&nbsp;components&nbsp;descend&nbsp;from&nbsp;TIdBaseComponent&nbsp;or&nbsp;a&nbsp;descendant&nbsp;of&nbsp;TIdBaseComponent.&nbsp;This&nbsp;class&nbsp;does&nbsp;not&nbsp;directly&nbsp;link&nbsp;to&nbsp;any&nbsp;stack&nbsp;functionality&nbsp;so&nbsp;it&nbsp;can&nbsp;be&nbsp;used&nbsp;with&nbsp;components&nbsp;that&nbsp;do&nbsp;not&nbsp;require&nbsp;stack&nbsp;functionality.&nbsp;This&nbsp;removes&nbsp;unnecessary&nbsp;functionality&nbsp;if&nbsp;the&nbsp;user&nbsp;was&nbsp;only&nbsp;using&nbsp;Indy&nbsp;components&nbsp;that&nbsp;do&nbsp;not&nbsp;use&nbsp;stack&nbsp;functionality.&nbsp;<br/>TIdComponent&nbsp;-&nbsp;All&nbsp;Indy&nbsp;components&nbsp;that&nbsp;use&nbsp;socket&nbsp;functionality&nbsp;such&nbsp;as&nbsp;clients&nbsp;and&nbsp;server&nbsp;descend&nbsp;from&nbsp;TIdComponent&nbsp;or&nbsp;a&nbsp;descendant&nbsp;of&nbsp;TIdComponent.&nbsp;This&nbsp;is&nbsp;an&nbsp;ancestor&nbsp;of&nbsp;TIdBaseComponent&nbsp;which&nbsp;links&nbsp;to&nbsp;the&nbsp;stack&nbsp;units&nbsp;and&nbsp;classes.&nbsp;<br/>EIdException&nbsp;-&nbsp;All&nbsp;exceptions&nbsp;must&nbsp;be&nbsp;of&nbsp;type&nbsp;EIdException&nbsp;or&nbsp;a&nbsp;descendant&nbsp;of&nbsp;EIdException.&nbsp;By&nbsp;descending&nbsp;from&nbsp;EIdException,&nbsp;a&nbsp;developer&nbsp;can&nbsp;determine&nbsp;if&nbsp;an&nbsp;exception&nbsp;is&nbsp;related&nbsp;to&nbsp;Indy.&nbsp;<br/>TStream&nbsp;instead&nbsp;of&nbsp;TextFile&nbsp;-&nbsp;In&nbsp;Indy,&nbsp;we&nbsp;use&nbsp;TStreams&nbsp;for&nbsp;most&nbsp;I/O&nbsp;access&nbsp;such&nbsp;as&nbsp;such&nbsp;as&nbsp;Loading&nbsp;and&nbsp;Saving&nbsp;instead&nbsp;of&nbsp;using&nbsp;things&nbsp;such&nbsp;as&nbsp;TextFile&nbsp;or&nbsp;File&nbsp;types.&nbsp;We&nbsp;do&nbsp;this&nbsp;because&nbsp;the&nbsp;TStream&nbsp;has&nbsp;more&nbsp;options&nbsp;than&nbsp;a&nbsp;typical&nbsp;text&nbsp;file&nbsp;giving&nbsp;the&nbsp;developer&nbsp;the&nbsp;utmost&nbsp;flexibility.&nbsp;By&nbsp;using&nbsp;TStreams&nbsp;as&nbsp;parameters,&nbsp;a&nbsp;user&nbsp;can&nbsp;use&nbsp;the&nbsp;function&nbsp;with&nbsp;data&nbsp;that&nbsp;is&nbsp;already&nbsp;in&nbsp;memory,&nbsp;do&nbsp;things&nbsp;such&nbsp;as&nbsp;compress&nbsp;data,&nbsp;and&nbsp;access&nbsp;files.&nbsp;We&nbsp;also&nbsp;know&nbsp;that&nbsp;there&nbsp;are&nbsp;more&nbsp;TStream&nbsp;descendant&nbsp;classes&nbsp;available&nbsp;which&nbsp;can&nbsp;add&nbsp;even&nbsp;more&nbsp;capability&nbsp;to&nbsp;programs&nbsp;such&nbsp;as&nbsp;buffered&nbsp;input&nbsp;and&nbsp;output.&nbsp;Most&nbsp;routines&nbsp;that&nbsp;access&nbsp;files&nbsp;in&nbsp;Indy&nbsp;directly&nbsp;simply&nbsp;are&nbsp;wrappers&nbsp;for&nbsp;functions&nbsp;that&nbsp;use&nbsp;TStreams.&nbsp;<br/>CLX&nbsp;/&nbsp;VCL&nbsp;Forms&nbsp;in&nbsp;property&nbsp;editors&nbsp;-&nbsp;Starting&nbsp;with&nbsp;Indy&nbsp;9.0,&nbsp;all&nbsp;property&nbsp;editors&nbsp;use&nbsp;dynamically&nbsp;created&nbsp;forms&nbsp;and&nbsp;controls&nbsp;along&nbsp;with&nbsp;IFDEF's&nbsp;for&nbsp;CLX&nbsp;on&nbsp;Kylix.&nbsp;&nbsp;This&nbsp;prevents&nbsp;us&nbsp;from&nbsp;having&nbsp;to&nbsp;make&nbsp;a&nbsp;single&nbsp;change&nbsp;in&nbsp;both&nbsp;.DFM&nbsp;and&nbsp;XFM&nbsp;files,&nbsp;prevents&nbsp;some&nbsp;maintenance&nbsp;problems&nbsp;that&nbsp;occur&nbsp;in&nbsp;the&nbsp;Delphi&nbsp;6&nbsp;IDE,&nbsp;and&nbsp;provide&nbsp;consistency&nbsp;with&nbsp;older&nbsp;Delphi&nbsp;and&nbsp;C++Builder&nbsp;versions.&nbsp;Example&nbsp;code.&nbsp;<br/>Design&nbsp;time&nbsp;property&nbsp;editors&nbsp;-&nbsp;Starting&nbsp;with&nbsp;Indy&nbsp;9.0,&nbsp;design-time&nbsp;property&nbsp;editor&nbsp;forms&nbsp;are&nbsp;separate&nbsp;from&nbsp;the&nbsp;component&nbsp;and&nbsp;design-time&nbsp;editors&nbsp;classes&nbsp;and&nbsp;are&nbsp;in&nbsp;separate&nbsp;units.&nbsp;&nbsp;This&nbsp;permits&nbsp;us&nbsp;to&nbsp;embed&nbsp;the&nbsp;property&nbsp;editor&nbsp;form&nbsp;in&nbsp;a&nbsp;test&nbsp;harness&nbsp;program&nbsp;so&nbsp;we&nbsp;can&nbsp;debug&nbsp;them&nbsp;without&nbsp;design-time&nbsp;unit&nbsp;problems.&nbsp;<br/>Replace&nbsp;AnsiXXX&nbsp;functions&nbsp;-&nbsp;Delphi&nbsp;8.0&nbsp;has&nbsp;marked&nbsp;a&nbsp;number&nbsp;of&nbsp;functions&nbsp;prefixed&nbsp;with&nbsp;Ansi&nbsp;as&nbsp;deprecated.&nbsp;Portable&nbsp;replacements&nbsp;have&nbsp;consequently&nbsp;been&nbsp;defined&nbsp;in&nbsp;IdCoreGlobal.&nbsp;Indy&nbsp;10&nbsp;code&nbsp;should&nbsp;replace&nbsp;(a)&nbsp;AnsiSameText&nbsp;with&nbsp;TextIsSame,&nbsp;(b)&nbsp;AnsiLowerCase&nbsp;with&nbsp;IndyLowerCase,&nbsp;(c)&nbsp;AnsiUpperCase&nbsp;with&nbsp;IndyUpperCase,&nbsp;(d)&nbsp;AnsiCompareStr&nbsp;with&nbsp;IndyCompareStr,&nbsp;and&nbsp;(e)&nbsp;AnsiPos&nbsp;with&nbsp;IndyPos.&nbsp;<br/>Sets&nbsp;have&nbsp;changed&nbsp;-&nbsp;Delphi&nbsp;8.0&nbsp;has&nbsp;changed&nbsp;the&nbsp;way&nbsp;sets&nbsp;are&nbsp;treated;&nbsp;so&nbsp;to&nbsp;avoid&nbsp;warnings,&nbsp;in&nbsp;Indy&nbsp;10&nbsp;replace&nbsp;constructs&nbsp;like&nbsp;"if&nbsp;not(Data&nbsp;in&nbsp;ValidChars)&nbsp;then"&nbsp;with&nbsp;"if&nbsp;not&nbsp;CharIsInSet(Data,&nbsp;i,&nbsp;ValidChars)&nbsp;then".&nbsp;<br/>Constants&nbsp;for&nbsp;Seek()&nbsp;offsets&nbsp;have&nbsp;changed&nbsp;-&nbsp;Starting&nbsp;with&nbsp;Delphi&nbsp;8.0,&nbsp;soBeginning,&nbsp;soCurrent,&nbsp;soEnd&nbsp;now&nbsp;replace&nbsp;soFromBeginning,&nbsp;soFromCurrent,&nbsp;and&nbsp;soFromEnd.&nbsp;These&nbsp;are&nbsp;used&nbsp;in&nbsp;functions&nbsp;such&nbsp;as&nbsp;Seek().&nbsp;In&nbsp;general,&nbsp;replace&nbsp;Seek()&nbsp;with&nbsp;Position,&nbsp;e.g.&nbsp;replace&nbsp;"TheStream.Seek(0,&nbsp;soFromEnd);"&nbsp;with&nbsp;"TheStream.Position&nbsp;:=&nbsp;TheStream.Size"&nbsp;(though&nbsp;there&nbsp;may&nbsp;be&nbsp;a&nbsp;small&nbsp;performance&nbsp;penalty&nbsp;that&nbsp;could&nbsp;be&nbsp;an&nbsp;issue&nbsp;in&nbsp;tightly-coded&nbsp;loops).&nbsp;If&nbsp;you&nbsp;really&nbsp;have&nbsp;to&nbsp;use&nbsp;those&nbsp;constants&nbsp;in&nbsp;Indy&nbsp;10,&nbsp;replace&nbsp;them&nbsp;with&nbsp;the&nbsp;portable&nbsp;constants&nbsp;IdFromBeginning,&nbsp;IdFromCurrent&nbsp;and&nbsp;IdFromEnd&nbsp;defined&nbsp;in&nbsp;CoreGlobal.&nbsp;</p>
页: [1]
查看完整版本: Source Code Stqndards !