42
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Apex Trigger Lightweight Framework

Last updated at Posted at 2019-03-06

#1.一般的な実装例


trigger EmployeeTrigger on Employee__c (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
    if (Trigger.isInsert) {
        if (Trigger.isBefore) {
            // Before Insert 処理
        } else if (Trigger.isAfter) {
            // After Insert 処理
    }
    ...(
}

#2.問題分析
●トリガはシステム権限で実行するため、レコード共有権限は無視される
●メソッド単位でテストできないため、テストクラスの作成には不便利
●ロジックは共有できない

#3.Trigger構成図(Lightweight Framework)
image.png

#4.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;
    }
}

#5.実装例


trigger EmployeeTrigger on Employee__c (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
    new EmployeeTriggerHandler().execute();
}

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){
        // 業務処理
    }
}

#6.Triggerの実行制御について
image.png

#7.テストクラス


/*******************************************************************************
* XXXXXXシステム
* @Auther Terrasky 徐
* 概要:トリガーハンドラーの基底クラス(テストクラス)
******************************************************************************/
@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{}
}
42
12
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?