什么是模块化编码,我做得对吗?

时间:2012-01-25 13:40:34

标签: c++

我正在试图弄清楚我是否正确理解了模块化代码的真正含义。我知道它非常强大/有用,所以我想确保我正确地学习它。

为了开始学习,我制作了一个相当简单的系统,根据一些标准将实体组合在一起。先到先得。

我还想以图形方式显示群组及其成员,以向用户(我自己)显示正在发生的事情。我将使用SDL库。

所以让我们把它分成几个类;

实体

主类“实体”将具有用于线程安全的Boost :: mutex,以及包含指向实际实体的指针的映射。当提供实体ID时,让我们创建一个从所述映射中检索指向实际实体的指针的函数。

class Entities
{
public:
    boost::mutex access_entitymap; //Thread safety
    std::map<unsigned int, Entity*> entitymap;

    Entity* getEntity(unsigned int entityID);
};

实体

保存有关实际实体的信息,例如它的唯一ID。并指向父“实体”的指针。

LFDGroups

分组系统。 包含指向实际组的指针的地图, 具有组在队列中的位置的地图(先到先服务。从该地图中删除完整的组以使迭代更快), 和一个实体在该组中的位置的地图(5个点,哪个实体占据了哪个点?)。 此外,它还包括一些在所述地图上操作的功能。如添加和删除成员。作为示例,addmember()函数将确保将实体添加到具有最高优先级的组中,或者在必要时创建新组。

groupObject

保存有关实际组的信息,例如它的唯一ID和它的居民实体ID。但也有一些功能,如;

LFDGroups *lfdgroup; //Parent LFDGroups;
bool isEmpty(); //is this group empty?
bool isFull(); //is this group full?
unsigned int getPosition(); //Position in queue?
bool addMember(unsigned int entityID,bool snatchIt); 
/*Add a member. Calls removeMember() on the entities' groupObject 
first if the entityID is already in another group.*/
bool removeMember(unsigned int entityID,bool snatchIt); 
/*Remove a member from this group, and snatch a member from another 
group further up in the queue. This ensures groups are always full 
if enough people are queued.*/
bool hasMember(unsigned int entityID); //Is this entity ID in our group?
/*etc. etc.*/

队列

提供一些易于使用的功能,使测试更容易。如;

void addFakeEntity(bool queuenow); //Create an all new entity and immediately queue it.
void removeFakeEntity(); //Remove a random entity from a random group
void removeFakeEntity(unsigned int entityID); //Remove a given entity from it's corresponding group.

SDLMain

以图形方式显示LFDGroups组的内容。它有多少成员,哪些斑点被采取,哪些不是等等。

还证明按钮可以使用Queue的功能。例如“添加”按钮将调用“queue-&gt; addFakeEntity(true)”

所以现在我可以轻松地开始整个事情;

#include "SDL_main.h" //gfx
#include "class_LFDGroups.h" //group system
#include "queue.h" //ease of use for testing
#include "class_entities.h" //entities

int main( int argc, char* args[] )
{
    Entities * entities = new Entities;
    LFDGroups * lfdgroups = new LFDGroups(entities);
    Queue * queue = new Queue(lfdgroups);
    SDLMain * sdlmain = new SDLMain(queue);
    return 1;
}
  1. 实体可以在没有任何其他情况下使用。
  2. LFDGroups只能与实体一起使用。
  3. 队列需要两者,但LFDGroups已经包含指向 实体。毕竟,没有它它就无法运作。
  4. SDLMain使用全部3。
  5. 果然;

    group_example

    所以这意味着即使我禁用图形显示组,我仍然可以将实际的分组系统用于其他事情。 而且,与某些对象相关的功能也在该对象本身内。例如,Entity* getEntity(unsigned int entityID);函数位于Entities类中,而不在groupObject中,即使这是目前唯一正在使用它的函数。

    这就是模块化编码吗?我做得对吗?

1 个答案:

答案 0 :(得分:2)

是的,您的程序希望遵循模块化编程范例,例如将各个组件组合在一起组成程序,并以特定组件可替换的方式编写。

因此,您已将程序的逻辑拆分为单独的类,并且还将类拆分为单独的编译单元(假设如此,基于SDLMain.h源中的包含),因此要添加新功能说你的小组类,只需要改变那个模块(假设新的功能只在内部被那个类调用),并且通过查看你的来源,程序在逻辑上被分成易于识别的独立部分。

您也可以轻松替换部分代码,例如,GUI前端可以替换为Qt或wxwindows。由于gui调用数据的操作不会改变,因此可以编写新的gui代码,并调用同一组操作,并且的数据组件将被更改。