複数のページで使用できる共通部品はVisualforce Componentとして開発することができます。コンポーネント内で完結するような処理の場合は、難しく考えなくても問題ありませんが、コンポーネント内の処理結果をページ側に反映するような場合は少し大変だったりします。
例えばJavaScriptを使ってページ側の項目に値をセットしたり、sObject型の変数を渡してコンポーネント内でputするということが必要になったりします。
そんなVisualforce Componentですが、type="ApexPages.Action"を利用することでページ側のApexクラスが持っている『doSearch』のようなactionメソッドを受け取ることができます。
Visualforce Component側
Visualforce Page側
これにより、コンポーネント側ではApexクラスの処理を実装することなくページ側の検索処理や保存処理を呼び出して実行することができます。この方法のいいところは処理の実行をページ側のApexクラスで行うので処理結果を反映させるという手間を回避できることです。
例えば検索条件を入力するためのコンポーネントで、検索条件は同じで表示項目は異なるというケースでも各ページ毎にApexPages.Actionで渡すメソッドを変更することで柔軟に対応できます。
実装例
2つの検索ページで使える検索条件入力コンポーネントのサンプルを用意しました。
Visualforce Component
Visualforce Page1
Visualforce Page2
コンポーネント側でApexコードを実装する必要が無いのでシンプルな実装となります。また、コンポーネント側で実装するときよりも汎用的に使えると思います。
こんな感じでコンポーネント開発がやりやすくなるので、type="ApexPages.Action"を使った方法は覚えておくと便利です。
デモ動画
おまけ
Visualforce Componentですが、出来る限りシンプルな作りになるようにした方がいいと思っています。例えば、上記のサンプルコードでは各ページ毎に検索処理を用意してコンポーネント側で呼び出して実行するという仕組みになっています。
もし、「コンポーネントを設置するだけで検索処理を実行できるようにする」、「ページ側では処理を記載せずに済むようにする」というような作りにした場合、コンポーネント側でフラグを持たせて実行する処理内容を切り替えたり、その結果を反映させたりという複雑な処理の実装が必要になってしまいます。
ページの場合は、万が一複雑なコードになってしまいエラーが発生するようなことがあっても、その影響が他の機能にでることはあまりありませんが、コンポーネントだと複数の機能に影響を与えてしまいます。
機能追加や改修作業が大変になったり、特にテスト周りが大変なことになります。テストクラスをきちんと実装することである程度は楽になりますが、ページ側との値の受け渡しなどが正常に行えているかの確認はなかなか大変だと思います。
そんな感じでページ開発よりもいろいろな箇所に影響を与えてしまうので、Visualforce Comonentを実装するときはできるかぎりシンプルな作りにしておくといいのかなと思いました。