デザインパターン入門 | Proxy(プロキシー)パターン

デザインパターンの1つ「Proxy(プロキシー)」パターンは、処理の「代理」をテーマにしたデザインパターンです。

「代理」ということは「代理してもらっている人(本人)」が存在しています。

これらの登場人物がどのように関連しあってプログラムが動いていくのかに注目しながら、「Proxy(プロキシー)」パターンについて見ていきましょう。

「Proxy(プロキシー)」パターンに登場するクラス・インターフェース

今回ご説明を行う「Proxy(プロキシー)」パターンの事例では、下図のようなクラス・インターフェースを作成していきます。

プロキシー1

「従業員(Employee)」とその「上司(Boss)」と「決済機能」を表すインターフェースである「Settlementing」があります。

「Employee」クラスも「Boss」クラスも決済業務を行うことができるため、「Settlementing」インターフェースを実装しています。

public interface Settlementing {
	 void settlement(); //通常決済を行う
	 void creditSettlement();  //クレジット決済を行う
}

そして、「従業員」はまだ新人のため、「通常決済」は行うことができますが、「クレジット決済」が行えないとします。

もしお客さんから「クレジット決済」を頼まれた場合、新人従業員は対応できないため、上司に依頼することになります。

このように、新人従業員でもできる決済業務は新人従業員(代理人)が行い、新人従業員ができない決済業務は上司(本人)が行うという処理構造となっています。

「Employee(従業員)」クラスは、下記のようになります。

public class Employee implements Settlementing{
	private Boss boss = null;

	//通常決済を行う
	@Override
	public void settlement() {
		System.out.println("商品の決済を行いました。");
	}

	//クレジット決済を行う
	@Override
	public void creditSettlement() {
		if(boss == null) {
			this.boss = new Boss();
		}
		boss.creditSettlement();
	}
}

「Employee」クラスには、「boss」フィールドがあり、お客さんから「クレジット決済」を依頼された場合に「Boss」クラスのインスタンスを作って格納しておき、次回また「クレジット決済」を依頼された場合にはこのフィールドのインスタンスを利用します。

「Employee」クラスでは、「クレジット決済」を行えないため、「creditSettlement」の内部では、「Boss」クラスのインスタンスに依頼し、「クレジット決済」行っています。

「Employee」クラスは「代理人」の役割を持っているクラスですので、「できる処理」のみを行い、「できない処理」は本人のクラスへ処理を依頼します。

そして、「Boss」クラスは下記のようになります。

public class Boss implements Settlementing{
	@Override
	public void settlement() {
		System.out.println("商品の決済を行いました。");
	}

	@Override
	public void creditSettlement() {
		System.out.println("商品のクレジット決済を行いました。");
	}
}

「Boss」クラスは、「通常決済」も「クレジット決済」も行うことができる「本人」のクラスです。

「プロキシー(代理)」のイメージを掴んでいくことが、このパターンの理解には大切ですので、どのクラスがどのクラスの「代理」となっているのかに注目してみてください。

「Proxy(プロキシー)」パターンのプログラムの実行

これまでにご紹介したクラスを利用して実行するプログラムは下記のようになります。

public class Main {
	public static void main(String[] args) {
		// Employeeクラスのインスタンスを生成
		Employee empl = new Employee();

		// 「通常決済」を実行
		empl.settlement();

		// 「クレジット決済」を実行
		empl.creditSettlement();
	}
}

実行結果は下記のようになります。

商品の決済を行いました。
商品のクレジット決済を行いました。

プログラムの実行時は「Employee」クラスしか利用していないのがわかりますね。

このように何かの処理の「代理」を行いたいときに「Proxy(プロキシー)」パターンを使うことができます。

これまでに書いたプログラムや現在書いているプログラムに「Proxy(プロキシー)」パターンを使うことができる部分がないかを探してみてはいかがでしょうか。

HOMEへ