C++ C++;可重用模块类设计

C++ C++;可重用模块类设计,c++,C++,我有很多很多模块可以从使用完全相同的设计模式和共享公共类中获益。在单个组件级别上,一切都有意义,类可以很容易地扩展。但是,当我试图将它们绑定到一个公共模块对象中时,它似乎是一个多态性不适用的模式,我缺少正确的模式或设计 从所有基类开始,所有其他类都将从基类扩展。模块是粘合剂和问题所在模块将包含防止代码重复的方法,如添加组件 // A physical interface (Ethernet, Bluetooth, etc) class Interface {}; // A basic compo

我有很多很多模块可以从使用完全相同的设计模式和共享公共类中获益。在单个组件级别上,一切都有意义,类可以很容易地扩展。但是,当我试图将它们绑定到一个公共模块对象中时,它似乎是一个多态性不适用的模式,我缺少正确的模式或设计

从所有基类开始,所有其他类都将从基类扩展。
模块是粘合剂和问题所在<代码>模块
将包含防止代码重复的方法,如
添加组件

// A physical interface (Ethernet, Bluetooth, etc)
class Interface {};
// A basic component
class Component {};
// An std::map wrapper for managing Components
class ComponentManager {};
// A place to store data
class Database {};
// A module to tie all things together
class Module {
public:
    Interface interface;
    ComponentManager manager;
    Database db;
    void AddComponent(Component& c) {
        manager.AddComponent(c);
        db.InsertComponent(c);
    }
};
在我们想要扩展所有或大部分类以及
模块之前,一切都很好

class EthInterface : public Interface {}; // cool
class UdpClientComponent : public Component {}; // cool
class UdpClientDatabase : public Database {}; // cool
//class UdpClientComponentManager : public ComponentManager {}; // 90% of the time won't need it
class UdpClientModule : public Module {
public:
    EthInterface interface; // how to get an EthInterface instead of Interface?
    UdpClientDatabase db; // how to get a UdpClientDatabase instead of Database?
};

我试图了解什么样的模式或设计,或者在这里使用什么。我认为模板可能不是正确的解决方案,因为我简化了这个示例,并且不认为带有5或6个
t
s的模板是好的设计。我真的不知道如何使用PTR设计它,因为我从外部为扩展的
模块
PTR供电,我希望它是独立的,这样人们就可以编写
UdpClientModule模块
,可以说,他们可以得到电池。

这可能是一种冒险,但也许它会让你朝另一个方向搜索。。。您可以使用模板,重新定义模块,使其看起来像这样:

模板类模块{
公众:
IFC接口;
构型管理经理;
分贝;
无效添加组件(组件和控制){
经理。添加组件(c);
db.InsertComponent(c);
}
};
但是如果您这样做,您应该确保
IFC
COMP
CM
DB
都是从
接口
组件
组件管理器
数据库
派生出来的,为此您需要概念。我不知道你的情况,但这有点让我不知所措,所以我会走另一条路:

类模块{
公众:
模块(接口和ifc、数据库和数据库):
接口(ifc),
管理器(),db(_db){
}
无效添加组件(组件和c){
经理。添加组件(c);
db.InsertComponent(c);
}
私人:
接口&接口;
组件经理;
数据库&db;
};
UdpClientModule类:公共模块{
公众:
UdpClientModule():
模块(ethInterface,udpClientDb),
ethInterface(),
udpClientDb(){
}
私人:
eth接口eth接口;
UdpClientDatabase udpClientdb;
};

这仍然很笨拙,但它至少能帮你找到(我想)你想去的地方。

这可能是一种冒险,但可能会让你朝着不同的方向搜索。。。您可以使用模板,重新定义模块,使其看起来像这样:

模板类模块{
公众:
IFC接口;
构型管理经理;
分贝;
无效添加组件(组件和控制){
经理。添加组件(c);
db.InsertComponent(c);
}
};
但是如果您这样做,您应该确保
IFC
COMP
CM
DB
都是从
接口
组件
组件管理器
数据库
派生出来的,为此您需要概念。我不知道你的情况,但这有点让我不知所措,所以我会走另一条路:

类模块{
公众:
模块(接口和ifc、数据库和数据库):
接口(ifc),
管理器(),db(_db){
}
无效添加组件(组件和c){
经理。添加组件(c);
db.InsertComponent(c);
}
私人:
接口&接口;
组件经理;
数据库&db;
};
UdpClientModule类:公共模块{
公众:
UdpClientModule():
模块(ethInterface,udpClientDb),
ethInterface(),
udpClientDb(){
}
私人:
eth接口eth接口;
UdpClientDatabase udpClientdb;
};

它仍然很笨拙,但它至少让你找到了一些你想得到的东西。

接口依赖于抽象,你想依赖于具体类型,你的设计缺陷就在那里。让接口执行“接口”,让具体类处理具体类型

class Module {
public:
    virtual ~Module() = default;

    void AddComponent(Component& c) {
        manager().AddComponent(c);
        db().InsertComponent(c);
    }
    
    virtual Interface& interface() = 0;
    virtual ComponentManager& manager() = 0;
    virtual Database& db() = 0;
    
};

class UdpClientModule : public Module {
public:       
    Interface& interface() override { return ethInterface; }
    ComponentManager& manager() override { return udcClienddb; }
    Database& db() override { return manager; }
    
    void specialUdpMethod() const { /*...*/}

private:
    EthInterface ethInterface;
    UdpClientDatabase udpClientdb;
    ComponentManager manager;
};

在这种情况下,您声明每个模块必须提供一个接口、e组件管理器和一个db。如果您有更宽松的约束,您可以将依赖项移动到依赖项注入解决方案,并改用指针。

接口依赖于抽象,您希望依赖于具体类型以及设计缺陷所在的位置。让接口执行“接口”,让具体类处理具体类型

class Module {
public:
    virtual ~Module() = default;

    void AddComponent(Component& c) {
        manager().AddComponent(c);
        db().InsertComponent(c);
    }
    
    virtual Interface& interface() = 0;
    virtual ComponentManager& manager() = 0;
    virtual Database& db() = 0;
    
};

class UdpClientModule : public Module {
public:       
    Interface& interface() override { return ethInterface; }
    ComponentManager& manager() override { return udcClienddb; }
    Database& db() override { return manager; }
    
    void specialUdpMethod() const { /*...*/}

private:
    EthInterface ethInterface;
    UdpClientDatabase udpClientdb;
    ComponentManager manager;
};

在这种情况下,您声明每个模块必须提供一个接口、e组件管理器和一个db。如果您有更宽松的约束,您可以将依赖项移动到依赖项注入解决方案,并改用指针。

“不要认为具有5或6个t的模板是好的设计。”。但是用户必须提供5到6个成员或参数(为模块接口提供数据)。好吧,这是一个糟糕的设计吗?我真的有这种重复的模式在这里,并希望不要复制粘贴它无处不在。这只是我的
模块的问题。我的意思是,如何
使用UdpClientModule=Module比您的示例更糟糕?我不知道:)只是想知道设计这个的最佳方法是什么,并且不确定模板是个好主意。“不要认为有5或6个t的模板是好设计。”。但是用户必须提供5到6个成员或参数(为模块接口提供数据)。好吧,这是一个糟糕的设计吗?我真的有这种重复的模式在这里,并希望不要复制粘贴它无处不在。这只是我的
模块的问题。我的意思是,如何使用