プロキシパターン(Proxy Pattern)は、あるオブジェクトへのアクセスを制御するための代理オブジェクトを提供する構造デザインパターンです。これは、元のオブジェクトへの直接アクセスを隠蔽し、追加の機能(ロギング、アクセス制御、遅延読み込みなど)を提供するのに役立ちます。
例えば、学生がバスや電車の切符を購入するシナリオを考えてみましょう。駅は遠く、試験勉強で忙しい学生にとって、直接駅に行くのは大変です。そこで、代理店(プロキシ)に依頼して切符を購入することにします。代理店は、手数料を加算するかもしれませんが、割引キャンペーンを提供してくれるかもしれません。このように、学生は直接駅に行かなくても、代理店を通して切符を購入できます。
以下に、C++でプロキシパターンを実装する例を示します。この例では、チケット販売インターフェースを定義し、バスチケットと電車チケットの具体的な実装を提供します。そして、チケットエージェント(プロキシ)を通じてこれらのチケットを販売し、サービス料と割引を適用します。
// チケット販売インターフェース.h
#ifndef TICKET_SALES_INTERFACE_H
#define TICKET_SALES_INTERFACE_H
#include <iostream>
namespace travel {
using std::cout;
using std::endl;
class TicketSalesInterface {
public:
virtual ~TicketSalesInterface() {}
virtual void sell() = 0;
virtual void showPrice() = 0;
};
} // namespace travel
#endif // TICKET_SALES_INTERFACE_H
// 基本チケット.h
#ifndef BASE_TICKET_H
#define BASE_TICKET_H
#include "チケット販売インターフェース.h"
namespace travel {
class BaseTicket : public TicketSalesInterface {
// 抽象基底クラス
};
} // namespace travel
#endif // BASE_TICKET_H
// バスチケット.h
#ifndef BUS_TICKET_H
#define BUS_TICKET_H
#include "基本チケット.h"
namespace travel {
class BusTicket : public BaseTicket {
public:
void sell() override {
cout << "販売中: バスチケット" << endl;
}
void showPrice() override {
cout << "価格: 80 RMB" << endl;
}
};
} // namespace travel
#endif // BUS_TICKET_H
// 電車チケット.h
#ifndef TRAIN_TICKET_H
#define TRAIN_TICKET_H
#include "基本チケット.h"
namespace travel {
class TrainTicket : public BaseTicket {
public:
void sell() override {
cout << "販売中: 電車チケット" << endl;
}
void showPrice() override {
cout << "価格: 100 RMB" << endl;
}
};
} // namespace travel
#endif // TRAIN_TICKET_H
// チケットエージェント.h
#ifndef TICKET_AGENT_H
#define TICKET_AGENT_H
#include "基本チケット.h"
namespace travel {
class TicketAgent : public TicketSalesInterface {
public:
TicketAgent(BaseTicket* realTicket)
: real_ticket(realTicket) {}
~TicketAgent() {
delete real_ticket;
}
void sell() override {
real_ticket->sell();
}
void showPrice() override {
real_ticket->showPrice();
addServiceFee();
applyDiscount();
}
private:
void addServiceFee() {
cout << "サービス料: 20 RMB" << endl;
}
void applyDiscount() {
cout << "割引適用: 30%" << endl;
}
private:
BaseTicket* real_ticket;
};
} // namespace travel
#endif // TICKET_AGENT_H
// main.cc
#include "チケットエージェント.h"
#include "バスチケット.h"
#include "電車チケット.h"
using namespace travel;
int main() {
TicketAgent* agent;
agent = new TicketAgent(new BusTicket);
agent->sell();
agent->showPrice();
delete agent;
agent = new TicketAgent(new TrainTicket);
agent->sell();
agent->showPrice();
delete agent;
return 0;
}
コンパイルして実行すると、以下の出力が得られます。
[ccx@ubuntu ~/object-oriented/Proxy_Pattern]$>g++ * -o Tickets.exe
[ccx@ubuntu ~/object-oriented/Proxy_Pattern]$>./Tickets.exe
販売中: バスチケット
価格: 80 RMB
サービス料: 20 RMB
割引適用: 30%
販売中: 電車チケット
価格: 100 RMB
サービス料: 20 RMB
割引適用: 30%