拡張コントローラーの二刀流

拡張コントローラーは複数設置できる!?

VisualForceページで拡張コントローラーを使用する場合、apex:pageタグのextensionsで拡張コントローラを指定できます。
実は、拡張コントローラーはカンマ区切りで指定することができるんです。

メソッド名が重複してたらどうなるか?

実際に簡単なVisualForceページと拡張コントローラーを作成して検証しました。

VisualForceページ
AccountMultiExtention.page

<apex:page standardController="Account" extensions="AccountExtCtrl1,AccountExtCtrl2">
    <apex:form >
        <apex:inputField value="{!Account.Name}"/>    
        <apex:commandButton action="{!save}" value="Save" />
    </apex:form> 
</apex:page>

拡張コントローラー1
AccountExtCtrl1.cls

public class AccountExtCtrl1 {

    public AccountExtCtrl1(ApexPages.StandardController controller) {

    }

    public PageReference save(){
        System.debug('AccountExtCtrl1');
        return null;
    }
}

拡張コントローラー2(単純に1が2になっただけです)
AccountExtCtrl2.cls

public class AccountExtCtrl2 {

    public AccountExtCtrl2(ApexPages.StandardController controller) {

    }

    public PageReference save(){
        System.debug('AccountExtCtrl2');
        return null;
    }
}

ここで、ポイントはapex:commandButtonのところにあるsaveメソッド。
standardControllerにもsaveメソッドが実装されている上、2つの拡張コントローラーにもsaveメソッドが存在しています。

では問題です。
ボタンを押した時に、どのメソッドが実行されるでしょうか?
選択肢は以下の5つ。

  1. standardControllerのsave(レコードの保存)
  2. AccountExtCtrl1のsaveメソッド
  3. AccountExtCtrl2のsaveメソッド
  4. AccountExtCtrl1とAccountExtCtrl2の両方のsaveメソッド
  5. standardController、AccountExtCtrl1、AccountExtCtrl2すべてのsaveメソッド

実際に動作を確認

では、実際に「Save」ボタンを押してみましょう。
デバッグログがこのように出力されます。

AccountExtCtrl1

レコードは保存されておらず、AccountExtCtrl1のsaveメソッドのみが実行されていました
つまり、2が正解です

まとめ

検証結果をまとめるとこうなります。

  • 標準コントローラーと拡張コントローラーでは、拡張コントローラーのメソッドが優先される
  • 拡張コントローラーが複数指定された場合は、最初に指定した拡張コントローラのメソッドが優先される
  • 実行されるのは1つのメソッドのみで、他の同名のメソッドは実行されない

まあ、普段の業務でこういう実装することはないんだけどね。。。
あくまでテスト対策ということで押さえておいてください。

コメント