tags:

views:

89

answers:

8
+1  Q: 

A question on APIs

Recently I have learnt of the many benefits (including beautiful looking code) of OOP.

So, now I am trying to write a small physics API for my personal use, perhaps to be put in a few little games. This is mainly because I like to practice coding, and I like my physics.

But the thing is, many APIs have an interface like this (including the Windows API):

// In this case, Object is just a plain data container without a constructor.
Object object = NewObject(...);
DoSomething(object);
DoAnotherThing(object,...);
 ... and so on

Is this how APIs should be arranged, or is there are more OO-style way of things, like:

Object object(...);
object.DoSomething(...);
object.DoAnother(otherObj,...);
otherObject.attachNode(object);
 ... and so on again

I hope you get the idea. So, to summarise by question, which method is more prefered, and why is it that I see a lot of the first example despite the glorification of OOP (though perhaps these APIs in reference are just old, like the Windows API).

As a side note, what do you think of the Windows API? To me it seems just a bit... not right.

+1  A: 

I think this is a highly subjective topic.

While I tend to prefer the object.DoSomething() style, I see nothing wrong with the other way. I would even say that sometimes, it makes more sense.

I believe what really matters is that your API remains consistent.

Usually, when the selected style is not adequate, you notice it because some things seem wrong.

ereOn
+1  A: 

It depends on whether you expect the API to work with OO and non-OO code. Your example, the Windows API, was designed to work with non-OO code primarily (at least, initially). So if you are sure that your users are using only OO languages (especially if it's just for your own projects), just stick with whatever is natural for the language you're working with. So for C++, I'd go with the second option and use the language's features to their fullest potential.

Ivo
A: 

The former system is C-like. The latter is the OO way of doing things.

Goz
A: 

If you're not bound with some performance constraints, use object methods. In this case, choice of methods is limited, and in C-style you have all possible methods to choose from. Human memory is limited, so divide everything in small (and testable!) parts.

alxx
Why would performance constaints prevent you from using member functions?
jalf
Well, some people are still picky about virtual function calls.
alxx
+4  A: 

An API can look any way you want it to. If you want to make a C++ API, then you can use member functions as much as you like. With the Win32 API, Microsoft had to make something that was accessible from C (and a variety of other languages) as well as C++, so they had to express everything using features that are universally accessible. That means they couldn't use classes (or by extension, member functions), namespaces, overloading, templates and a variety of other C++ features.

They then took that pretty reasonable premise, and built the ugliest, most inconsistent API imaginable.

If your API is intended to be used from C++ code, then you can use all the C++ features you like.

On a side note, even in C++, making everything a member function isn't necessarily preferable. Using non-member functions by default can be a very good idea, even in object-oriented code, although the reasons are different than the ones Microsoft had for it in their API.

jalf
Sounds like a good answer to me. Perhaps their API reflects their programmers? In that case, perhaps the Windows programmers aren't really these gods of the PC world...
Alexander Rafferty
I don't think anyone ever accused Windows programmers of being gods. But they do have some very good programmers. There are a lot of reasons why the Windows API is as horrible as it is, but I don't think the quality of their programmers as a whole is one of them.
jalf
+2  A: 

One of the pillars of object oriented programming is encapsulation. As little code as possible should be dependent on the internals of an object, because those internals could potentially change. Member functions can access those internals, non-member (non-friend) functions cannot.

This means that do_something(object) is actually more OO than object.do_something(), and a lot of OO officionados don't seem to get that at all.

Of course this is an oversimplification. If you need dynamic dispatch, you have to use member functions. See Item 23 in Effective C++ or click on How Non-Member Functions Improve Encapsulation for details.

FredOverflow
+1  A: 

This document might not be a 100% fit to the question but nevertheless closely related. Scott Meyers discusses both styles mentioned in the question. Scott Meyers: How Non-Member Functions Improve Encapsulation

thorsten
Sorry FredOverflow for double posting the Scott Meyers link. I've been busy searching the URL while you posted your answer :-(
thorsten
A: 

You should not confuse spelling with design.

object.Foo() is just a way of spelling that says you're calling the Foo method on object. Another OO language could use the spelling CallMethod(object, Foo) to mean exactly the same. Or it could use the Foo(object) syntax.

Now the Windows API is an API that's intended to be used by OO and non-OO languages alike. You appear to be using the C binding of the Windows API, the binding that you get from #include <windows.h>. C is not OO at all. Therefore windows.h doesn't seem like an OO API from a C++ perspective.

MSalters