Proxy Pattern
- Structural Design Patterns
Definition of Proxy: The authority to represent someone else, especially in voting.
What is the Proxy Pattern?
The Proxy Pattern provides a surrogate or placeholder for another object to control access to it. The Surrogate or placeholder would be our Proxy Object that controls the access to another object. Each implement the same interface.
UML
The Client has no knowledge that it is iteracting with a Proxy vs. the Real Subject.
Different Types of Proxies:
- Remote Proxy
- Virtual Proxy
- Protection Proxy
- Smart Reference
Example of the Proxy Pattern
In my Example I have Stadium that allows two different type of fans/members, members and regular guests. Memebers receive a few perks like such as early access and access to the floor over normal guests.
UML
NBAFan Header File (NBAfan.h)
Here is a close up of the UML of an NBAfan
!
#ifndef NBA_Fan_H_
#define NBA_Fan_H_
#include <string>
class NBAfan {
private:
std::string name_;
public:
NBAfan(std::string name) : name_(name) {}
virtual ~NBAfan() {} // Deconstructor
std::string GetName() { return name_; }
virtual bool HasFloorSeatAccess() = 0;
virtual bool HasEarlyAccess() = 0;
};
#endif /* NBA_Fan_H_ */
NBAGuest Header File (NBAGuest.h)
#ifndef NBAGUEST_H_
#define NBAGUEST_H_
#include "NBAfan.h"
class NBAGuest : public NBAfan {
public:
NBAGuest(std::string name);
virtual ~NBAGuest();
virtual bool HasFloorSeatAccess()
{
return false;
}
virtual bool HasEarlyAccess()
{
return false;
}
};
NBAGuest::NBAGuest(std::string name) : NBAfan(name){}
NBAGuest::~NBAGuest() {}
#endif /* NBAGUEST_H_ */
NBAMember Header File (NBAMember.h)
#ifndef NBA_MEMBER_H_
#define NBA_MEMBER_H_
#include "NBAfan.h"
class NBAMember : public NBAfan {
public:
NBAMember(std::string name);
virtual ~NBAMember();
virtual bool HasFloorSeatAccess()
{
return true;
}
virtual bool HasEarlyAccess()
{
return true;
}
};
NBAMember::NBAMember(std::string name) : NBAfan(name) {}
NBAMember::~NBAMember() {}
#endif /* NBA_MEMBER_H_ */
Stadium Header File (Stadium.h)
!
#ifndef STADIUM_H_
#define STADIUM_H_
#include "NBAfan.h"
#include <iostream>
class NBAfan;
class Stadium {
public:
Stadium();
virtual ~Stadium();
virtual void EnterStadiumEarly(NBAfan * patron);
virtual void AttendFloor(NBAfan * patron);
};
Stadium::Stadium() {} // constructor
Stadium::~Stadium() {} // deconstructor
// members normally
void Stadium::EnterStadiumEarly(NBAfan * patron)
{
std::cout << "Welcome, " << patron->GetName() << ", to our early access stadium hours\n";
}
void Stadium::AttendFloor(NBAfan * patron)
{
std::cout << "Welcome, " << patron->GetName() << ", to the floor seats\n";
}
#endif /* STADIUM_H_ */
Stadium Interface Header File (StadiumIF.h)
!
#ifndef STADIUMIF_H_
#define STADIUMIF_H_
class NBAfan;
class StadiumIF {
public:
virtual void EnterStadiumEarly(NBAfan * patron) = 0;
virtual void Attendfloor(NBAfan * patron) = 0;
};
#endif /* STADIUMIF_H_ */
Stadium Proxy Header File (StadiumProxy.h)
#ifndef STADIUMPROXY_H_
#define STADIUMPROXY_H_
#include "StadiumProxy.h"
#include "Stadium.h"
#include "NBAfan.h"
#include <iostream>
class Stadium;
class NBAfan;
class StadiumProxy {
public:
StadiumProxy(Stadium * stadium);
virtual ~StadiumProxy();
virtual void EnterStadiumEarly(NBAfan * patron);
virtual void AttendFloor(NBAfan * patron);
private:
Stadium * m_pstadium;
};
StadiumProxy::StadiumProxy(Stadium * stadium) : m_pstadium(stadium) {}
StadiumProxy::~StadiumProxy() {}
void StadiumProxy::EnterStadiumEarly(NBAfan * patron)
{
if(patron->HasEarlyAccess())
{
m_pstadium->EnterStadiumEarly(patron);
}
else
{
std::cout << "Sorry, " << patron->GetName() << ", you don't have early stadium access privileges\n";
}
}
void StadiumProxy::AttendFloor(NBAfan * patron)
{
if(patron->HasFloorSeatAccess())
{
m_pstadium->AttendFloor(patron);
}
else
{
std::cout << "Sorry, " << patron->GetName() << ", you don't have access to the Floor Seats \n";
}
}
#endif /* STADIUMPROXY_H_ */
Main File to Run (StadiumProxyTest.cpp)
!
#include "Stadium.h"
#include "StadiumProxy.h"
#include "NBAMember.h"
#include "NBAGuest.h"
int main()
{
NBAMember member(std::string("Devin"));
NBAGuest guest(std::string("Noah"));
NBAGuest guest2(std::string("Sarah"));
NBAMember member2(std::string("Aaron"));
Stadium stadium;
StadiumProxy stadiumProxy(&stadium);
stadiumProxy.EnterStadiumEarly(&member);
stadiumProxy.EnterStadiumEarly(&member2);
stadiumProxy.EnterStadiumEarly(&guest);
stadiumProxy.EnterStadiumEarly(&guest2);
stadiumProxy.AttendFloor(&member);
stadiumProxy.AttendFloor(&member2);
stadiumProxy.AttendFloor(&guest);
stadiumProxy.AttendFloor(&guest2);
}
Output
Welcome, Devin, to our early access stadium hours
Welcome, Aaron, to our early access stadium hours
Sorry, Noah, you don't have early stadium access privileges
Sorry, Sarah, you don't have early stadium access privileges
Welcome, Devin, to the floor seats
Welcome, Aaron, to the floor seats
Sorry, Noah, you don't have access to the Floor Seats
Sorry, Sarah, you don't have access to the Floor Seats
Extra
- Let’s just use the Regualr Stadium Interface to see how it interacts/works
#include "Stadium.h"
#include "StadiumProxy.h"
#include "NBAMember.h"
#include "NBAGuest.h"
int main()
{
NBAMember member(std::string("Devin"));
NBAGuest guest(std::string("Noah"));
NBAGuest guest2(std::string("Sarah"));
NBAMember member2(std::string("Aaron"));
Stadium stadium;
StadiumProxy stadiumProxy(&stadium);
// Lets just use the stadium Interface to interact
stadium.AttendFloor(&member);
stadium.AttendFloor(&guest);
stadium.EnterStadiumEarly(&guest);
}
Output
Welcome, Devin, to the floor seats
Welcome, Noah, to the floor seats
Welcome, Noah, to our early access stadium hours