代理パターンは、他のオブジェクトへのアクセスを制御するためにそのオブジェクトの代理を提供します。以下では、「依頼者」「代理人」「目標」という役割を使って、代理パターンの基本的な概念と実装方法を説明します。
### シナリオ
ある「依頼者」が「目標」にプレゼントを贈るために「代理人」を介して行動するというシナリオで、代理パターンを理解します。
#### ターゲットクラス (目標)
/**
* 目標となる人物
*/
public class TargetPerson {
private String name;
public TargetPerson(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
#### プレゼント送付インターフェース
/**
* プレゼント送付インターフェース
*/
public interface GiftSender {
void sendToy();
void sendFlower();
void sendChocolate();
}
#### 依頼者クラス
/**
* 依頼者クラス
*/
public class Client implements GiftSender {
private String name;
private TargetPerson target;
public Client(String name) {
this.name = name;
}
public void admire(TargetPerson target) {
this.target = target;
}
@Override
public void sendToy() {
if (target == null) return;
System.out.println(name + " がおもちゃを " + target.getName() + " に贈りました");
}
@Override
public void sendFlower() {
if (target == null) return;
System.out.println(name + " が花を " + target.getName() + " に贈りました");
}
@Override
public void sendChocolate() {
if (target == null) return;
System.out.println(name + " がチョコレートを " + target.getName() + " に贈りました");
}
}
#### 代理人クラス
/**
* 代理人クラス
*/
public class Agent implements GiftSender {
private Client client;
public Agent(Client client, TargetPerson target) {
this.client = client;
client.admire(target);
}
@Override
public void sendToy() {
client.sendToy();
}
@Override
public void sendFlower() {
client.sendFlower();
}
@Override
public void sendChocolate() {
client.sendChocolate();
}
}
#### 実行例
public class ProxyExample {
public static void main(String[] args) {
// 目標となる人
TargetPerson target = new TargetPerson("山田さん");
// 依頼者
Client client = new Client("鈴木さん");
// 代理人を作成し、依頼者の要求を処理
Agent agent = new Agent(client, target);
// プレゼントを送る
agent.sendToy();
agent.sendFlower();
agent.sendChocolate();
}
}
#### 結果
鈴木さん がおもちゃを 山田さん に贈りました
鈴木さん が花を 山田さん に贈りました
鈴木さん がチョコレートを 山田さん に贈りました
### 代理パターンの種類
1. **リモートプロキシ**: 違うアドレス空間にあるオブジェクトのローカルな代表を提供し、異なる場所にあるオブジェクトの存在を隠蔽します。
2. **仮想プロキシ**: 高コストなオブジェクトを必要に応じて生成し、インスタンス化に時間がかかる実際のオブジェクトを保持します。
3. **セキュリティプロキシ**: 実際のオブジェクトへのアクセス権限を制御します。
4. **スマートリファレンス**: 実際のオブジェクトが呼び出される際に、追加の操作を行うための仕組みです。