Proxy パターン![]() Proxy パターンは、プログラミングにおけるデザインパターンの一種。Proxy(プロキシ、代理人)とは、大まかに言えば、別物のインタフェースとして機能するクラスである。その「別物」は何でもよく、ネットワーク接続だったり、メモリ上の大きなオブジェクトだったり、複製がコスト高あるいは不可能な何らかのリソースなどである。 Proxy パターンのよく知られている例として、参照カウント付きポインタオブジェクトがある。 複雑なオブジェクトの複数のコピーが必須となる状況では、Proxy パターンに Flyweight パターンを加えることでメモリ使用量を抑えることができる。通常、複雑なオブジェクトのインスタンスは1つだけ生成し、プロキシオブジェクトを複数生成する。それらプロキシオブジェクトは唯一の複雑なオブジェクトへの参照を含む。プロキシへの操作は、オリジナルのオブジェクトにフォワードされる。プロキシオブジェクトが全て破棄されると、参照されていた複雑なオブジェクトの使用していたメモリも解放される。 例Virtual Proxy (Java)以下のJavaの例は、"virtual proxy" パターンを示したものである。このプログラムは以下のように出力する。 Loading HiRes_10MB_Photo1 Displaying HiRes_10MB_Photo1 Loading HiRes_10MB_Photo2 Displaying HiRes_10MB_Photo2 Displaying HiRes_10MB_Photo2
import java.util.*;
interface Image {
public void displayImage();
}
class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadImageFromDisk();
}
private void loadImageFromDisk() {
// 時間のかかる一連の操作
// ...
System.out.println("Loading "+filename);
}
public void displayImage() { System.out.println("Displaying "+filename); }
}
class ProxyImage implements Image {
private String filename;
private Image image;
public ProxyImage(String filename) { this.filename = filename; }
public void displayImage() {
if (image == null) {
image = new RealImage(filename); // ロードはオンデマンドでのみ行われる
}
image.displayImage();
}
}
class ProxyExample {
public static void main(String[] args) {
Image image1 = new ProxyImage("HiRes_10MB_Photo1");
Image image2 = new ProxyImage("HiRes_10MB_Photo2");
Image image3 = new ProxyImage("HiRes_10MB_Photo3");
image1.displayImage(); // ロードが必要
image2.displayImage(); // ロードが必要
image2.displayImage(); // すでにロード済みなのでロード不要
// image3の画像は一度もロードされない
}
}
Protection Proxy (C#)以下のC#の例では、 この例では、正しいパスワードは thePassword である。 using System;
namespace ConsoleApplicationTest.FundamentalPatterns.ProtectionProxyPattern
{
public interface IClient {
string GetAccountNo();
}
public class RealClient : IClient {
private string accountNo = "12345";
public RealClient() {
Console.WriteLine("RealClient: Initialized");
}
public string GetAccountNo() {
Console.WriteLine("RealClient's AccountNo: " + accountNo);
return accountNo;
}
}
public class ProtectionProxy : IClient
{
private string password; //秘密のパスワード
RealClient client;
public ProtectionProxy(string pwd) {
Console.WriteLine("ProtectionProxy: Initialized");
password = pwd;
client = new RealClient();
}
// ユーザーを認証し、アカウント番号を返す
public String GetAccountNo() {
Console.Write("Password: ");
string tmpPwd = Console.ReadLine();
if (tmpPwd == password) {
return client.GetAccountNo();
} else {
Console.WriteLine("ProtectionProxy: Illegal password!");
return "";
}
}
}
class ProtectionProxyExample
{
[STAThread]
public static void Main(string[] args) {
IClient client = new ProtectionProxy("thePassword");
Console.WriteLine();
Console.WriteLine("main received: " + client.GetAccountNo());
Console.WriteLine("\nPress any key to continue . . .");
Console.Read();
}
}
}
関連項目外部リンク
|