【探索Apex开发之】 使用TriggerHandler,让你的代码逻辑更清晰
2023年09月08日
文章浏览:287

Salesforce中的触发器(Trigger)是一种特殊类型的Apex代码,它在数据库操作(如插入、更新、删除或合并等)之前或之后自动执行。触发器是用于在特定数据更改之前或之后自动执行预定义操作的强大工具。

主要特点:

·事件驱动: 触发器根据记录的数据库操作(如 Before Insert, After Update 等)被触发。

·批量处理: 触发器是批量处理的,即它们不仅仅针对单个记录,也适用于多个记录。

·与现有数据模型紧密集成: 触发器可以访问和操作与触发事件相关的记录。

·顺序与执行计划: 在一个对象上可以有多个触发器,并且可以通过代码或配置来控制执行顺序。


示例代码:

以下示例代码在插入新的“Account”记录之前执行某些操作。

trigger AccountTrigger on Account (before insert) {
    for(Account a : Trigger.new) {
        // 你的代码逻辑,例如
        if(a.AnnualRevenue == null) {
            a.AnnualRevenue = 0;
        }
    }
}

注意事项:

·递归调用: 确保避免触发器的递归调用。

·批量处理: 总是假设触发器可能会一次处理多个记录。

·测试: 所有触发器都需要进行单元测试,并满足至少75%的代码覆盖率。

·逻辑隔离: 尽量避免将复杂的业务逻辑放在触发器中。最好是将业务逻辑放在Apex类中,并从触发器里调用。

·避免DML操作: 在循环内避免DML操作,以减少执行时间和避免触发限制。

·使用触发器能实现高度定制化的业务逻辑,但也需要注意其带来的复杂性和潜在的性能问题。所以在设计和实施触发器时应谨慎。

问题点:

·由于触发器以系统管理者权限执行,因此记录共享权限将被忽略。

·由于不能以方法为单位进行测试,所以不方便创建测试类。

·逻辑不能共享。

使用TriggerHandler,让你的代码逻辑更清晰:

架构图:


1.基盘TriggerHandler类

作为所有业务逻辑TriggerHandler类的父类,用于继承实装,创建后无需更改。

public abstract class TriggerHandler {
    public void execute() {
        switch on Trigger.operationType {
            when BEFORE_INSERT  { this.beforeInsert(Trigger.new); }
            when BEFORE_UPDATE  { this.beforeUpdate(Trigger.oldMap, Trigger.newMap); }
            when BEFORE_DELETE  { this.beforeDelete(Trigger.oldMap); }
            when AFTER_INSERT   { this.afterInsert(Trigger.newMap); }
            when AFTER_UPDATE   { this.afterUpdate(Trigger.oldMap, Trigger.newMap); }
            when AFTER_DELETE   { this.afterDelete(Trigger.oldMap); }
            when AFTER_UNDELETE { this.afterUndelete(Trigger.newMap); }
        }
    }

    protected virtual void beforeInsert(List<Sobject> newList) {}
    protected virtual void beforeUpdate(Map<Id, Sobject> oldMap, Map<Id, Sobject> newMap) {}
    protected virtual void beforeDelete(Map<Id, Sobject> oldMap) {}
    protected virtual void afterInsert(Map<Id, Sobject> newMap) {}
    protected virtual void afterUpdate(Map<Id, Sobject> oldMap, Map<Id, Sobject> newMap) {}
    protected virtual void afterDelete(Map<Id, Sobject> oldMap) {}
    protected virtual void afterUndelete(Map<Id, Sobject> newMap) {}

    @TestVisible protected Boolean isFieldValueChanged(SObject oldObject, SObject newObject, SObjectField field) {
        Object oldValue = getFieldValue(oldObject, field);
        Object newValue = getFieldValue(newObject, field);
        return oldValue != newValue;
    }

    @TestVisible protected Object getFieldValue(SObject obj, SObjectField field) {
        Object fieldValue = (obj != null) && (field != null) ? obj.get(field) : null;
        return fieldValue;
    }
}

2.实装案例

启动Tirgger:

trigger EmployeeTrigger on Employee__c (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
    new EmployeeTriggerHandler().execute();
}
/**
 * 业务逻辑TriggerHandler类
 */
public with sharing class EmployeeTriggerHandler extends TriggerHandler {
    public override void afterInsert(Map<Id, SObject> newMap) {
        // 业务逻辑处理
    }
    public override void afterUpdate(Map<Id, SObject> oldMap, Map<Id, SObject> newMap){
        // 业务逻辑处理
    }
}

3.基盘TriggerHandler类的测试类

@isTest
private class TriggerHandlerTest {
    @isTest
    static void testAll() {
        TriggerHandlerDummy dummy = new TriggerHandlerDummy();
        dummy.execute();
        dummy.beforeInsert(null);
        dummy.beforeUpdate(null, null);
        dummy.beforeDelete(null);
        dummy.afterInsert(null);
        dummy.afterUpdate(null, null);
        dummy.afterDelete(null);
        dummy.afterUndelete(null);
        dummy.isFieldValueChanged(new Account(name='123'), new Account(name='456'), Account.name);
    }

    private Class TriggerHandlerDummy extends TriggerHandler{}
}

以上,欢迎补充!

关注 收藏
2023年09月08日

写得是非常好啊!!! 大赞

回复
jowell.qiao 回复 yusizhong 谢谢!
回复