当达到Salesforce中的配置限制时,可以通过代码扩展功能。编写良好的代码是可扩展的,能够随着业务的发展而增长。
但现实情况是,在许多系统中,遗留代码非常复杂,以至于很难在无风险的情况下对其进行更新。当代码又长又难读时,更新造成的不良影响往往无法预测。究竟该如何解决这个问题呢?
01
如何编写可维护的代码?
没有开发人员会故意写出糟糕的代码,大多数代码一开始都是运行良好的。但代码通常总是在变化。随着不断的更改,生成的代码会变得东拼西凑。随着更多更改被添加到同一代码库,方法和类开始变得越来越长,最后只能导致更改变得困难。
为了编写可维护的代码,可以遵循一些基本规则:第一,保持方法和类的小型化和模块化;第二,规范类和方法的名称,使代码更具可读性。
02
保持方法和类的小规模
将任何问题分解成小块,可以更便于处理,代码也是如此。要使代码易于管理,第一件事就是保持方法和类的小规模。例如,有一个名为updateContact的method,不要让它既更新业务机会,又向联系人发送电子邮件。确保一个method只做一件事。
如果一个method只做一件事,并且它有100%的测试覆盖率,除非该method封装的业务逻辑发生变化,否则永远不需要再次更改。将它们视为创建和收藏起来的小构建块,它们将始终按预期工作。
以下是一个long method的示例:
public void handleBeforeUpdate(List newSales, Map oldMap){
// update audit fields
for(Sale__c s : newSales) {
if(oldMap != null){ // this is an update
Sale__c oldRec = oldMap.get(s.id);
if( oldRec.Audit_Completed__c == true && s.Audit_Completed__c == false) {
boolean canAudit = false;
Id currentProfileId= userinfo.getProfileId();
Profile curUserProfile = [Select Id,Name from Profile where Id = :currentProfileId LIMIT 1];
for(String pname: allowedProfileNames){
if(curUserProfile.name == pname){
canAudit = true;
}
}
if(!canAudit){
s.addError('Audit Box cannot be unchecked once checked');
}
}
else if(s.Audit_Completed__c == true){
s.Audit_Completed_Time__c = system.now();
s.Auditor__c = UserInfo.getUserId();
}
else { // an admin is unchecking the checkbox
system.debug('an admin is unchecking the sales audit checkbox');
s.Audit_Completed_Time__c = null;
s.Auditor__c = null;
}
} // insert - there is no oldmap
else if(s.Audit_Completed__c == true){
s.Audit_Completed_Time__c = system.now();
s.Auditor__c = UserInfo.getUserId();
}
}
for(Sale__c s : newSales) {
String category;
if(s.Amount__c < 1000){
s.Sale_Category__c = 'Small';
}
else if( s.Amount__c < 10000){
s.Sale_Category__c = 'Medium';
}
else if(s.Amount__c < 50000){
s.Sale_Category__c = 'Large';
}
else if(s.Amount__c > 50000){
s.Sale_Category__c = 'Extra Large';
}
}
}){
这种代码样式可能会变得复杂,而且会变得很快。这里有一个使代码更具可读性的例子,你能看出区别吗?
public void handleBeforeUpdate(List newSales, Map oldMap){
addErrorForUnauthorizedAuditChanges(newSales, oldMap);
handleAuditFieldChanges(newSales, oldMap);
setSaleCategory(newSales);
}
private void addErrorForUnauthorizedAuditChanges(List newSales, Map oldMap){
// error code here
}
private void handleAuditFieldChanges(List newSales, Map oldMap){
// audit field change code here
}
private void setSaleCategory(List newSales){
// sale category code here
}
03
保持类的内部工作私有
许多代码都公开了所有method,这使部分工作变得非常轻松。尤其是在为代码覆盖率编写测试类时,只需从测试类中调用所有method即可获取代码。但这是正确的做法吗?
试想一下,有一个验证地址的类。它调用其他三个具有基本逻辑的method来确保街道、城市和邮政编码的有效性。这些method是公开的。这个类被组织中需要验证邮政编码的其他开发人员注意到,因此他们决定在代码中使用该method。
public class AddressValidator{
public Boolean isAddressValid(String address){
return (isStreetValid() &&
isCityValid() &&
isPostalCodeValid)
}
public Boolean isStreetValid(){
// validation code
}
public Boolean isCityValid(){
// validation code
}
public Boolean isPostalCodeValid(){
// validation code
}
}
后来,该企业决定购买一项服务,以更准确地验证地址。因此,这三个method可以被删除,并替换为对服务的调用。但是,无法删除isPostalCodeValid()方法,因为它正在其他地方使用。如果这些method一开始就是私有的,那么就不会被公开,也不会导致代码依赖。
public class AddressValidator{
public Boolean isAddressValid(String address){
return PostalAddressValidationService.validateAddress();
}
}
因此,只公开需要从编写的类之外看到的内容。将所有内容公开会产生意想不到的依赖性。任何内部工作都应该是私有的,这样就可以根据需要进行更改,而不会破坏类之外的任何东西。
04
规范method的命名
如果规范了method的命名,代码就不需要过多的注释。当你过段时间再阅读代码时,代码也会变得更容易阅读和理解。例如:
总之,为了保持代码的可维护性,开发人员应该努力保持小规模的方法和类。这意味着method应该一次只做一件事,method名称应该反映method中实际发生的内容。使用public修饰符仅显示必要的内容,并将其他所有设置私有。
作者:自由侠部落
免费领取:Salesforce学习资料、高薪岗位、考证攻略,$140考试优惠券
本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接
如果文章的内容对你有帮助,欢迎点赞~