Salesforce 开发整理(五)代码开发最佳实践
在Salesforce项目实施过程中,对项目代码的维护可以说占据极大的精力,无论是因为项目的迭代,还是需求的变更,甚至是项目组成员的变动,都不可避免的需要维护之前的老代码,而事实上,几乎没有任何一个项目的整个周期中,维护人员都是最初的开发人员,所以,合适的编码规范能极大的改善代码的可读性,方便其他开发者,甚至你自己在一段时间之后来阅读,维护你的代码
首先最重要的是包括对象,字段,进程生成器,工作流,class类,触发器,函数,变量在内的所有API的命名应该是“望文生义”的,也即是说,通过你的API就能推测你的函数功能
|
类型 |
规范 |
示例 |
|
对象API |
对象名称单词用下划线连接 |
WeChat_Account__c |
|
字段API |
字段名称单词用下划线连接 |
WeChat_Account_ID__c |
|
Class |
单词连写,首字母大写 |
OrderItem |
|
Trigger |
Trigger名称=对象名+Trigger |
AccountTrigger |
|
Handler |
Trigger的实现类 = Trigger名+Handler |
AccountTriggerHandler |
|
Visualforce页面 |
页面功能描述 |
OrderTracking |
|
Vf页面控制类 |
VF页面的名+Controller |
OrderTrackingController |
|
WebService Class |
类功能描述+WS |
CalculationPriceWS |
|
Batch Class |
功能描述+Batch |
AutoUpdateAccountStatusBatch |
|
Schedule Class |
功能描述+Sch |
AutoUpdateAccountStatusSch |
|
测试类 |
Test_+Class名或Trigger名 |
Test_OrderItem |
|
常量 |
全大写,单词与单词之间下划线隔开 |
PAGE_SIZE |
|
变量 |
驼峰命名法,尽可能避免单字符 |
userName |
|
方法名 |
每个方法前必须加说明包括:参数说明、返回值说明、异常说明。如果方法名实在是太长可以对变量名缩写,但是必须添加相应的说明 |
checkStatus |
上表是一些推荐的命名规范,仅供参考.
在开发的过称中,需要尽可能的减少if,for循环的嵌套,下面是一段嵌套很深的代码节选
public void updateOppInsAccShare(List<Opportunity> list_opp,Map<Id,Opportunity> map_oldOpp){
Set<Id> set_opp = new Set<Id>();
for(Opportunity op : list_opp){
Opportunity old = map_oldOpp.get(op.Id);
if(op.OwnerId != null && op.OwnerId != old.OwnerId){
set_opp.add(op.Id);
}
}
if(!set_opp.isEmpty()){
List<Opportunity> list_op = [select Id,OwnerId,AccountId,Account.OwnerId from Opportunity where Id in: set_opp];
List<AccountShare> list_share = new List<AccountShare>();
for(Opportunity op : list_op){
if(op.AccountId != null && op.Account.OwnerId != null){
for(Opportunity p : list_opp){
if(p.Id == op.Id){
//新的所有人不等于客户所有人,则创建共享
if(p.OwnerId != op.Account.OwnerId){
System.debug('============op.AccountId===' + op.AccountId + '---p.OwnerId--' + p.OwnerId + '----op.Account.OwnerId-----' + op.Account.OwnerId);
AccountShare share = new AccountShare();
share.AccountId = op.AccountId;
share.UserOrGroupId = p.OwnerId;
share.AccountAccessLevel='Edit';
share.OpportunityAccessLevel='Edit';
share.RowCause='Manual';
list_share.add(share);
break;
}
}
}
}
}
if(!list_share.isEmpty()){
insert list_share;
}
}
}
上面的代码可以看到多层逻辑嵌套,读起来不是那么的容易理解其核心逻辑,我们可以这样改写
//业务机会所有人变更,共享该业务机会对应客户的读写权限给新所有人
public void updateOppInsAccShare(List<Opportunity> list_opp,Map<Id,Opportunity> map_oldOpp){
Set<Id> set_opp = new Set<Id>();
for(Opportunity op : list_opp){
if(op.OwnerId == map_oldOpp.get(op.Id).OwnerId){
continue;
}
set_opp.add(op.Id);
}
if(set_opp.isEmpty()){
continue;
} List<Opportunity> list_op = [select Id,OwnerId,AccountId,Account.OwnerId from Opportunity where Id in: set_opp];
List<AccountShare> list_share = new List<AccountShare>(); for(Opportunity op : list_op){
if(op.AccountId == null){
continue;
}
for(Opportunity p : list_opp){
if(p.Id != op.Id && p.OwnerId == op.Account.OwnerId){
continue;
}
System.debug('============所有人变更的业务机会对应客户id===' + op.AccountId
+ '---业务机会所有人id--' + p.OwnerId
+ '----所有人变更的业务机会对应的客户所有人-----' + op.Account.OwnerId);
AccountShare share = new AccountShare();
share.AccountId = op.AccountId;
share.UserOrGroupId = p.OwnerId;
share.AccountAccessLevel='Edit';
share.OpportunityAccessLevel='Edit';
share.RowCause='Manual';
list_share.add(share);
break;
}
}
if(!list_share.isEmpty()){
insert list_share;
}
}
在原有基础上的修改如上,实质上对于权限共享的应该还包括删除原所有人的权限以及处理因所有人变更引起的业务机会读写权限缺失问题,可以参考我的博客:Salesforce 开发整理(三)权限共享
同样需要注意的一点是,避免在循环中使用SOQL查询语句以及DML操作。
Salesforce系统限制一次请求不允许超过100个SOQL查询语句,150个DML操作。下面是一个将查询和更新语句放在for循环中的操作
trigger ContactTrigger on Contact(after insert){
for(Contact c:trigger.new){
Account acc = [select id,Name from Account where id=:c.AccountId];
acc.Name = c.FirstName;
update acc;
}
}
如果一次执行的数据超过200条,那么就超出了Salesforce的限制,所以我们修改为批量的方法
trigger ContactTrigger on Contact(after insert){
//联系人关联客户id
Set<Id> accIds = new Set<Id>();
for(Contact c : trigger.new){
if(c.AccountId != null){
accIds.add(c.AccountId);
}
}
if(accids.size() > 0){
map<Id,Account> accountMap = new map<Id,Account>([select name from Account where id IN:accids]);
for(Contact c : trigger.new){
if(!accountMap.containskey(c.AccountId)){
continue;
}
accountMap.get(c.AccountId).Name = c.LastName;
}
}
if(accountMap.size() > 0) update accountMap.values();
}
同样的,在使用SOQL语句查询时,需要那些字段就查询那些字段,以提高性能。
最后是代码的注释部分
在类和Trigger的头部添加作者、创建时间、功能描述,如果此类需要修改,那么要记录修改时间,修改人,修改内容简介
/********
*
* 作者:Ricardo
* 创建时间:2018-05-31
* 功能描述:
* function1() ...
* function2() ...
* 修改人:updatePerson
* 修改时间:updateTime
* 修改内容:description
*
*****
public class PrintQuote{
////// code....
}
方法注释应该有适当的说明,位于方法声明之前,包括:说明,参数说明、异常说明、返回值说明和特别说明等
/*******
*
* 描述:单个发送邮件
* 参数:address:邮件地址
* 参数:text:邮件正文
* 返回值:发送结果
*
****/
public String SendChatter(String address,String text){
// code....
}
针对一些关键的代码逻辑,特殊的变量都应该标记上代码注释,但是需要避免的是写太多无用的代码注释,否则跟不写注释的效果不没有太大的差异
最后是关于在开发中使用RecordTypeId,UserId,记录ID以及角色名称,用户名称等硬码,如果确定有特殊需要,可以使用自定义设置进行配置
开发时适当的遵循编码规范,可以写出简洁,易读,扩展性强,结构好的代码,既有助于自己编码习惯的养成,也能有效降低开发维护的难度,可以说是很有必要的。
以上如有错漏,欢迎指正,如有疑问,欢迎评论区留言探讨
推荐一些Salesforce编码最佳实践的网站
Force.com Apex Code Best Practices
SOQL(Salesforce Object Query Language)查询
SOOSL(Salesforce Object Search Language)查询
Salesforce 开发整理(五)代码开发最佳实践的更多相关文章
- (转载)PyTorch代码规范最佳实践和样式指南
A PyTorch Tools, best practices & Styleguide 中文版:PyTorch代码规范最佳实践和样式指南 This is not an official st ...
- Java Servlet开发的轻量级MVC框架最佳实践
在Servlet开发的工程实践中,为了减少过多的业务Servlet编写,会采用构建公共Servlet的方式,通过反射来搭建轻量级的MVC框架,从而加快应用开发. 关于Servlet开发的基础知识,请看 ...
- 前端代码标准最佳实践:CSS
前端工程师对写标准的前端代码的重视程度很高.这些最佳标准实践并不是那个权威组织发布的,而是由大量的前端工程师们在实践过程中的经验总结,目的在于提高代码的可读性,可维护性和性能.那么接着上一篇,我们再来 ...
- [libgdx游戏开发教程]使用Libgdx进行游戏开发(7)-屏幕布局的最佳实践
管理多个屏幕 我们的菜单屏有2个按钮,一个play一个option.option里就是一些开关的设置,比如音乐音效等.这些设置将会保存到Preferences中. 多屏幕切换是游戏的基本机制,Libg ...
- React 代码共享最佳实践方式
任何一个项目发展到一定复杂性的时候,必然会面临逻辑复用的问题.在React中实现逻辑复用通常有以下几种方式:Mixin.高阶组件(HOC).修饰器(decorator).Render Props.Ho ...
- 【转】Git代码提交最佳实践
GIT Commit Good Practice The following document is based on experience doing code development, bug ...
- nodejs 后台开发 和C++代码开发
https://www.npmjs.com/package/node-gyp node-gyp Node.js native addon build tool Node.js native addon ...
- 编写高性能Java代码的最佳实践
博客地址: http://blog.csdn.net/dev_csdn/article/details/79033972
- Web前端开发最佳实践(1):前端开发概述
引言 我从07年开始进入博客园,从最开始阅读别人的文章到自己开始尝试表达一些自己对技术的看法.可以说,博客园是我参与技术讨论的一个主要的平台.在这其间,随着接触技术的广度和深度的增加,也写了一些得到了 ...
- YonBuilder低代码开发实践:4行代码实现跨实体列表数据同步
提到增.删.改.查等数据维护,后端开发者们再熟悉不过了.传统的数据维护通过操作数据库的方式实现,步骤比较繁琐,需要通过Java代码实现数据库链接,然后编写SQL语句.编写实体,将想要的数据存到相应的数 ...
随机推荐
- c、c++ char*和wchar*互相转换
1. 问题描述 编写程序时通常会面对一些不同的编码格式,如Unicode和multibytes.在有关字符串的处理时尤其重要,系统编程时通常会遇到很多这样的问题,例如把wchar*的字符串转换为cha ...
- VS2019无法安装Android SDK 28的问题
在一台新电脑上安装VS2019,新建Xamarin.Android项目,反复提示要安装Android SDK Build Tools 28.0.3,在弹出的窗口里点击接受协议,却无法安装SDK. 直接 ...
- 2019 vs 如何升级到.net core 3.0 版本
写在前面 看到微软的官网都已经更新.NET CORE 3.0的版本了.发现自己的还是.NET CORE 2.1X 的版本. 那应该如果升级到.NET CORE 3.0 的版本呢? 思考 [1]首先,我 ...
- asp.net web 项目 针对aspx和ashx的 IHttpHandlerFactory 开发
ASP.NET Framework处理一个Http Request的流程: HttpRequest-->inetinfo.exe-->ASPNET_ISAPI.dll-->ASPNE ...
- Windows下分布式环境搭建以及简单测试
环境配置: 解压文件: Nginx服务器和Tomcat服务器 Tomcat服务器配置:(conf/server.xml) Nginx配置:(conf/nginx.conf) 安装memcached H ...
- javascript 对象的创建与继承模式
针对JS高级程序设计这本书,主要是理解概念,大部分要点源自书内.写这个主要是当个笔记加总结 存在的问题请大家多多指正! 6.1理解对象 创建对象的两个方法(暂时) //第一种,通过创建一个Object ...
- c# 读数据库二进制流到图片
public Bitmap PictureShow(string connectionString, string opName, string productType) { ...
- 未能加载文件或程序集“Spire.Pdf, Version=4.8.8.2020, Culture=neutral, PublicKeyToken=663f351905198cb3”或它的某一个依赖项。未能授予最小权限请求
问题:运行程序执行到代码报错:未能加载文件或程序集“Spire.Pdf, Version=4.8.8.2020, Culture=neutral, PublicKeyToken=663f3519051 ...
- idea svn 文件还原到指定版本
使用svn经常会遇见,由于自己或者其他同事的提交(或者误操作),把原本正确代码或文件覆盖掉了,现在就得需要恢复到之前指定的某个版本. 先打开指定的文件,然后右上角点击时间的按钮: 这比会出现以前的许多 ...
- 源码安装rlwrap 0.43(为了方便使用linux下的sqlplus)
为了linux下的sqlplus方便调用历史命令和退格,安装下rlwrap,最新版本是0.43,貌似作者已经不更新了 下载地址 https://fossies.org/linux/privat/rlw ...