Apex デザインパターン Observer

#はじめに
Apexクラスをデザインパターンで実装する。

#Observer パターン
被験者(Subjectクラス)の状態が変化したことを観測者(Observerクラス)へ通知する。

#クラス図
![Observe (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324175/b125d145-9ce9-7a62-e3b3-63f499dd9a04.png)

#利点
・Observerの具象クラス単位に処理を移譲できる

#実装
```Apex:ContactTrigger.apxt
/**
 *  取引先責任者のトリガ
 */
trigger ContactTrigger on Contact (before insert, before update, before delete, after insert, after update, after delete) {
    
    ContactTriggerHandler handler=new ContactTriggerHandler();
    
    handler.oldObjects=Trigger.old;
    handler.newObjects=Trigger.new;
    handler.oldObjectsMap=Trigger.oldMap;
    handler.newObjectsMap=Trigger.newMap;
    
    handler.addObservers();
    
    if(Trigger.isBefore && Trigger.isInsert){
        handler.notifyBeforeInsertObserver();
    }
    if(Trigger.isBefore && Trigger.isUpdate){
        handler.notifyBeforeUpdateObserver();
    }
    if(Trigger.isBefore && Trigger.isDelete){
        handler.notifyBeforeDeleteObserver();
    }
    if(Trigger.isAfter && Trigger.isInsert){
        handler.notifyAfterInsertObserver();
    }
    if(Trigger.isAfter && Trigger.isUpdate){
        handler.notifyAfterUpdateObserver();
    }
    if(Trigger.isAfter && Trigger.isDelete){
        handler.notifyAfterDeleteObserver();
    }

}
```

```Apex:BaseTriggerHandler.apxc
/**
 *  トリガハンドラの基底クラス
 */
public virtual class BaseTriggerHandler {
    
    public List<SObject> oldObjects{get; set;}
    public List<SObject> newObjects{get; set;}
    public Map<Id, SObject> oldObjectsMap{get; set;}
    public Map<Id, SObject> newObjectsMap{get; set;}
    
    private List<BaseTriggerObserver> obserbers=new List<BaseTriggerObserver>();
    
    public virtual void addObservers(BaseTriggerObserver obserber){
         this.obserbers.add(obserber);
    }

    public void notifyBeforeInsertObserver(){
        for(BaseTriggerObserver observe: this.obserbers){
            observe.beforeInsert(this.newObjects);
        }
    }
    public void notifyBeforeUpdateObserver(){
        for(BaseTriggerObserver observe: obserbers){
            observe.beforeUpdate(this.oldObjects, this.newObjects, this.oldObjectsMap, this.newObjectsMap);
        }
    }    
    public void notifyBeforeDeleteObserver(){
        for(BaseTriggerObserver observe: this.obserbers){
            observe.beforeDelete(this.newObjects, this.newObjectsMap);
        }
    }
    public void notifyAfterInsertObserver(){
        for(BaseTriggerObserver observe: this.obserbers){
            observe.afterInsert(newObjects, newObjectsMap);
        }
    }
    public void notifyAfterUpdateObserver(){
        for(BaseTriggerObserver observe: obserbers){
            observe.afterUpdate(oldObjects, newObjects, oldObjectsMap, newObjectsMap);
        }
    }    
    public void notifyAfterDeleteObserver(){
        for(BaseTriggerObserver observe: this.obserbers){
            observe.afterDelete(oldObjects, oldObjectsMap);
        }
    }

}
```

```Apex:BaseTriggerObserver.apxt
/**
 *  トリガオブザーバの基底インターフェイス
 */
public Interface BaseTriggerObserver {
    void beforeInsert(List<SObject> oldObjects);
    void beforeUpdate(List<SObject> oldObjects, List<SObject> newObjects, Map<Id, SObject> oldObjectsMap, Map<Id, SObject> newObjectsMap);
    void beforeDelete(List<SObject> oldObjects, Map<Id, SObject> oldObjectsMap);
    void afterInsert(List<SObject> newObjects, Map<Id, SObject> newObjectsMap);
    void afterUpdate(List<SObject> oldObjects, List<SObject> newObjects, Map<Id, SObject> oldObjectsMap, Map<Id, SObject> newObjectsMap);
    void afterDelete(List<SObject> oldObjects, Map<Id, SObject> oldObjectsMap);
}
```

```Apex:ContactTriggerHandler.apxt
/**
 *  取引先責任者のトリガハンドラ
 */
public class ContactTriggerHandler extends BaseTriggerHandler{
    public void addObservers(){
        super.addObservers(new ContactTriggerObserver_Test());
    }
}
```

```Apex:ContactTriggerObserver_Test.apxt
/**
 *  取引先責任者をxxxする
 */
public class ContactTriggerObserver_Test implements BaseTriggerObserver {
    
    public void beforeInsert(List<SObject> oldObjects){
        for(Contact contact: (List<Contact>)oldObjects){
            System.debug('beforeInsert='+contact);
        }    
    }
    
    public void beforeUpdate(List<SObject> oldObjects, List<SObject> newObjects, Map<Id, SObject> oldObjectsMap, Map<Id, SObject> newObjectsMap){
       	for(Contact contact: (List<Contact>)newObjects){
            System.debug('beforeUpdate='+contact);
        }  
    }
    
    public void beforeDelete(List<SObject> oldObjects, Map<Id, SObject> oldObjectsMap){}
    public void afterInsert(List<SObject> newObjects, Map<Id, SObject> newObjectsMap){}
    public void afterUpdate(List<SObject> oldObjects, List<SObject> newObjects, Map<Id, SObject> oldObjectsMap, Map<Id, SObject> newObjectsMap){}
   	public void afterDelete(List<SObject> oldObjects, Map<Id, SObject> oldObjectsMap){}

}
```

#課題
・Observerの具象クラスをどの単位で分割して実装するか