1 | # Apex Code Conventions
|
2 |
|
3 | March 17, 2018
|
4 |
|
5 | THIS DOCUMENT IS PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR
|
6 | IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
7 | FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
8 | THIS DOCUMENT COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS.
|
9 | CHANGES ARE PERIODICALLY ADDED TO THE INFORMATION HEREIN; THESE CHANGES WILL BE
|
10 | INCORPORATED IN NEW EDITIONS OF THE DOCUMENT. SUN MICROSYSTEMS, INC. MAY MAKE
|
11 | IMPROVEMENTS AND/OR CHANGES IN THE PRODUCT(S) AND/OR THE PROGRAM(S) DESCRIBED IN THIS
|
12 | DOCUMENT AT ANY TIME.
|
13 |
|
14 | ## 1. Introduction
|
15 |
|
16 | ### 1.1 Why
|
17 |
|
18 | Code 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 |
|
22 | This 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 |
|
24 | For 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 |
|
30 | Apex 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 |
|
41 | It 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 |
|
45 | For 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 |
|
49 | An 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 |
|
51 | Files longer than 2000 lines are cumbersome and should be avoided.
|
52 |
|
53 | ### 3.1 Apex Source Files
|
54 |
|
55 | Each Apex source file contains a single class, trigger or interface.
|
56 |
|
57 | Apex source files have the following ordering:
|
58 |
|
59 | 1. Beginning Comments
|
60 | 2. Class or interface declarations
|
61 |
|
62 | #### 3.1.1 Beginning Comments
|
63 |
|
64 | All 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 |
|
66 | For 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 |
|
97 | Four 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 |
|
101 | Avoid 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 |
|
107 | When 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
|
120 | private class SomeClass {
|
121 | public static void doSomethingReallyComplicated(Integer sumOfSomething, Decimal anotherSum,
|
122 | String nameOfThatThing) {
|
123 | Object someObject = SomeOtherClass.getObject();
|
124 | // ...
|
125 | }
|
126 | }
|
127 | ```
|
128 |
|
129 | The 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
|
134 | public with sharing class SomeClass {
|
135 | // ...
|
136 | public void someMethod () {
|
137 | AnotherClass.AClassChildren bigVariableName
|
138 | = new AnotherClass.AClassChildren(this.someVariable);
|
139 | }
|
140 | }
|
141 | ```
|
142 |
|
143 | The 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
|
149 | if ((condition1 && condition2)
|
150 | || (condition3 && ocndition4)
|
151 | || !(condition5 && condition6)) {
|
152 | doSomething();
|
153 | }
|
154 | ```
|
155 |
|
156 | ```java
|
157 | //DO THIS
|
158 | if ((condition1 && condition2)
|
159 | || (condition3 && condition4)
|
160 | || !(condition5 && condition6)) {
|
161 | doSomething();
|
162 | }
|
163 | ```
|
164 |
|
165 | Bad 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:
|
171 | result = (aLongExpression) ? something : anotherThing;
|
172 |
|
173 | // if it doesn't fit the 100 character limit use this:
|
174 | result = (aLongExpression) ? something
|
175 | : anotherThing;
|
176 |
|
177 | // or this:
|
178 | result = (aLongexpression)
|
179 | ? something
|
180 | : anotherThing;
|
181 |
|
182 | ```
|
183 |
|
184 | As exemplified above, there are three ways to format ternary expressions.
|
185 |
|
186 | ### 5. Comments
|
187 |
|
188 | Apex has only one type of comment, which can be written in two ways, using `/*..*/` (multi-line) and `//` (single-line).
|
189 |
|
190 | Example:
|
191 |
|
192 | ```java
|
193 | // this is a single line comment
|
194 |
|
195 | /*
|
196 | this is a multi-line comment
|
197 | */
|
198 | ```
|
199 |
|
200 | Comments 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 |
|
202 | Discussion 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 |
|
204 | The 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 |
|
206 | Comments 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 |
|
212 | Put 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
|
215 | public 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 |
|
230 | Try 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 |
|
234 | The 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 |
|
240 | Class example:
|
241 |
|
242 | ```java
|
243 | // class
|
244 | public 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 |
|
259 | Each line should contain at most one statement.
|
260 |
|
261 | ```java
|
262 | // DON'T DO THIS
|
263 | myInt++; otherInt--;
|
264 |
|
265 | // DO THIS
|
266 | myInt++;
|
267 | otherInt++;
|
268 | ```
|
269 |
|
270 | #### 7.2 Return Statements
|
271 |
|
272 | A `return` statement with a value should not use parentheses unless they make the return value more obvious in some way.
|
273 |
|
274 | ```java
|
275 | return;
|
276 |
|
277 | return listOfRecords.size();
|
278 |
|
279 | return (length ? length : defaultLength);
|
280 | ```
|
281 |
|
282 | #### 7.3 If, If-else, If-else-if Statements
|
283 |
|
284 | The `if-else` class of statements should have the following form:
|
285 |
|
286 | ```java
|
287 | if (condition) {
|
288 | ...
|
289 | }
|
290 |
|
291 | if (condition) {
|
292 | statements;
|
293 | } else {
|
294 | statements;
|
295 | }
|
296 |
|
297 | if (condition) {
|
298 | statements;
|
299 | } else if (condition) {
|
300 | statements;
|
301 | } else {
|
302 | statements;
|
303 | }
|
304 | ```
|
305 |
|
306 | Always avoid omitting the braces when using single-line statements inside a condition block, like this:
|
307 |
|
308 | ```java
|
309 | if (condition) // PLEASE DON'T OMIT THE BRACES!
|
310 | statements;
|
311 | ```
|
312 |
|
313 | #### 7.4 "for" Statements
|
314 |
|
315 | A for statement should have one of the following forms:
|
316 |
|
317 | ##### 7.4.1 With indexes
|
318 |
|
319 | If you need the index of the elements you are iterating with the `for` loop, ideally you should use the following syntax:
|
320 |
|
321 | ```java
|
322 | for (Integer index = 0; index < myList.length(); index++) {
|
323 | statements
|
324 | }
|
325 | ```
|
326 |
|
327 | Avoid using more than three variables. If needed, use separate statements to compute the three variables before.
|
328 |
|
329 | ##### 7.4.2 Without indexes
|
330 |
|
331 | On 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
|
334 | for (Object anObject : myListOfObject) {
|
335 | statements
|
336 | }
|
337 | ```
|
338 |
|
339 | #### 7.5 "while" Statements
|
340 |
|
341 | A `while` statement should have the following form:
|
342 |
|
343 | ```java
|
344 | while (condition) {
|
345 | statements;
|
346 | }
|
347 | ```
|
348 |
|
349 | #### 7.6 "do-while" Statements
|
350 |
|
351 | A `do-while` statement should have the following form:
|
352 |
|
353 | ```java
|
354 | do {
|
355 | statements
|
356 | } while (condition);
|
357 | ```
|
358 |
|
359 | #### 7.7 "try-catch" Statements
|
360 |
|
361 | A `try-catch` statement should have the following format:
|
362 |
|
363 | ```java
|
364 | try {
|
365 | statement;
|
366 | } catch (Exception e) {
|
367 | statements;
|
368 | }
|
369 | ```
|
370 |
|
371 | ### 8. White Space
|
372 |
|
373 | Blank lines improve readability by setting off sections of code that are logically related.
|
374 |
|
375 | Two blank lines should be used in the following:
|
376 |
|
377 | - Between sections of a source file
|
378 | - Between class and interface definitions
|
379 |
|
380 | One 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 |
|
388 | Blank 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
|
393 | while(true){ // WRONG
|
394 | ...
|
395 | }
|
396 |
|
397 | while (true) { // CORRECT
|
398 | ...
|
399 | }
|
400 | ```
|
401 |
|
402 | - A blank space should appear after commas in argument lists.
|
403 |
|
404 | ```java
|
405 | method(Object anObjectArg,Integer anIntegerArg){ // WRONG
|
406 | ...
|
407 | }
|
408 |
|
409 | method(Object anObjectArg, Integer anIntegerArg) { // CORRECT
|
410 | ...
|
411 | }
|
412 | ```
|
413 |
|
414 | - Expressions inside a `for` statement:
|
415 |
|
416 | ```java
|
417 | for (Integer i=0;i<10;i++) { // WRONG
|
418 | ...
|
419 | }
|
420 |
|
421 | for (Integer i = 0; i < 10; i++) { // CORRECT
|
422 | ...
|
423 | }
|
424 | ```
|
425 |
|
426 | - Object casts:
|
427 |
|
428 | ```java
|
429 | ObjectA objInstance = (ObjectA)anotherType; // WRONG
|
430 |
|
431 | ObjectA objInstance = (ObjectA) anotherType; // CORRECT
|
432 | ```
|
433 |
|
434 | ### 9. Naming Conventions
|
435 |
|
436 | Naming 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 |
|
450 | Don'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 |
|
452 | One 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 |
|
456 | Numerical 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 |
|
460 | Do not use embedded assignments in an attempt to improve run-time performance. This is the job of the compiler. Example:
|
461 |
|
462 | ```java
|
463 | d = (a + b - c) / z; // NOT OK
|
464 |
|
465 | // OK
|
466 | d = a + b;
|
467 | d -= c;
|
468 | d /= z;
|
469 | ```
|
470 |
|
471 | #### 10.4 Miscellaneous Practices
|
472 |
|
473 | ##### 10.4.1 Parentheses
|
474 |
|
475 | It 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
|
478 | if (a == b && c == d) // NO
|
479 |
|
480 | if ((a == b) && (c ==d)) // YES
|
481 | ```
|
482 |
|
483 | ##### 10.4.2 Returning Values
|
484 |
|
485 | Try to make the structure of the program match the intent. Example:
|
486 |
|
487 | ```java
|
488 | if (condition) {
|
489 | return true;
|
490 | } else {
|
491 | retunr false;
|
492 | }
|
493 | ```
|
494 |
|
495 | can easily be written with:
|
496 |
|
497 | ```java
|
498 | return condition;
|
499 | ```
|
500 |
|
501 | In a similar way,
|
502 |
|
503 | ```java
|
504 | if (condition) {
|
505 | return x;
|
506 | }
|
507 | return y;
|
508 | ```
|
509 |
|
510 | should be written as:
|
511 |
|
512 | ```java
|
513 | return (condition ? x : y)
|
514 | ```
|
515 |
|
516 | ##### 10.4.3 Expressions before "?" in the Ternary Operator
|
517 |
|
518 | If 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 |
|
526 | If 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>` |
|