I have an Engine
class that has core logic, however there is a chance this class will be replaced by a third party engine with similar functionalities, so I want minimum impact to rest of the application.
I have another class called Adapter
that allows simple interface with the Engine
class and also provides some value-added functionality on top of the Engine
class.
I then have another class called OrderProcessor
that I want to expose to rest of the application that has a much simpler interface.
I want Engine
and Adapter
hidden from rest of the application and OrderProcesseor
as the only interface for rest of the application.
How do I go about designing this and which access modifier to use where? Is there a design pattern that does it?
This is what I have but I don't think it's right.
//This is the core functionality. Might have to replace this class with a third //party implementation
//Want to hide it as much as possible
class Engine
{
private:
char* ip;
char* port;
protected:
Engine();
bool Connect();
bool DisConnect();
bool SendOrder(Message msg);
bool CancelOrder (CancelMessage cxl);
Message ReceiveOrder();
};
//This is an interface to the engine and provides value added functions
//Don't want this known to anyone except the OrderPRocessor
class Adapter : public Engine
{
private:
int TotalAmount;
double DollarAmount;
protected:
bool Start(char*ip, char* port); //this will call Engine's connect() and do other things
bool Stop (); //this will call Engine's Disconnect
int TotalInventory();
double TotalSales();
double TotalCommission();
};
//This class is the main interface to the rest of the application for order
//processing related functionality.
class OrderProcessor
{
public:
OrderProcessor();
~OrderProcessor();
Stats SendStats();
ManageInventory();
private:
Adapter adapter;
};
Make Engine
and Adapter
private nested classes of OrderProcessor
:
class OrderProcessor
{
public:
OrderProcessor();
~OrderProcessor();
Stats SendStats();
ManageInventory();
private:
class Engine
{
// ...
};
class Adapter : public Engine
{
// ...
};
Adapter adapter;
};
If you want to more granular access limits, make 'key tags':
class OrderProcessor
{
public:
class OpenSesame
{
friend ClassThatCanAccessTreasure;
private:
OpenSezame() {}; // = default is not sufficient
};
int AccessTreasure(int arg1, int arg2, OpenSesame key = {});
};
Note that in the above scheme you don't need to pass key
, because it's defaulted. Since the default value is instantiated in caller context, only friends of OpenSesame
can call AccessTreasure
. This defaulting scheme works as long as you don't have varargs/parameter pack; if you do, you need to pass it before those and pass it manually.