Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;软件设计选项、类关系_C++_Class_Relationships - Fatal编程技术网

C++ C++;软件设计选项、类关系

C++ C++;软件设计选项、类关系,c++,class,relationships,C++,Class,Relationships,问题: 我有完全独立的软件经理(软件实体),例如CCarManager、CTruckManager等。。在某些时候,我正在创建新对象,例如CCar。CCar必须与不同的独立经理建立关系,例如,与CResourceManager、CTruckManager建立关系。将CCar与这些经理联系起来的最佳方式是什么 解决方案: 具有全局软件管理器(头文件中的Singleton或extern) [不喜欢全球化] 使用一个全局点并将其传递给其他对象,例如CCar(capapplication)、capapp

问题:

我有完全独立的软件经理(软件实体),例如CCarManager、CTruckManager等。。在某些时候,我正在创建新对象,例如CCar。CCar必须与不同的独立经理建立关系,例如,与CResourceManager、CTruckManager建立关系。将CCar与这些经理联系起来的最佳方式是什么

解决方案:

  • 具有全局软件管理器(头文件中的Singleton或extern) [不喜欢全球化]

  • 使用一个全局点并将其传递给其他对象,例如CCar(capapplication)、capapplication->TrukManager()、capapplication->CarManager()。。。 [看起来不太好,但可以传递一个指针]

  • 传递给CCar(CCarManager*pCarManager、CTruckManager*pTruckManager….) [难以扩展]

  • 使用观察者模式,例如CCar.Attach(CCarManager)、CCar.Attach(CTruckManager); [易于扩展,但主要集中在处理方法调用、哪些部分负责什么等方面,还有很多检查]

  • 工厂

    CCarFactory类(CCarManager*pMngr) { CCar*CreateCar() { 返回CCar(m_pCarManager); } }


  • 其他的方法是什么

    您可以在
    CCar
    的构造函数中传递对
    CResourceManager
    CTruckManager
    等的引用

    CCar(const CResourceManager& resourceMgr, const CTruckManager& truckMgr):
        _resourceMgr(resourceMgr), _truckMgr(truckMgr) {
        //relevant construtor code here
    }
    
    通过这种方式,也很容易使用模拟实现进行测试。很难说不知道“经理类”做什么


    依我看,名称以“Manager”结尾的类通常要么命名不好(我已经做了很多次了),要么设计不好。

    您可以在
    CCar
    的构造函数中传递对
    CResourceManager
    CTruckManager
    等的引用

    CCar(const CResourceManager& resourceMgr, const CTruckManager& truckMgr):
        _resourceMgr(resourceMgr), _truckMgr(truckMgr) {
        //relevant construtor code here
    }
    
    通过这种方式,也很容易使用模拟实现进行测试。很难说不知道“经理类”做什么


    依我看,名称以“Manager”结尾的类通常要么命名不好(我已经做了很多次了),要么设计不好。

    如果您不使用单例模式的唯一原因是因为您不喜欢它,我想您可能需要重新考虑您的方法


    单身是你想要实现的完美模式。您的管理类应该只有一个实例,并且需要从许多其他类访问。

    如果您不使用Singleton模式的唯一原因是因为您不喜欢它,我想您可能需要重新考虑您的方法


    单身是你想要实现的完美模式。您的管理类应该只有一个实例,并且需要从许多其他类进行访问。

    如果没有更多的规范,很难说。。。如果CCar要求对manager方法(如内部变量/方法)进行特殊访问,或反之亦然,则可以在CCar manager中声明为friend,或在这些manager类中声明为friend

    举个简单的例子,记住那些糟糕的成员名称

    class CCar
    {
        int I;
    public:
        friend class CManager;
        CCar(int i): I(i) {}
    
    };
    
    class CManager
    {
        int D;
    public:
        CManager(int i, CCar& car): D(i) 
        {
            car.I = 5;      // modify CCar instance internal member
        }
    
    };
    
    反之亦然

    如果一个CCar实例可以有多个CCarManager,则可以设置一个指针数组,将这些管理器“链接”到CCar实例。与其拥有3个不同的pManager数组,不如拥有一个Manager基类,并将这些管理器子类化到该基类,这样可以将对管理器的所有引用存储在一个数组中

    class Manager // etc...
    
    class CResourceManager : public Manager 
    
    // in CCar
    std::vector<Manager*> _mgrs;
    // or if heap allocated
    std::vector<std::shared_ptr<Manager>> _mgrs; // assuming multiple CCars can reference same manager instance
    
    类管理器//等。。。
    类别资源经理:公共经理
    //综合资本分析及审查
    标准::向量管理器;
    //或者如果已分配堆
    标准::向量_mgrs;//假设多个CCAR可以引用同一个manager实例
    
    另一种方法可以是使用一个结构/类来保存特定实例的所有管理器引用

    struct MgrRefs
    {
        std::vector<CCarManager*> _pCarMgrs;
        std::vector<CResourceManager*> _pResMgrs;
        // etc....
    };
    
    struct MgrRefs
    {
    std::vector_pCarMgrs;
    std::vector_pResMgrs;
    //等等。。。。
    };
    
    如果没有更多的规范,很难说。。。如果CCar要求对manager方法(如内部变量/方法)进行特殊访问,或反之亦然,则可以在CCar manager中声明为friend,或在这些manager类中声明为friend

    举个简单的例子,记住那些糟糕的成员名称

    class CCar
    {
        int I;
    public:
        friend class CManager;
        CCar(int i): I(i) {}
    
    };
    
    class CManager
    {
        int D;
    public:
        CManager(int i, CCar& car): D(i) 
        {
            car.I = 5;      // modify CCar instance internal member
        }
    
    };
    
    反之亦然

    如果一个CCar实例可以有多个CCarManager,则可以设置一个指针数组,将这些管理器“链接”到CCar实例。与其拥有3个不同的pManager数组,不如拥有一个Manager基类,并将这些管理器子类化到该基类,这样可以将对管理器的所有引用存储在一个数组中

    class Manager // etc...
    
    class CResourceManager : public Manager 
    
    // in CCar
    std::vector<Manager*> _mgrs;
    // or if heap allocated
    std::vector<std::shared_ptr<Manager>> _mgrs; // assuming multiple CCars can reference same manager instance
    
    类管理器//等。。。
    类别资源经理:公共经理
    //综合资本分析及审查
    标准::向量管理器;
    //或者如果已分配堆
    标准::向量_mgrs;//假设多个CCAR可以引用同一个manager实例
    
    另一种方法可以是使用一个结构/类来保存特定实例的所有管理器引用

    struct MgrRefs
    {
        std::vector<CCarManager*> _pCarMgrs;
        std::vector<CResourceManager*> _pResMgrs;
        // etc....
    };
    
    struct MgrRefs
    {
    std::vector_pCarMgrs;
    std::vector_pResMgrs;
    //等等。。。。
    };
    
    我知道你可能会考虑让各个实体执行他们自己的业务逻辑。之后,这真的是一个关于如何为实体做存储库的问题。HMM,我嗅到了你可能会考虑让各个实体强制执行自己的业务逻辑。在这之后,真正的问题是如何为实体创建存储库;o) 。。。他还可以将依赖对象的构造及其装饰封装在一个“外部”可配置工厂中。“IMHO,名称以“Manager”结尾的类通常要么命名不好(我已经做了很多次了),要么设计不好。”我想由于缺乏经验,我也有同样的问题,你能分享你的工作吗?听起来不错;o) 。。。他还可以将依赖对象的构造及其装饰封装在一个“外部”可配置工厂中。“IMHO,名称以“Manager”结尾的类通常要么命名不好(我已经做了很多次了),要么设计不好。”