Arcadio Alivio Sincero
Arcadio Alivio Sincero

Reputation: 720

C++ API design approaches

I'm trying to design an API and I'm wondering which approach is better. I have this concept I'll call a Message. This Message is composed of up to five MessageElements. There are about 300 MessageElements the user can add to a Message.

There are two approaches that I've thought of so far on to model this in C++. One, I can have a Message class with a method to add each MessageElement:

class Message
{
public:
    void AddMessageElement1();
    void AddMessageElement2();
    void AddMessageElement3();
    ...
    void AddMessageElement300();
};

(Note: the MessageElements aren't actually called "MessageElement1", "MessageElement2", etc.. They actually have more descriptive names than that. I'm just being generic here.)

Or, I represent each MessageElement by a class that all derive from a MessageElement base class. The Message class would thus have a single "Add()" method like so:

class Message
{
public:
    void Add(const MessageElement& element);
};

The advantage to approach 1 is that the class hierarchy is simple. I won't have 300+ classes in the library. Basically just one class. However, that'll be one class with 300+ methods. Plus, any changes to the class's public API (like I have to add an additional MessageElement type) would require a recompile of all users of the class.

The advantage to approach 2 is that the Message class's API becomes really simple. Also, adding additional MessageElement types would not require a recompile of all the users of the Message class. The disadvantage is that I'll have 300+ little classes populating the library's API.

Which approach would be better? I'm kind of leaning towards approach 2. But approach 1 seems easier for user's to grasp.

Upvotes: 1

Views: 280

Answers (1)

utnapistim
utnapistim

Reputation: 27385

Go with approach number 2.

Besides the advantages you stated (simple API for Message and modularity), you will have much more testable code with this approach (usually testable code is manageable and reusable code).

Approach 1 creates a monster;

If I went to an interview and the interviewer told me "we have a class with 300 methods in our code base" I would seriously consider not working there at all.

With approach 2 you may be able to centralize some of the the code in MessageElement, into a base class (much more natural than centralizing element-speciffic code into the Message class).

Upvotes: 4

Related Questions