Ø General Best Practices :
Try to Adopt Before Adapt through SFDC.
Consider adopting the most standard functionality of SFDC and use the most easy technology that don't require development skills (such as Formula, Workflow, Validation rule, etc.).
Consider Adapting only when any of the standard components doesn't meet the business needs; because every custom development are expensive to develop and to maintain.
More the code is complex, more it is to understand and expensive to maintain. Don't design such features that were not asked (avoid the 'feature creep').
Ø Data Model Design :
Reuse the maximum standard objects of the platform.
Be aware of the behavior for these objects, especially on Lead (that becomes an Account and a Contact) and Opportunity (stage, probability).
Need to be careful of relationship type you want to implement, sometimes lookup is enough but try to identify future needs to select the right relation (for example when a field of the parent object should be updated -by workflow- when the child changes, it's only possible with a master-detail relationship.).
Need to be careful when choosing the right field type and name as when they're deployed it's a high risk to modify them.
Always consider making a field required when he's updatable by both the UI, web service and other apex code.
Field API Name should be as short as possible. Avoid using underscores; use a capital letter for each word.
Create a default record type when creating an object. This will prevent data migration afterward when you will need to manage record types.
Ensure you have Field Level Securities, giving access to all fields for such a profile who need to be able backup all your data; i.e. Technical profile.
Custom Settings: Optimize the length of your text fields. You have limited storage. So even if you put data with a shorter length it will estimated with full length!
Visibility: Think twice before defining Org Wide Defaults for external users as "public" on an object.
When defining an existing field as required, ensure that existing records have no empty value for that field.
If "Strictly enforce picklist values" option enabled, picklist values must be aligned with your data.
Ø Integration Design :
Identify the volume of data exchanged.
Identify the direction: inbound, outbound.
Identify the type: sync / async.
Identify the integration process: batch, onego.
Inbound message using the standard Enterprise / Partner API because custom inbound or outbound are expensive to develop (except for outbound call using the workflow).
Ø Logic Design :
Match each need with available Force.com technology to build the logic (Validation Rule, Workflow, Approval Process, etc).
Manage configuration limits: number of workflows, filtered lookups, etc.
Use Apex code in a last probable consideration.
Any item configured should have brief comments in the description attribute.
Always impose naming conventions.
Ø Code - general :
Keep the right visibility.
Use "with sharing" for your class, or comments “why you would run without sharing”.
Don't code if you can configure it.
Comment your code snippet or logic.
Do not hard code IDs. If you need some invariant Ids in some circumstance you can put them in a Custom Label.
Keep your code small. This will better manage the 3Mb limit, make you think on an optimized algorithm, and most of the time make your code faster. Ex: is it necessary to define a temporary variable that will be used only once?
Always code for performance.
Ensure system.debug() is consistent to the context (Example: do not log "after insert" if you are in a "before insert" trigger).
Avoid multi-line tests. This could have negative impact on code coverage if part of the test is false.
Remove commented code to have clean classes.
Never use “try-catch” when the purpose is only to hide errors (with no code in the catch, or just a system debug). The user or admin should be notified by the error.
Do not have a different behavior when testing vs when running (spaghetti code using if(“System.Test.isRunningTest()”).
Apex Callouts - Do not hard code credentials in the code. Use named credentials as endpoints to simplify authenticated Apex callouts and manage credentials through the Setup user interface.
Do not call @future methods inside FOR loops. These methods should be bulkified and called after the loop.
Do not hardcode email addresses.
Put outside the FOR loops invariants. Ex: Contact.sObjectType.getDescribe() or Schema.SObjectType.Contact.fields.getMap();
Use only one return statement par method.
Remove unnecessary local variables, empty blocks and empty methods.
Ø SOQL in Apex :
Avoid SOQL queries statements inside loops (for, while etc.).
Leverage SOQL Capability to order results, filter, query multiple objects in 1 query through relationships.
Leverage SOQL Capability to aggregate date and do computation (Example: select SUM()).
Put the result directly in a map instead of doing this in a "for loop".
Nested for-loop with a SOQL query in the container loop can implicitly manage batch records, reducing heap consumption and increasing speed because of smaller lists. for(Contact[] cons:[Select Name from Contact limit 10000])for(Contact a: cons){business logic }
Make efficient SOQL queries. Ex: [select Name from Profile where id in (select ProfileId from User where Id=:UserInfo.getUserId())] could be rewritten as [select Name from Profile where Id=:UserInfo.getProfileId()]
Whenever it is possible, try to use 1 query for multiple records on the same object, instead of 1 query per record.
Do not query on fields that you will not use.
When querying users, don't forget to filter on the isActive field.
To filter your query, use the DeveloperName field instead of the Name field when the queried object has both (i.e.: Group, RecordType, etc.).
When doing a query on RecordType object, filter on SObject name as you can have the same recordType developerName across multiple objects.
Limit returned records. If a query is returning multiple records, you must add "limit xxx" at the end of the query to manage governor limits.
Reduce joins in queries. If you need an id of the record from a lookup, do not code select theLookup__r.id from theObject__c. Prefer this one: select theLookup__c from theObject__c
* Continue reading in Part II ( Publish soon...)
Comments