2017-02-06 23 views
1

我有一个Engine类,它具有核心逻辑,但有这样的课程将通过类似功能的第三方引擎来代替一个机会,所以我想的其余部分的影响最小应用。C++限制核心类的可视性和提供干净的界面

我有另一个类叫Adapter,它允许与Engine类的简单接口,并且还在Engine类的顶部提供了一些增值功能。

然后我有叫OrderProcessor,我希望暴露给具有更简单的界面应用程序的其余部分的类。

我想EngineAdapter从应用程序的休息和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

EngineAdapter私人嵌套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。只要您没有可变参数/参数包,此违约计划就会生效;如果你这样做,你需要在它们之前传递它并手动传递它。