UNPKG

16 kBMarkdownView Raw
1# Apex Code Conventions
2
3March 17, 2018
4
5THIS DOCUMENT IS PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR
6IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
7FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
8THIS DOCUMENT COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS.
9CHANGES ARE PERIODICALLY ADDED TO THE INFORMATION HEREIN; THESE CHANGES WILL BE
10INCORPORATED IN NEW EDITIONS OF THE DOCUMENT. SUN MICROSYSTEMS, INC. MAY MAKE
11IMPROVEMENTS AND/OR CHANGES IN THE PRODUCT(S) AND/OR THE PROGRAM(S) DESCRIBED IN THIS
12DOCUMENT AT ANY TIME.
13
14## 1. Introduction
15
16### 1.1 Why
17
18Code Conventions are important because most of the cost of software is for maintenance, hardly a software will be maintained by the original author, conventiosns improve code readability and allow code written by many people to be standardized, which helps understanding of what it does.
19
20### 1.2 Acknowledgements
21
22This document reflects the Java coding standards presented in the Java Code Conventions, from Oracle Corporation, written in 1997, since Apex is so much similar to Java (syntax-wise).
23
24For questions concerning adaptation, modification, or redistribution of this document, please open an issue on this repository. Comments on this document should be submited as issues on said repository as well.
25
26## 2. File Names
27
28### 2.1 File Suffixes
29
30Apex source files should be saved with the prefix `.cls` for common classes and `.trigger.` for triggers.
31
32| File type | Suffix |
33| --------- | -------- |
34| Class | .cls |
35| Trigger | .trigger |
36
37### 2.2 Common File Names
38
39#### 2.2.1 Classes
40
41It is very usual for a developer to work with both file types specified on 2.1. For classes, they should not be the same as standard or custom objects names. For instance, we have the `Account` standard object. One shouldn't create a class called `Account.cls`. If you need a wrapper class for your objects, consider adding "Wrapper" to its name, like `AccountWrapper.cls`.
42
43#### 2.2.2 Triggers
44
45For triggers, since they are separated from the common classes, it is acceptable to give it the name of your object.
46
47## 3. File Organization
48
49An Apex source file consists of sections that should be separated by blank lines with no empty strings, and an optional comment identifying each section.
50
51Files longer than 2000 lines are cumbersome and should be avoided.
52
53### 3.1 Apex Source Files
54
55Each Apex source file contains a single class, trigger or interface.
56
57Apex source files have the following ordering:
58
591. Beginning Comments
602. Class or interface declarations
61
62#### 3.1.1 Beginning Comments
63
64All source files should begin with a comment that lists the programmer(s), the date, a copyright notice, if applicable, and also a brief description of the purpose of the program.
65
66For example:
67
68```java
69/*
70 * Author(s):
71 * - John
72 * - Mary
73 * - Fernando
74 *
75 * Copyright (C) TheCompanyName, Inc
76 *
77 * March 2018
78 *
79 * This is a callable class, that should do this and that...
80 */
81```
82
83#### 3.1.2 Class and Interface Declarations
84
85| | Part of Class/Interface declaration | Notes |
86| - | ----------------------------------- | ----- |
87| 1 | Class/interface documentation comment (/\*\*/) | - |
88| 2 | `class` or `interface` statement | - |
89| 3 | Class/interface implementation comment, if necessary | - |
90| 4 | Class (static) variables | First the `public` class variables, then the `protected` and finally the `private`. |
91| 5 | Instance variables | First `public`, then `protected` and finally `private` variables. |
92| 6 | Constructors | - |
93| 7 | Methods | - |
94
95## 4. Indentation
96
97Four spaces should be used as the unit of indentation. The exact construction of the indentation should be the space.
98
99### 4.1 Line Length
100
101Avoid lines longer than 100 characters, for consistency with IDEs and text editors. If a line exceeds 100 characters, it should be broken into two or more lines, depending on the situation (see below).
102
103### 4.2 Wrapping Lines
104
105#### 4.2.1 Principles
106
107When an expression will not fit on a single line, break it according to these general principles:
108
109- Break after a comma.
110- Break before an operator.
111- Prefer higher-level breaks to lower-level breaks.
112- Align the new line with the beginning of the expression at the same level on the previous line.
113- If the above rules lead to confusing code or to code that is squished up against the right margin, just indent 8 spaces (2 tabs) instead.
114
115#### 4.2.2 Examples
116
117##### 4.2.2.1 Method Signatures
118
119```java
120private class SomeClass {
121 public static void doSomethingReallyComplicated(Integer sumOfSomething, Decimal anotherSum,
122 String nameOfThatThing) {
123 Object someObject = SomeOtherClass.getObject();
124 // ...
125 }
126}
127```
128
129The method line above has 95 characters (counting the 4 whitespaces before `public`), and it applies the first principle of breaking after a comma. Note that by using an extra indentation on the signature on the lower line we avoid the confusion of where the scope actually starts.
130
131##### 4.2.2.2 Instance Declarations
132
133```java
134public with sharing class SomeClass {
135 // ...
136 public void someMethod () {
137 AnotherClass.AClassChildren bigVariableName
138 = new AnotherClass.AClassChildren(this.someVariable);
139 }
140}
141```
142
143The instance declaration on line 3 would use 105 characters, but with the principle of breaing before an operator it will use 65 characters on the lower line.
144
145##### 4.2.2.3 Conditionals
146
147```java
148// DON'T DO THIS
149if ((condition1 && condition2)
150 || (condition3 && ocndition4)
151 || !(condition5 && condition6)) {
152 doSomething();
153}
154```
155
156```java
157//DO THIS
158if ((condition1 && condition2)
159 || (condition3 && condition4)
160 || !(condition5 && condition6)) {
161 doSomething();
162}
163```
164
165Bad wraps like the one on the first example make easy to miss the part where the method's signature ends and when the scope actually begins. Good wraps help to make those clearer, and not so easy to miss.
166
167##### 4.2.2.4 Ternary Expressions
168
169```java
170// if it fits on the 100 character limit:
171result = (aLongExpression) ? something : anotherThing;
172
173// if it doesn't fit the 100 character limit use this:
174result = (aLongExpression) ? something
175 : anotherThing;
176
177// or this:
178result = (aLongexpression)
179 ? something
180 : anotherThing;
181
182```
183
184As exemplified above, there are three ways to format ternary expressions.
185
186### 5. Comments
187
188Apex has only one type of comment, which can be written in two ways, using `/*..*/` (multi-line) and `//` (single-line).
189
190Example:
191
192```java
193// this is a single line comment
194
195/*
196this is a multi-line comment
197*/
198```
199
200Comments should be used to give an overview of the code, and provide additional information that is not explicit in the code itself. Comments should ideally contain only information that is relevant for that specific program. Information about what a class or method does which is not explicit by its name, for example.
201
202Discussion of nontrivial or nonobvious design decisions is appropriate, but avoid duplicating information that is present in the code. It is easy to get redundant comments in the same file. In general, avoid any comments that are likely to get out of date as your application evolves.
203
204The frequency of comments sometimes can reflect poor code quality. If you often feel the need of commenting code inside methods consider rewriting the code to make it clearer and the comment unecessary. Comments should ideally be used on top of classes and methods only.
205
206Comments should not be enclosed in large boxes drawn with asterisks or other characters (ASCII Art). Comments should never include special characters such as form-feed and backspace, and they should respect the 100-charcter limit.
207
208### 6. Declarations
209
210#### 6.1 Placement
211
212Put declarations only at the beginning of blocks/scopes. Don't wait to declare variables until their first use; it can confuse the unwary programmer and hamper code portability within the scope.
213
214```java
215public void doSomething () {
216 Integer anInteger = 0; // beginning of the method scope
217
218 //... code that doesn't actually use the variable, but we have it
219 // declared already.
220
221 if (condition) {
222 Integer anotherInteger = anInteger; // beginning of the "if" scope
223 ...
224 }
225}
226```
227
228#### 6.2 Initialization
229
230Try to initialize local variables where they are declared. The only acceptable reason not to initialize a variable where it is declared is if the initial value depends on some computation.
231
232#### 6.3 Class and Interface Declarations
233
234The following formatting rules should be followed when coding Apex classes and interfaces:
235
236- A single space between a method name and the parenthesis "(" starting its parameter list
237- Open brace "{" appears at the end of the same line as the declaration statement
238- Closing brace "}" starts a line by itself indented to match its corresponding opening statement, except when it is a null statement the "}" should appear immediately after the "{".
239
240Class example:
241
242```java
243// class
244public without sharing class MyClass {
245 // method
246 public static void myMethod () {
247 ...
248 }
249
250 // null statement example
251 public class CustomException extends Exception {}
252}
253```
254
255### 7. Statements
256
257#### 7.1 Simple Statements
258
259Each line should contain at most one statement.
260
261```java
262// DON'T DO THIS
263myInt++; otherInt--;
264
265// DO THIS
266myInt++;
267otherInt++;
268```
269
270#### 7.2 Return Statements
271
272A `return` statement with a value should not use parentheses unless they make the return value more obvious in some way.
273
274```java
275return;
276
277return listOfRecords.size();
278
279return (length ? length : defaultLength);
280```
281
282#### 7.3 If, If-else, If-else-if Statements
283
284The `if-else` class of statements should have the following form:
285
286```java
287if (condition) {
288 ...
289}
290
291if (condition) {
292 statements;
293} else {
294 statements;
295}
296
297if (condition) {
298 statements;
299} else if (condition) {
300 statements;
301} else {
302 statements;
303}
304```
305
306Always avoid omitting the braces when using single-line statements inside a condition block, like this:
307
308```java
309if (condition) // PLEASE DON'T OMIT THE BRACES!
310 statements;
311```
312
313#### 7.4 "for" Statements
314
315A for statement should have one of the following forms:
316
317##### 7.4.1 With indexes
318
319If you need the index of the elements you are iterating with the `for` loop, ideally you should use the following syntax:
320
321```java
322for (Integer index = 0; index < myList.length(); index++) {
323 statements
324}
325```
326
327Avoid using more than three variables. If needed, use separate statements to compute the three variables before.
328
329##### 7.4.2 Without indexes
330
331On the Salesforce platform, most of the time this will be the syntax used. With this one you don't have easy access to the index, like in the previous example, but it is more readable:
332
333```java
334for (Object anObject : myListOfObject) {
335 statements
336}
337```
338
339#### 7.5 "while" Statements
340
341A `while` statement should have the following form:
342
343```java
344while (condition) {
345 statements;
346}
347```
348
349#### 7.6 "do-while" Statements
350
351A `do-while` statement should have the following form:
352
353```java
354do {
355 statements
356} while (condition);
357```
358
359#### 7.7 "try-catch" Statements
360
361A `try-catch` statement should have the following format:
362
363```java
364try {
365 statement;
366} catch (Exception e) {
367 statements;
368}
369```
370
371### 8. White Space
372
373Blank lines improve readability by setting off sections of code that are logically related.
374
375Two blank lines should be used in the following:
376
377- Between sections of a source file
378- Between class and interface definitions
379
380One blank line should be used in the following:
381
382- Between methods
383- Between the local variables in a method and its first statement
384- Before a block or a single line comment
385
386#### 8.2 Blank Spaces
387
388Blank spaces should be used in the following circumstances:
389
390- A keyword followed by a parenthesis should be separated by a single space.
391
392```java
393while(true){ // WRONG
394 ...
395}
396
397while (true) { // CORRECT
398 ...
399}
400```
401
402- A blank space should appear after commas in argument lists.
403
404```java
405method(Object anObjectArg,Integer anIntegerArg){ // WRONG
406 ...
407}
408
409method(Object anObjectArg, Integer anIntegerArg) { // CORRECT
410 ...
411}
412```
413
414- Expressions inside a `for` statement:
415
416```java
417for (Integer i=0;i<10;i++) { // WRONG
418 ...
419}
420
421for (Integer i = 0; i < 10; i++) { // CORRECT
422 ...
423}
424```
425
426- Object casts:
427
428```java
429ObjectA objInstance = (ObjectA)anotherType; // WRONG
430
431ObjectA objInstance = (ObjectA) anotherType; // CORRECT
432```
433
434### 9. Naming Conventions
435
436Naming conventions make programs more understandable by making them easier to read. They can also give information about what they actually do (for example, whether it is a constant or class) which is helpful in understanding the code.
437
438| Identifier Type | Rules for Naming | Examples |
439| --------------- | ---------------- | -------- |
440| Classes | Class names should be nouns, written in CamelCase. Avoid acronyms and abbreviations (unless the abbreviation is much more widely used than the long form, like "HTML" or "URL"). | `AccountWrapper`, `AttachmentHandler` |
441| Interfaces | Same as classes, but starting with a capitalized "I" | `IAccountable`, `IHandler` |
442| Methods | Methods should be verbs, in CamelCase with the first letter lowercase. | `run();`, `runFaster();`, `runInSomeParticularWay();` |
443| Variables | Variable names should be short yet meaningful, except when they are "disposable", like inside loops. | `Integer maximumSize = 10;`, `for (Integer i = 0; i < 10; i++) {` |
444| Constants | Names of variables declared as constants should be written in uppercase with words separated by underscores (`_`). | `MAX_WIDTH = 10` |
445
446### 10. Programming Practices
447
448#### 10.1 Providing Access to Instance and Class Variables
449
450Don't make any instance or class variable public without a good reason. Those often don't need to be explicitly set or gotten as this often happens as a side effect of method calls.
451
452One example of appropriate public instance variables is the case where the class is essentially a data structure, like a wrapper to an object, with no behaviour. If Apex supported `struct`, we could use that.
453
454#### 10.2 Constants
455
456Numerical constants (literals) should be coded directly only if they won't really be modified in the future. The first N numbers of Pi por example (3.14159265).
457
458#### 10.3 Variable Assignments
459
460Do not use embedded assignments in an attempt to improve run-time performance. This is the job of the compiler. Example:
461
462```java
463d = (a + b - c) / z; // NOT OK
464
465// OK
466d = a + b;
467d -= c;
468d /= z;
469```
470
471#### 10.4 Miscellaneous Practices
472
473##### 10.4.1 Parentheses
474
475It is a good idea to use parentheses liberally in expressions involving mixed operators to avoid operator precedence problems and to let the order clear for other programmers as well.
476
477```java
478if (a == b && c == d) // NO
479
480if ((a == b) && (c ==d)) // YES
481```
482
483##### 10.4.2 Returning Values
484
485Try to make the structure of the program match the intent. Example:
486
487```java
488if (condition) {
489 return true;
490} else {
491 retunr false;
492}
493```
494
495can easily be written with:
496
497```java
498return condition;
499```
500
501In a similar way,
502
503```java
504if (condition) {
505 return x;
506}
507return y;
508```
509
510should be written as:
511
512```java
513return (condition ? x : y)
514```
515
516##### 10.4.3 Expressions before "?" in the Ternary Operator
517
518If an expression containing an operator before the `?` in the ternary operator, it should be parenthesized:
519
520```java
521(x == 0) ? a : b;
522```
523
524##### 10.4.4 Special Comments
525
526If you find a code that requires your attention later, or someone else's, you should flag it accordingly.
527
528| Case | Flag |
529| ---- | ---- |
530| Something is bogus but works | `// XXX` |
531| Something is bogus and does not work | `// FIXME` |
532| Something needs to be done, but you or your team don't have the necessary attention to do it right now. | `// TODO: <small description of what to do>` |