alguidelines/navpatterns/3-cal-coding-guidelines/design/index.xml
2022-02-11 17:30:04 +00:00

50 lines
No EOL
12 KiB
XML

<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Design on AL Guidelines</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/</link><description>Recent content in Design on AL Guidelines</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><atom:link href="https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/index.xml" rel="self" type="application/rss+xml"/><item><title>By Reference Parameters</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/by-reference-parameters/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/by-reference-parameters/</guid><description>Do not declare parameters by reference if their values are not intended to be changed.
Unintentional value changes might propagate. Also, it might lead people to believe that value changes are intended.
Bad code
LOCAL PROCEDURE ShowMessage@15(VAR Text@1000 : Text[250]); BEGIN Text := GetMessageText; IF (Text &amp;lt;&amp;gt; '') AND GenJnlLineInserted THEN MESSAGE(Text); END; Good code
LOCAL PROCEDURE ShowMessage@15(Text@1000 : Text[250]); BEGIN Text := GetMessageText; IF (Text &amp;lt;&amp;gt; '') AND GenJnlLineInserted THEN MESSAGE(Text); END;</description></item><item><title>Class Coupling</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/class-coupling/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/class-coupling/</guid><description>Do not write functions that have high class coupling. This makes the code hard to maintain.
Bad code
Any procedure / trigger that has class coupling of &amp;gt; 30 Good code
Any procedure / trigger that has class coupling of &amp;lt;= 30\. Class coupling is computed by summing the unique instances of the following in a code block: - every unique usage of a complex C/AL data type (table, codeunit, etc) as 1\.</description></item><item><title>Cyclomatic Complexity</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/cyclomatic-complexity/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/cyclomatic-complexity/</guid><description>Do not write functions that have high cyclomatic complexity. This makes the code hard to maintain.
Bad code
Any procedure / trigger that has a cyclomatic complexity &amp;gt; 25, using the CC3 version mentioned in [this article][anchor0]. Good code
Any procedure / trigger that has a cyclomatic complexity &amp;lt;= 25, using the CC3 version. The CC3 version is computed by summing the following in a code block: - each IF statement as 1\.</description></item><item><title>Encapsulate Local Functionality</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/encapsulate-local-functionality/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/encapsulate-local-functionality/</guid><description>Any function used local must be defined as local.</description></item><item><title>FINDSET FINDFIRST FINDLAST</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/findset-findfirst-findlast/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/findset-findfirst-findlast/</guid><description>FINDSET, FIND('+') or FIND('-') should only be used when NEXT is used and vice versa.
Bad code
IF Cust.FIND('-') THEN ERROR(CustIsBlockErr) Good code
IF Cust.FINDFIRST THEN ERROR(CustIsBlockErr) Bad code
IF Cust.FINDFIRST THEN REPEAT ... UNTIL Cust.NEXT = 0; Good code
IF Cust.FINDSET THEN REPEAT ... UNTIL Cust.NEXT = 0;</description></item><item><title>Initialized Variables</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/initialized-variables/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/initialized-variables/</guid><description>Variables should always be set to a specific value, before they are used.
Bad code
PROCEDURE SetPurchLine@22(VAR CurrentPurchLine@1000 : Record 39); VAR Pegging@1001 : Boolean; BEGIN IF Pegging THEN CurrQuantity := CurrentPurchLine.&amp;quot;Quantity (Base)&amp;quot; ELSE CurrQuantity := CurrentPurchLine.&amp;quot;Outstanding Qty. (Base)&amp;quot;; END; Good code
PROCEDURE SetPurchLine@22(VAR CurrentPurchLine@1000 : Record 39); VAR Pegging@1001 : Boolean; BEGIN Pegging := IsPegging(CurrentPurchLine); IF Pegging THEN CurrQuantity := CurrentPurchLine.&amp;quot;Quantity (Base)&amp;quot; ELSE CurrQuantity := CurrentPurchLine.&amp;quot;Outstanding Qty. (Base)&amp;quot;; END; Bad code</description></item><item><title>Maintainability Index</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/maintainability-index/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/maintainability-index/</guid><description>Maintainability Index: Do not write functions that have a very low maintainability index. This makes the code hard to maintain.
Bad code
Any procedure / trigger that has a maintainability index &amp;lt; 20 Good code
Any procedure / trigger that has a maintainability index &amp;gt;= 20\. The Maintainability Index is computed as a function: - Lines Of Code (inverse proportional) - the Halstead Volume - Cyclomatic Complexity (inverse proportional). More info</description></item><item><title>Parameter Placeholders</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/parameter-placeholders/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/parameter-placeholders/</guid><description>The number of parameters passed to a string must match the placeholders.
Bad code
CannotDeleteLineErr@1005 : TextConst 'ENU=You cannot delete this line because one or more rating values exists.'; ... ERROR(CannotDeleteLineErr,TABLECAPTION); Good code
CannotDeleteLineErr@1005 : TextConst 'ENU=You cannot delete this line because one or more rating values exists.'; ... ERROR(CannotDeleteLineErr); Bad code
CannotUseThisFieldErr@1020 : TextConst 'ENU=You cannot use this field for %2 fields.'; ... ERROR(CannotUseThisFieldErr,0,Field.Class); Good code</description></item><item><title>Static Object Invocation</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/static-object-invocation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/static-object-invocation/</guid><description>Call objects statically whenever possible. It reduces extra noise and removes extra variables. Downside: changing the name of the object which is called statically will need a code update.
Bad code
LOCAL PROCEDURE Code@1(); VAR CAJnlPostBatch@1001 : Codeunit 1103; BEGIN CAJnlPostBatch.Run(CostJnlLine); END; Good code
LOCAL PROCEDURE Code@1(); BEGIN CODEUNIT.RUN(CODEUNIT::&amp;quot;CA Jnl.-Post Batch&amp;quot;,CostJnlLine); END;</description></item><item><title>Unreachable Code</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/unreachable-code/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/unreachable-code/</guid><description>Do not write code that will never be hit.
It affects code readability and can lead to wrong assumptions.
Bad code
IF Type &amp;lt;&amp;gt; Type::FIELD THEN BEGIN ... ERROR(...); RecRef.CLOSE; END; Good code
IF Type &amp;lt;&amp;gt; Type::FIELD THEN BEGIN ... RecRef.CLOSE; ERROR(...); END;</description></item><item><title>Unused Initialized Variables</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/unused-initialized-variables/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/unused-initialized-variables/</guid><description>The value assigned to a variable must be used. Else the variable is not necessary.
Bad code
PROCEDURE AddEntities@1(FilterStr@1000 : Text[250]); VAR Vendor@1001 : Record 23; Count@1002 : Integer; BEGIN Count := 0; Vendor.SETFILTER(&amp;quot;No.&amp;quot;,FilterStr); IF Vendor.FINDSET THEN REPEAT &amp;quot;User ID&amp;quot; := USERID; &amp;quot;Vendor No.&amp;quot; := Vendor.&amp;quot;No.&amp;quot;; IF INSERT THEN Count += 1; UNTIL Vendor.NEXT = 0; END; Good code
PROCEDURE AddEntities@1(FilterStr@1000 : Text[250]); VAR Vendor@1001 : Record 23; BEGIN Vendor.</description></item><item><title>Unused Variables</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/unused-variables/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/unused-variables/</guid><description>Do not declare variables that are unused.
Unused variables affect readability.
Bad code
PROCEDURE CheckPostingDate@23(CaptionEntryNo@1005 : Text[50]); BEGIN IF GenJnlCheckLine.DateNotAllowed(PostingDate) THEN ERROR(DateNotAllowedErr,Caption,EntryNo) IF PostingDate &amp;gt; MaxPostingDate THEN MaxPostingDate := PostingDate; END Good code
PROCEDURE CheckPostingDate@23(); BEGIN IF GenJnlCheckLine.DateNotAllowed(PostingDate) THEN ERROR(DateNotAllowedErr,Caption,EntryNo); IF PostingDate &amp;gt; MaxPostingDate THEN MaxPostingDate := PostingDate; END; Bad code
PROCEDURE IsReturned@14(EntryNo@1002 : Integer) : Decimal; VAR ItemEntry@1000 : Record 32; Quantity@1003 : Integer; BEGIN EXIT(-OutboundApplied(EntryNo,TRUE) - InboundApplied(EntryNo,TRUE)); END; Good code</description></item><item><title>Variable Capacity Mismatch</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/variable-capacity-mismatch/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/variable-capacity-mismatch/</guid><description>Do not assign a value to a variable whose capacity is smaller.
It will throw an error at runtime.
Bad code
FileName@1010 : Text[250]; ... UploadedFileName@1016 : Text[1024]; ... FileName := UploadedFileName; Good code
FileName@1010 : Text[1024]; ... UploadedFileName@1016 : Text[1024]; ... FileName := UploadedFileName; Bad code
FileName@1010 : Text[250]; ... UploadedFileName@1016 : Text[1024]; ... FileName := UploadedFileName; Good code
FileName@1010 : Text[250]; ... UploadedFileName@1016 : Text[1024]; .</description></item><item><title>WITH Scope Name Collision</title><link>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/with-scope-name-collision/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alguidelines.dev/navpatterns/3-cal-coding-guidelines/design/with-scope-name-collision/</guid><description>Do not use the WITH scope when it has a variable whose name is the same as a local variable. This can lead to wrong code assumptions.
Given that &amp;ldquo;Contract Type&amp;rdquo; is a field on table ServiceContractHeader, then in the following example there is a parameter name clash with the field name. Which one will be used?
Bad code
PROCEDURE InsertData@1(&amp;quot;Contract Type&amp;quot;@1000 : Option...); ... BEGIN ... WITH ServiceContractHeader DO BEGIN .</description></item></channel></rss>