Skip to content

Instantly share code, notes, and snippets.

@jairzh
Last active June 22, 2016 03:36
Show Gist options
  • Save jairzh/33315756dfccd92f24057a6bd0b682c3 to your computer and use it in GitHub Desktop.
Save jairzh/33315756dfccd92f24057a6bd0b682c3 to your computer and use it in GitHub Desktop.

Meginfo Force.com Style Guide

Introduction

Objective

This coding standard is mandatory for Meginfo. The objective of this coding standard is to have a positive effect on

  • Avoidance of errors/bugs, especially the hard-to-find ones.
  • Maintainability, by promoting some proven design principles.
  • Maintainability, by requiring or recommending a certain unity of style.
  • Performance, by dissuading wasteful practices.
  • Rules and recommendations are given that promote reliability and maintainability.

Scope

This standard pertains to the use of Apex language in Meginfo, and also contains following languages:

  • C#
  • Java
  • JavaScript
  • XML
  • HTML

This standard does not include rules or recommendations on how to use the class libraries or APIs.

Rationale

Many of the rules and recommendations were taken from the Coding Standard of Philips Medical Systems and the book Clean Code written by Robert Martin. They are for C# language. These rules and recommendations were taken here to make an agreement inside the company to keep the code and tags conform to a same standard. This standard describes the rules and recommendations mainly for Apex. But a considerable part of a coding standard could be considered for other languages, which is also described in this standard.

Notational Conventions

Each chapter contains a set of rules and/or recommendations. An entry started with an asterisk (*) is a recommendation.

A rule should be strictly followed, and be broken only for compelling reasons where no reasonable alternative can be found. Also let the author know why the rule should be broken then.

A recommendation should be followed unless there is good reason to do otherwise. Also, there are exceptions in some rules and recommendations. The exceptions demonstrated the scenario in which the rule/recommendation is not followed.

Terms and Abbreviations

Terms Description
  |    	

General Rules

Every time a recommendation is not followed this must have a good reason.

Good reasons do not include personal preferences of style.

Do not mix coding styles within an organization

This coding standard gives you some room in choosing a certain style. Do keep the style consistent within a certain scope. This scope usually means to a salesforce organization or a project.

Naming conventions

Use US-English for naming identifiers.

Use Pascal and Camel casing for naming identifiers.

In Pascal casing the first letter of each word in an identifier is capitalized. For example, BackColor.

In Camel casing only the first letter of the second, third, etc. word in a name is capitalized; for example, backColor.

The table below provides the casing for the most common types.

IDENTIFIER CASE EXAMPLE
Class Pascal Account
Enum type Pascal Severity
Enum values Pascal Severity.Error
Field camel listItem
Final/Const field Pascal MaximumCount
Static field Pascal RedValue
Interface Pascal IDisposable
Method in Apex, Java camel toString
Method in C# Pascal ToString
Parameter camel typeName
Property Pascal BackColor
Trigger Pascal SendEmailOnNewAccount

In Apex, primitive types such as String, Decimal are all classes. So they should be Pascal casing.

Two-letter abbreviations in Pascal casing have both letters capitalized. In Camel casing this also holds true. With respect to capitalization in Pascal and Camel casing, abbreviations with more than two letters are treated as ordinary words. Please note, the abbreviation ID is often written as Id since it has become a wellknownordinary word, like UserName is written as Username.

Some examples:

CAMEL CASING PASCAL CASING
newImage NewImage
urlAddress UrlAddress
uiEntry UIEntry
id Id
pmsMR PmsMR

Do not use Hungarian notation or add any other type identification to identifiers.

Hungarian notation means to put the variable type prior to its name. For example: strName, intAge. Use of Hungarian notation is deprecated by companies like Microsoft because it introduces a programming language-dependency and complicates maintenance activities.

Do not use casing to differentiate identifiers.

Apex is case-insensitive, so do not define type called name and Name in the same context.

Exception

It is allowed in C# to have identifiers that differ only in case in distinct categories, e.g. a property BackColor that wraps the field backColor.

Use abbreviation with care.

Do not contract words in identifiers, but do use well-known abbreviations. For example, do not use GetWin instead of GetWindow, but do use a well-known abbreviation such as UI instead of UserInterface. Some examples:

RIGHT WRONG
opp oppo, op, oppt, oppty

Do not use an underscore in identifiers.

Avoid using underscore (_) in identifiers. It is deprecated in most companies.

Exception

In Apex, underscores exist in the name of every custom field and custom object as “__c” or “__r”, and in managed package. When you create custom field/object, remove the blank spaces in the name to avoid unnecessary underscores. In other words, blank spaces could appear in the label, but not in the name.

Some examples in Apex,

LABEL API NAME
Person Email PersonEmail__c
Email Notification EmailNotification

Remove blank spaces in the API name of custom field and custom object.

As described in the example of section 3.6, blank spaces are allowed in the label of custom field or custom object; and NOT allowed in its API name.

Name an identifier according to its meaning and not its type. Every identifier should be meaningful.

Avoid using language specific terminology in names of identifiers. As an example, suppose you have a number of overloaded methods to write data types into a stream. Do not use definitions like:

void write(Double doubleValue);  // wrong
void write(Long longValue);      // wrong

Instead, use:

void write(Double value);
void write(Long value);

Also, every identifier should be meaningful. Consider you have a method receives 3 parameters, do not define it like:

void calculate(Decimal a, Decimal b, Decimal c);  // wrong

Instead, please use:

void calculate(Decimal length, Decimal width, Decimal height);

Furthermore:

Integer d;						// wrong; what it stands for?
Integer daysSinceCreation;		// right; clearly enough now

theList.add(x);					// wrong; what included in the List?
if (a1[i] == a2[i])				// wrong; we can tell no different between a1 and a2

If we have the following 3 members defined in a class, who can tell the difference?

// Example with ambiguous naming
getActiveAccount();
getActiveAccounts();
getActiveAccountInfo();

Exception

Only a few variables can be meaningless. For example, the variable in a for loop:

for(Integer i = 0; i < max; i++)

Or the conventional name for a special variable:

Graphics g;		// g is a common name for Graphic instance in Java

Use a noun or a noun phrase to name a class field or property.

Classes, fields and properties should be noun phrases.

Also, if the class involved is a derived class, it is a good practice to use a compound name. For example, if you have a class named Button, deriving from this class result in a class named RoundCorneredButton.

The name for a Visualforce page can either be a noun or verb phrase.

Use a verb or a verbal phrase to name a method or trigger.

Methods and Triggers do actions, so they should be verbal phrases.

Avoid naming a trigger something like AccountTrigger. Trigger name should be meaningful, as well as verbal.

The name for a Visualforce page can either be a noun or verb phrase.

Do not prefix member fields.

Some people like to put “m” prior to the member fields in a class, like:

private String m_age;		// wrong
private String mAge;		// wrong
private String _age;		// wrong

However, this is deprecated.

In general, a method in which it is difficult to distinguish local variables from member fields is too big.

Do not add an Enum suffix to an enumeration type.

See also in section 3.3.

Do not add a Trigger suffix to a trigger.

A valid trigger name should be meaningful, and without a Trigger suffix. For example,

trigger AccountTrigger on Account(after insert)				// wrong

trigger SendEmailOnNewAccount on Account(after insert)		// right

Suffix exception classes with Exception.

Classes derived from Exception are special. They should have a suffix Exception. For example, DmlException.

Suffix controller classes with Controller

Custom controller or extensions for Visualforce pages should have a suffix Controller.

For example, EmailNotificationController

Use singular names for enumeration types.

For example, do not name an enumeration type Protocols but name it Protocol instead. Consider the following example in which only one option is allowed.

public enum Protocol
{
	Tcp,
	Udp,
	Http,
	Ftp
} 

Do not use letters that can be mistaken for digits, and vice versa.

To create obfuscated code, use very short, meaningless names formed from the letters O, o, l, I and the digits 0 and 1. Anyone reading code like

Boolean b001 = (lo == 10) ? (I1 == l1) : (lol != l01);		// wrong

Will marvel at your creativity.

Use a plural noun to name a collection.

See also in section 3.8.

Do not use something like accountList to name a variable of type List. Please use a plural noun to name a collection, for example, accounts.

Only use this. to avoid a name clash

Do not use this keyword to dereference members. The use of this is only allowed as a reference to the current class instanc or to prevent name clashing between method parameters and class fields.

Example:

void setName(String name)
{
	this.name = name;
}

Comments and embedded documentation

Each class or trigger shall contain a header block.

The header block must containing the purpose of this class/trigger.

/*
 * Controller of page EmailNotification
 * Sends email to ……
 */
public class EmailNotificationController

Use // for single line comments.

Use // instead of /* */ if the comments is a single line.

Comments shall be written in US English.

Verbs in comments shall be of singular form in third person.

Conventionally, comments are of singular form in third person. But the identifiers are not.

For example:

// Gets a string represents the name of the student.
public String getStudentName();

// Sets the name of the student
public String setStudentName(String value);

Write necessary comments not redundant or noisy

For example, everybody knows that is a default constructor:

public class Whatever
{
	// default constructor
	public Whatever()
	{
		…
	}
} 

Comment important variables

Any variable/method that is important to the class, or is difficult to understand, should be commented to help others understand the logic.

Separate class members and code sections with a blank line. Remove unnecessary blank lines.

Blank lines are treated equal as comments. Use them to separate class members. For example, each method should be separated by a blank line. If a method contains more than one operation, separate them with blank lines. Do remove unnecessary blank lines in your code.

Remove the commented lines from production.

For some reason, we need to comment some lines out when coding. Please remember to remove them before deploy them to production.

No need to comment if the code can explain itself.

Consider the following section of code:

// Check to see if the user is eligible for full benefits
if ((user.flags & HOURLY_FLAG) && (user.age > 65))

The comment is sufficient, but why not write like this:

if (user.isEligibleForFullBenefits())
// or
if (isEligibleForFullBenefits(user))

Object lifecycle

Declare and initialize variables close to where they are used.

Avoid the C style where all variables have to be defined at the beginning of a block, but rather define and initialize each variable at the point where it is needed.

If possible initialize variables at the point of declaration.

Avoid the C style where all variables have to be defined at the beginning of a block, but rather define and initialize each variable at the point where it is needed.

Use final or const keyword to define constant values.

Making it final/const ensures that memory is allocated for that item only once.

private final Integer maxCount = 100;

Exception

If the value of a constant field must be calculated at run-time, use a static field instead.

Use a public static field to define predefined object instances.

For example, consider a Color class that expresses a certain color internally as red, green, and blue components, and this class has a constructor taking 3 numeric values, then this class may expose several predefined colors like this.

public class Color
{
	public static Color Red = new Color(255, 0, 0);
	public static Color Black = new Color(0, 0, 0);
	public static Color White = new Color(255, 255, 255);
	public Color(Integer r, Integer g, Integer b)
	{
		// implementation
	}
}

Do not “shadow” a name in an outer scope.

Repeating a name that already occurs in an outer scope is seldom intended and may be surprising in maintenance, although the behavior is well-defined.

Integer foo = something;
…
if(whatever)
{
	double foo = 12.34;  // do not re-use this name   
}

Exception

Some methods have a parameter of the same name as a field. For example, a construction like this.foo = foo;

Control flow

Do not change a loop variable inside a for loop block.

Updating the loop variable within the loop body is generally considered confusing, even more so if the loop variable is modified in more than one place.

All flow control primitives (if, else, while, for, do, switch) shall be followed by a block, even if it is empty.

Please note that this also avoids possible confusion in statements of the form:

if(b1) if(b2) Foo(); else Bar();		// which ‘if’ goes with the ‘else’?

An else sub-statement of an if statement shall not be an if statement without an else part.

The intention of this rule is to define a “default action” after all the prior conditions are missed. Consider the following example.

void Foo(String answer)
{
	if (answer == “no”)
	{
		System.debug(“You answered with No”);
	}
	else if (answer == “yes”)
	{
		System.debug(“You answered with Yes”);
	}
	else
	{
		// This block is required, even though you might not care of any other
		// answers than “yes” and “no”.
	}
}

Avoid multiple or conditional return statements.

One entry, one exit is a sound principle and keeps control flow simple. However, if some cases, such as when preconditions are checked, it may be good practice to exit a method immediately when a certain precondition is not met.

Do not make explicit comparisons to true or false if we know the variable is not null.

It is usually bad style to compare a bool-type expression to true or false. However, every type in Apex is an object, includes Boolean. This means the default value of a bool-type variable is null not false.

The best practice to do this is to give a meaningful name to the variable and initialize with a default value. Then we can use the bool-type directly in conditional statements.

Example:

Boolean isFailed = false;
try
{
	insert accounts;
}
catch(Excecption ex)
{
	isFailed = true;
	ApexPage.addMessages(ex);   // error handling
}
if(isFailed)
{
	// process with the failure
}

In above example, do not compare the isFailed variable with true or false:

if(isFailed == true)	// not wrong, but not recommended either
if(isFailed != false)	// absolutely wrong 

If we have to make explicit comparison, compare it with “== true”.

BOOL test

Do not access a modified object more than once in an expression.

Take the following code as an example:

v[i] = ++i;		// wrong
v[i] = ++c;		// right

i = ++i + 1;	// wrong and useless; i += 2 would be clearer
i = i + 1;		// right

Do not use selection statements (if, switch) instead of a simple assignment or initialization.

Express your intentions directly. For example, rather than

Boolean pos;
If(val > 0)
{
	pos = true;
}
else
{
	pos = false;
}

Or (slightly better)

Boolean pos = (val > 0) ? true : false;

Or even better

 Boolean pos = (val > 0);

Object oriented programming

Declare all fields (data members) private.

This rule is accepted in most companies.

Exception

Static fields and const fields, which may have any accessibility deemed appropriate, may be an exception.

Allow properties to be set in any order.

Properties should be stateless with respect to other properties, i.e. there should not be an observable difference between first setting property A and then B and its reverse.

Use a property rather than a method when the member is a logical data member.

Use a method rather than a property when this is more appropriate.

In some cases a method is better than a property:

  • The operation is a conversion, such as Object.toString()
  • The operation is expensive enough that you want to communicate to the user that they should consider caching the result.
  • Obtaining a property value using the get accessor would have an observable side effect.
  • Calling the member twice in succession produces different results.
  • The order of execution is important. See section 7.2.3.
  • The member is static but returns a value that can be changed.
  • The member returns a copy of an internal array or other reference type.
  • Only a set accessor would be supplied. Write-only properties tend to be confusing.

Do not create a constructor that does not yield a fully initialized object.

Only create constructors that construct objects that are fully initialized. There shall be no need to set additional properties. A private constructor is exempt from this rule.

Use this and super keywords to do constructor chaining and avoid duplicate initialization.

Classes with more than one constructor are common. Pick one constructor as a main; others shall invoke the main constructor.

Also applies to the derived classes.

Consider the following example:

public virtual class Student
{
	private String name;
	private Integer age;
	private String email;
	public Student(String name)
	{
		this.name = name;
	}
	public Student(String name, Integer age)
	{
		this(name);
		this.age = age;
	}
	public Student(String name, Integer age, String email)
	{
		this(name, age);
		this.email = email;
	}
}
	
public class CollegeStudent extends Student
{
	private String major;
	public CollegeStudent(String name, Integer age, String email, String major)
	{
		super(name, age, email);
		this.major = major;
	}
}

Avoid creating overly big classes or triggers

Avoid creating triggers or classes that contains too many lines. It’s not only difficult to read, but also hard to maintain.

A class contains too many lines should be considered to separate into a couple of small classes.

A trigger contains too many lines should be considered to put some code into a class.

This standard does not set any explicit limit on the length of a source file, thus leaving the definition of “too big” to groups or projects.

Extract some small methods out of a big method.

Also, avoid creating a method that contains too many lines. A method contains too many lines should be considered to separate into a couple of small methods.

Initialize the data members lazily.

This recommendation is not part of the standard strictly. It’s about a good habit to write the code. Some developers used to write almost everything into the class constructor. For example:

// An example with bad code
public class Example
{
	public Example()
	{
		List<Contact> contacts = [select …… from Contact where …..];
		if(contacts.size() > 0)
		{
			Student = contacts[0];
		}
			// and more initializations
	}

	public Contact Student { get; set; }
	…
}

When there are more properties to initialize, the constructor becomes extremely fat and hard to read. A design principle is to postpone the initialization to where they are about to be used:

// An example with good code
public class Example
{
	public Example()
	{
		// nothing to initialize here.
	}
	public Contact Student
	{
		get
		{
			List<Contact> contacts = [select …… from Contact where …..];
			if (contacts.size() > 0)
			{
				return contacts[0];
			}
			return null;
		}
	}
	…
}

The reasons why this is better:

  1. The constructor contains less code, so that easier to read.
  2. The logic to pull student only exists inside the student property.

However, this introduced a drawback of more SOQL count. For a frequently retrieved property, we should wrap a field.

// An example with good code
public class Example
{
	private Contact theStudent;
	public Example()
	{
		// nothing to initialize here.
	}
	public Contact Student
	{
		get
		{
			if(theStudent == null)
			{
				List<Contact> contacts = [select …… from Contact where …..];
				if (contacts.size() > 0)
				{
					theStudent = contacts[0];
				}
			}
			return theStudent;
		}
	}
	…
}

Exceptions

Only throw exceptions in exceptional situations.

Do not throw exceptions in situations that are normal or expected (e.g. end-offile). Use return values or status enumerations instead. In general, try to design classes that do not throw exceptions in the normal flow of control. However, do throw exceptions that a user is not allowed to catch when a situation occurs that may indicate a design error in the way our class is used.

Only rethrow exceptions when you want to specialize the exception.

Only catch and re-throw exceptions if you want to add additional information and/or change the type of the exception into a more specific exception. In the latter case, set the

Always figure out a way to log that an exception is thrown.

Exceptions cannot be swallowed without any warning, except few situations, e.g. FormatException on data conversion and the default value is specified.

There should always be a solution to warn users that an exception has ever occurred. Solutions include but not limited to:

  • Show up to the end user as error message (ApexPages.addMessage method)
  • Email notification
  • Write to a log object
  • Alert in Javascript

Allow callers to prevent eceptions by providing a method or property that returns the object state.

For example, consider a communication layout that will throw an Invalid OperationException when an attempt is made to call Send() when no connection is available. To allow preventing such a situation, provide a property such as Connected to allow the caller to determine if a connection is available before attempting an operation.

Always check the data conversion operation.

If you use an explicit data conversion, always ensures that the source type can be converted to the destination type, so that an exception is not occurred. To verify if a class is a specific type of class, use the instanceOf keyword. This rule also applies to the conversion methods in Apex, includes but not limited to:

  • DateTime.parse
  • Integer.valueOf
  • Decimal.valueOf
  • String.valueOf

The methods above should be nested in a try/catch block.

Do remember to check null reference.

Consider the following code:

User currentUser = [select SchoolName__c from User where 
Id =:UserInfo.getUserId() limit 1];
String schoolName = currentUser.SchoolName.replace(‘_’, ‘ ‘);

A null pointer exception would possibly happen.

DO remember to correct as below:

User currentUser = [select SchoolName__c from User where 
Id =:UserInfo.getUserId() limit 1];
String schoolName = (currentUser.SchoolName == null) ? ‘’ : 
currentUser.SchoolName.replace(‘_’, ‘ ‘);

Throw informational exceptions.

When you instantiate a new exception, set its Message property to a descriptive message that will help the caller to diagnose the problem. For example, if an argument was incorrect, indicate which argument was the cause of the problem.

Also mention the name (if available) of the object involved. Also, if you design a new exception class, note that it is possible to add custom properties that can provide additional details to the caller.

Throw a more specific exception possible.

Do not throw a generic exception if a more specific one is available(related to 8.2.5).

Avoid side-effects when throwing recoverable exceptions.

For example, if during the process of adding a new item to a list, an exception is raised, then the caller may safely assume that the item has not been added, and another attempt to re-add it is possible.

Do not throw an exception from inside an exception constructor.

This doesn’t make sense.

Do not throw an exception from inside a getter property.

Throwing an exception from inside a getter property is not recommended. But in few situations, this is possible. Any exceptions from property should be careful.

Various data types

Use an enum to stongly type parameters properties and return types.

Use an enum type instead of String if the variable has only a few values. This enhances clarity and type-safety. Try to avoid casting between enumerated types and integral types.

Consider the constructor of ApexPage.Message class. When initializing, we specify an ApexPage.Severity enum instead of a string.

new Message(Severity.Fatal)	// right; Severity is a predefined collection.

new Message(“Fatal”)		// wrong

In this way, typos can be avoided, and users can have more precise control to the values.

Do not use "magic numbers".

Do not use literal values, either numeric or strings, in your code other than to define symbolic constants. Use the following pattern to define constants:

public class Whatever
{
	public static Color White = new Color(255, 255, 255);
	public static final Integer MaxNumber = 19;
	public static final String PersonAccountRecordTypeId = ‘016x00000036y’;
	public static final String FinanceProfileId = ‘0350000039x’;
}

A common mistake is to hard-code record type id or profile id. Instead, we should use predefined constant variables (as shown above).

Exception:

The value 0, 1, and null can nearly always be used safely. Very ofen the values 2 and -1 are OK as well. String or number in test methods are exempt from this rule. Literals are allowed then their meaning is clear from the context, and not subject to future changes.

avg = (a + b) / 2;				// right; clear enough
milliSeconds = seconds * 1000;	// right; clear enough

If the value of one constant depends on the value of another, do attempt to make this explicit in the code, so do not write

public final Integer MaxItem = 32;
public final Integer MaxHeight = 64;			// wrong as it is calculated from MaxItem
public final Integer MaxHeight = MaxItem * 2;	// right

Please note that an enum can often be used for certain types of symbolic constants.

Floating point values shall not be compared using either the equal or not equal operators.

Most floating-point values have no exact binary representation and have a limited precision.

Exception:

When a floating-point variable is explicitly initialized with a value such as 1.0 or 0.0, and then checked for a change at a later stage, that makes sense.

Do not cast types where a loss of precision is possible.

For example, do not cast a long to an integer, unless you can guarantee that the value of long is small enough to fit in the integer.

Page action returns Pagereference rather than void even if the page is not supposed to redirect.

Actions in the page controller or extension should always return PageReference as a return value. This rule guarantees a method looks like a page action. If you don’t want the page to be redirected, please specify return null at the end of the method.

Coding style

Put the opening brace to a new line.

Java developers used to put the opening brace in the same line of the block definition, like:

public class Whatever {
	// not recommended
}

This is not about right or wrong, but we make an agreement to put it to the next line, like:

public class Whatever 
{
	// recommended
}

This rule applies to all kinds of code blocks, includes class, method, property, if else,while, etc.

Use blank spaces properly.

Use blank spaces properly as betrayed in the following table:

EXPRESSION BLANK SPACE EXAMPLE
Arithmetical operator 1 b + c
Assignment 1 a = b + c
Comparison 1 a >= b + c
Semi-colon 0 a = b + c;
if/while 1 if (a == b + c)
for loop - for (i = 0; i < 100; i++)
Unary operator 0 !bool -i
Increment/Decrement 0 i++ --i
Ternary operator 1 (a == null) ? 0 : a
Function call 0 sendEmail(email);
Subscript 0 array[0]
Automatic property 1 String Name { get; set; }

Example:

a=b+c;			// wrong
a = b + c ;		// wrong
a = b + c;		// right

a = (a == null)?0:a;		// wrong
a = (a == null) ? 0 : a;	// right

for(i=0;i<10;i++)			// wrong
for (i = 0; i < 10; i ++)	// wrong
for (i = 0; i < 10; i++)	// right

a = -- b;		// wrong
a = --c;		// right

a = - b;	// wrong
a = -b;		// right

public String Name{get;set;}		// wrong
public String Name { get; set; }	// right

Note: unary, increment and decrement operators are an exception.

Use istest annotation rather than testmethod keyword.

For example:

@isTest
testMethod static void testThisClass()  // NOT recommended

static void testThisClass()   			// recommended

Put soql or sosl statement into one line if possible.

People have different favor to type the SOQL statement. Somebody likes to start a newline to put each field.

This standard recommends put SOQL statement into one line. For some extra long SOQL statement, you could choose to put thesub-select/from/where clause to a new line. Nevertheless, align the clauses properly.

Xml and Html Tags

Use camel casing for elements and attributes.

For camel casing, see section 3.2.

Xml and Html document should always be well-formed.

This means the format of the document should be carefully maintained includes blank space indent ending tags etc.

Example:

<apex:page showHeader="false" sidebar="false" title="abcd">
	<apex:stylesheet value="{!URLFOR($Resource.Skin2, 'css/About.css')}" />
	<apex:composition template="{!$Site.Template}">
		<apex:define name="content">
			<c:AboutNav />
			<div class="rightTextCon">
				<img class="ourStoryPic" alt="About The Juno Company, Juno Baby, Juno Jr." src="{!URLFOR($Resource.Skin2_Images, 'ourStoryPic.png')}" />
				<div class="rightText">
					<span class="shadowText">test</span><br />
					<span class="shadowText">test</span><br />
				</div>
			</div>
		</apex:define>
	</apex:composition>
</apex:page>

Write Html pages in Xhtml standard.

Though we are not writing XHTML document, its standard should also get respected. For example, following attribute are required according to XHTML standard.

ATTRIBUTE EXAMPLE
alt in img <img src="" alt="" />

Governor Limit (Apex Only)

Because Apex runs in a multitenant environment, the Apex runtime engine strictly enforces a number of limits to ensure that runaway Apex does not monopolize shared resource. Refer to document: http://wiki.developerforce.com/page/Governors_in_Apex_Code

Avoid SQL or DML inside iteration.

Avoid sending emails inside iteration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment