50 lines
No EOL
12 KiB
XML
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 &lt;&gt; '') AND GenJnlLineInserted THEN MESSAGE(Text); END; Good code
|
|
LOCAL PROCEDURE ShowMessage@15(Text@1000 : Text[250]); BEGIN Text := GetMessageText; IF (Text &lt;&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 &gt; 30 Good code
|
|
Any procedure / trigger that has class coupling of &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 &gt; 25, using the CC3 version mentioned in [this article][anchor0]. Good code
|
|
Any procedure / trigger that has a cyclomatic complexity &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.&quot;Quantity (Base)&quot; ELSE CurrQuantity := CurrentPurchLine.&quot;Outstanding Qty. (Base)&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.&quot;Quantity (Base)&quot; ELSE CurrQuantity := CurrentPurchLine.&quot;Outstanding Qty. (Base)&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 &lt; 20 Good code
|
|
Any procedure / trigger that has a maintainability index &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::&quot;CA Jnl.-Post Batch&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 &lt;&gt; Type::FIELD THEN BEGIN ... ERROR(...); RecRef.CLOSE; END; Good code
|
|
IF Type &lt;&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(&quot;No.&quot;,FilterStr); IF Vendor.FINDSET THEN REPEAT &quot;User ID&quot; := USERID; &quot;Vendor No.&quot; := Vendor.&quot;No.&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 &gt; MaxPostingDate THEN MaxPostingDate := PostingDate; END Good code
|
|
PROCEDURE CheckPostingDate@23(); BEGIN IF GenJnlCheckLine.DateNotAllowed(PostingDate) THEN ERROR(DateNotAllowedErr,Caption,EntryNo); IF PostingDate &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 &ldquo;Contract Type&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(&quot;Contract Type&quot;@1000 : Option...); ... BEGIN ... WITH ServiceContractHeader DO BEGIN .</description></item></channel></rss> |