2017-02-06 2 views
1

У меня есть класс Engine, который имеет основную логику, однако есть вероятность, что этот класс будет заменен сторонним движком с аналогичными функциями, поэтому я хочу, чтобы минимальное воздействие на остальную часть заявление.C++ Ограничение видимости основного класса и обеспечение чистого интерфейса

У меня есть еще один класс под названием Adapter, который позволяет использовать простой интерфейс с классом Engine, а также предоставляет некоторые дополнительные функции в дополнение к классу Engine.

У меня есть еще один класс под названием OrderProcessor, который я хочу открыть для остальной части приложения, имеющего гораздо более простой интерфейс.

Я хочу, чтобы Engine и Adapter скрыты от остальной части приложения и OrderProcesseor как единственный интерфейс для остальной части приложения.

Как мне это сделать и какой модификатор доступа использовать где? Есть ли шаблон дизайна, который это делает?

Это то, что у меня есть, но я не думаю, что это правильно.

//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; 
}; 
+0

Может быть полезно [Является ли идиома pImpl действительно используемой на практике?] (Http://stackoverflow.com/questions/8972588/is-the-pimpl-idiom-really-used-in-practice) – lcs

+0

'ip' должен быть 'const char *' по крайней мере. Порт, возможно, int. – Igor

ответ

1

Сделать Engine и Adapter частные вложенных классов OrderProcessor:

class OrderProcessor 
{ 
public: 
    OrderProcessor(); 
    ~OrderProcessor(); 

    Stats SendStats(); 
    ManageInventory(); 

private: 
    class Engine 
    { 
     // ... 
    }; 

    class Adapter : public Engine 
    { 
     // ... 
    }; 

    Adapter adapter; 
}; 

Если вы хотите более детальные ограничения доступа, сделать 'ключевые тег':

class OrderProcessor 
{ 
public: 
    class OpenSesame 
    { 
     friend ClassThatCanAccessTreasure; 
    private: 
     OpenSezame() {}; // = default is not sufficient 
    }; 

    int AccessTreasure(int arg1, int arg2, OpenSesame key = {}); 
}; 

Обратите внимание, что в приведенной выше схеме вам не нужно проходить key, потому что она по умолчанию. Поскольку значение по умолчанию создается в контексте вызывающего абонента, только друзья OpenSesame могут звонить AccessTreasure. Эта схема по умолчанию работает до тех пор, пока у вас нет пакета varargs/parameter; если вы это сделаете, вам нужно передать его до этого и передать его вручную.

Смежные вопросы