当达到Salesforce中的配置限制时,可以通过代码扩展功能。编写良好的代码是可扩展的,能够随着业务的发展而增长。
但现实情况是,在许多系统中,遗留代码非常复杂,以至于很难在无风险的情况下对其进行更新。当代码又长又难读时,更新造成的不良影响往往无法预测。究竟该如何解决这个问题呢?
01
如何编写可维护的代码?
没有开发人员会故意写出糟糕的代码,大多数代码一开始都是运行良好的。但代码通常总是在变化。随着不断的更改,生成的代码会变得东拼西凑。随着更多更改被添加到同一代码库,方法和类开始变得越来越长,最后只能导致更改变得困难。
为了编写可维护的代码,可以遵循一些基本规则:第一,保持方法和类的小型化和模块化;第二,规范类和方法的名称,使代码更具可读性。
02
保持方法和类的小规模
将任何问题分解成小块,可以更便于处理,代码也是如此。要使代码易于管理,第一件事就是保持方法和类的小规模。例如,有一个名为updateContact的method,不要让它既更新业务机会,又向联系人发送电子邮件。确保一个method只做一件事。
如果一个method只做一件事,并且它有100%的测试覆盖率,除非该method封装的业务逻辑发生变化,否则永远不需要再次更改。将它们视为创建和收藏起来的小构建块,它们将始终按预期工作。
以下是一个long method的示例:
public void handleBeforeUpdate(List<Sale__C> newSales, Map<Id,Sale__C> oldMap){
// update audit fieldsfor(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,NamefromProfilewhereId = :currentProfileId LIMIT1]; for(String pname: allowedProfileNames){if(curUserProfile.name == pname){canAudit =true; } }if(!canAudit){s.addError('Audit Box cannot be unchecked once checked'); } }elseif(s.Audit_Completed__c ==true){ s.Audit_Completed_Time__c = system.now(); s.Auditor__c = UserInfo.getUserId(); }else{// an admin is unchecking the checkboxsystem.debug('an admin is unchecking the sales audit checkbox');s.Audit_Completed_Time__c =null;s.Auditor__c =null; }}// insert - there is no oldmapelseif(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'; }elseif( s.Amount__c <10000){s.Sale_Category__c ='Medium'; }elseif(s.Amount__c <50000){s.Sale_Category__c ='Large'; }elseif(s.Amount__c >50000){s.Sale_Category__c ='Extra Large'; } } }
这种代码样式可能会变得复杂,而且会变得很快。这里有一个使代码更具可读性的例子,你能看出区别吗?
public void handleBeforeUpdate(List<Sale__C> newSales, Map<Id,Sale__C> oldMap){ addErrorForUnauthorizedAuditChanges(newSales, oldMap);
handleAuditFieldChanges(newSales, oldMap); setSaleCategory(newSales);
}
private void addErrorForUnauthorizedAuditChanges(List<Sale__C> newSales, Map<Id,Sale__C> oldMap){// error code here
}
private void handleAuditFieldChanges(List<Sale__C> newSales, Map<Id,Sale__C> oldMap){// audit field change code here} private void setSaleCategory(List<Sale__c> 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开发《高薪岗位》
网友评论