本記事では、GoFが提唱する23のデザインパターンの一つである「Proxyパターン」について解説します。
Proxyパターンは、オブジェクトへのアクセスを制御するために使用される構造パターンです。
このパターンを使うことで、対象オブジェクトへのアクセスを簡略化したり、遅延処理を実装したり、その他の目的でのインタフェースを提供することが可能です。
本記事では、Proxyパターンの概要、具体的な使い方、およびJava、C++、C#、VB.NETでの実装例について詳しく説明します。
Proxyパターンとは
Proxyパターンは、実際のオブジェクト(RealSubject)に代わってその振る舞いを制御する代理(Proxy)オブジェクトを提供するデザインパターンです。
このパターンの主な目的は、クライアントと実際のオブジェクトとの間にインタフェースを設け、クライアントが実際のオブジェクトに直接アクセスするのを避けることです。
代理オブジェクトは、必要に応じて実際のオブジェクトを作成したり、処理を実行するタイミングを制御したりします。
Proxyパターンの使い方
Proxyパターンの主な使用ケースは以下の通りです。
リモートプロキシ
リモートオブジェクトへのアクセスを代理する際に使用されます。
リモートプロキシは、ネットワーク通信を隠蔽し、リモートオブジェクトに対してローカルオブジェクトのようにアクセスできるインタフェースを提供します。
仮想プロキシ
大きなメモリを必要とするオブジェクトの生成を遅延させるために使用されます。
オブジェクトが本当に必要になるまで生成を遅らせることで、リソースの無駄遣いを防ぎます。
保護プロキシ
アクセス制御を行うために使用されます。
特定の条件下でのみオブジェクトにアクセスさせる必要がある場合に、保護プロキシを使ってアクセス権限を制御します。
Proxyパターン実装サンプル
以下に、Java、C++、C#、VB.NETでのProxyパターンの実装サンプルを示します。
それぞれの言語で、RealSubject(実際のオブジェクト)とProxy(代理オブジェクト)の関係を実装します。
Javaの実装例
interface Subject {
void request();
}
class RealSubject implements Subject {
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
class Proxy implements Subject {
private RealSubject realSubject;
public void request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
System.out.println("Proxy: Logging request.");
realSubject.request();
}
}
public class Client {
public static void main(String[] args) {
Subject proxy = new Proxy();
proxy.request();
}
}
C++の実装例
#include
using namespace std;
class Subject {
public:
virtual void request() = 0;
};
class RealSubject : public Subject {
public:
void request() {
cout << "RealSubject: Handling request." << endl;
}
};
class Proxy : public Subject {
private:
RealSubject* realSubject;
public:
Proxy() : realSubject(nullptr) {}
void request() {
if (realSubject == nullptr) {
realSubject = new RealSubject();
}
cout << "Proxy: Logging request." << endl;
realSubject->request();
}
~Proxy() {
delete realSubject;
}
};
int main() {
Proxy proxy;
proxy.request();
return 0;
}
C#の実装例
using System;
interface Subject {
void Request();
}
class RealSubject : Subject {
public void Request() {
Console.WriteLine("RealSubject: Handling request.");
}
}
class Proxy : Subject {
private RealSubject realSubject;
public void Request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
Console.WriteLine("Proxy: Logging request.");
realSubject.Request();
}
}
class Client {
static void Main(string[] args) {
Subject proxy = new Proxy();
proxy.Request();
}
}
VB.NETの実装例
Interface Subject
Sub Request()
End Interface
Class RealSubject
Implements Subject
Public Sub Request() Implements Subject.Request
Console.WriteLine("RealSubject: Handling request.")
End Sub
End Class
Class Proxy
Implements Subject
Private realSubject As RealSubject
Public Sub Request() Implements Subject.Request
If realSubject Is Nothing Then
realSubject = New RealSubject()
End If
Console.WriteLine("Proxy: Logging request.")
realSubject.Request()
End Sub
End Class
Module Client
Sub Main()
Dim proxy As Subject = New Proxy()
proxy.Request()
End Sub
End Module
まとめ
Proxyパターンは、実際のオブジェクトに対するアクセスを制御する強力なデザインパターンです。
このパターンを使用することで、リモートアクセスやリソースの最適化、アクセス制御など様々な目的を達成することが可能です。
今回は、Java、C++、C#、VB.NETでの実装例を紹介しました。実際の開発において、状況に応じた適切なプロキシを選択することで、コードの柔軟性や拡張性が向上します。