Sign in to follow this  

OO Design Question: Should *everything* be inside a class

This topic is 4732 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi again I have more of a theoretical question this time about OO design, in particular when to make use of classes. At university doing Java, we were always taught when doing OO theory that classes should represent...well, classes of object, where an object was a given instance of that class. Vehicle can be a class, and Truck and Bus can be 2 subclasses inheriting nessesary variables and functions from Vehicle. Thats all fine, but when it came to codeing in Java this definition was somewhat blurred. I always found Java a pain with all these rules it had. In Java everything had to be in a class (and even the source files had to have the same name as a class in them). Even the main function was in a class, ie a class called "Application" for example. All our IO functionality also had to be in a class... To me this never really made sence, that all parts of an application had to be part of a class (this is what we were taught when programming and Java seems to enforce this). OO is supposed to be about real world objects isnt it, ie "bank account" or "monster"...things that have properties (variables) and do actions or have actions done upon them (functions)? Objects that are identical are the same class... Now say if I had a simple C++ game that had a main loop, a keyboard input grabbing function, a function that draws to the screen and some different monsters and a player that run around. The only things here that i would consider should logically be in classes are the monsters (a subclass for each one) and the player, and each of these should perhaps derive from some base class "Actors" for example. I dont see why the input functionality, or the drawing functionality or the mainloop code should be put within a class. Is my design above a bad OO design? Should everything be made a class? I am just starting with C++ and it seems that C++ allows for my type of design above as you can code procceedural C alongside the OO stuff, but Java wanted everything to be put in a class. Sorry for the long post.

Share this post


Link to post
Share on other sites
Unfortunately, introductory C++ courses often don't really get into the *philosophy* of object-oriented programming; in fact, from my experience they mainly just cover the older C-style procedural approach with some object-oriented concepts (such as the class) "tacked on". When this "tacking on" happens, then you're really looking at the object-BASED programming paradigm rather than an object-ORIENTED paradigm.

Remember that OOP has three widely-haralded benefits: encapsulation, inheritance, and polymorphism. The issue at hand is that our main program code only exists as a single entity, and thus it may not make sense to have it all contained in a "time-consuming" class. This argument also applies to ALL classes which will only be defined ONCE -- for instance, our "render engine" will only exist as a single object, as will our "audio engine" and so forth. In C++ terms, these are called "singletons", and they happen to be one of the most well known design patterns!

See http://www.gamedev.net/community/forums/topic.asp?topic_id=165446 for debates on whether the Singleton is a good idea.

But now on to your more specific question: In C++, it turns out that you CAN'T place EVERYTHING in classes. Your main function must always be outside of a class. However, your main function CAN simply be the initialization of a class, hence starting your program from inside a class. This is one way that C++ programs differ from Java ones, and some say that this is one reason why C++ is not as object-oriented. Basically, if our program code is inside a class, then the benefit of encapsulation comes into play.

Theoretically, we can now treat our main program as a black box that we can call on a whim and not really understand what's going on inside. Further, our global variables are no longer global since they are contained inside our program class. From the main() function, you cannot access them. Is this a good thing? In OOP terms, it is. What if all of your programs were like this, in separate classes, and you wanted a main function that would combine them all into one executable and act as a loader? Well, now you can put several "program classes" into one project and it will compile perfectly since everything is so well contained and there aren't naming conflicts! Further, what if you wanted to make two different versions of your program which perhaps only differed in, say, the rendering capabilities. Thus, your render() function was different but everything else is the same. Well, then let's make the render() function virtual, have your main() determine whether your video card supports certain features, then derive a class from your main program class that simply redefines the render() function to not include the new features (perhaps not the best solution in this case, but you can see the benefit).

It really all boils down to preference, since in most situations it doesn't matter all that much. Theoretically, for a great OOP program, everything WILL be bundled into classes since it's much cleaner and gets around global identifier programs. However, in practice you won't run into these problems that often if only a few functions are outside of classes. In the end, it really boils down to what you're happiest with, since you are after all the programmer :-)

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Java is a little quirky in that (as you say) *everything* needs to be inside a class in some way. Thats just a quirk you have to deal with - its often easier if you imagine it as an additional level of namespacing (in addition to packages). Eg. the built-in Math class which is just static sin, cos, etc. methods. All static classes aren't nessisarily a bad thing, so if you have a lot of common IO functions you could easily create an IOUtil class to keep them all in.

However unless you've got lots of simple, primitive, shared operations those methods 'belong' somewhere. If it's IO for loading an image, it belongs associated with a suitable Image class (or better yet, is does via an Image constructor).

Equally, you don't just have "a drawing function", if you've got lots of objects then its not uncommon for them to draw themselves to screen (and some kind of entity manager holds and tells them to draw themselves in the correct order). Typically you want some kind of Map/Level class for that. If you're into your 3d rendering then different requirements typically mean you need a Renderer class instead of others drawing themselves.

Generally the only thing you 'need' to have as non-class is your startup and gameloop ('cos you'll only ever have one of those). But in practice I like to have some kind of App class which you only ever have one object of that handles that. One of the most difficult things I find in designing systems is nailing down the classes that refer to abstract concepts (like 'renderer') rather than the obvious physical objects (like 'monster'), sounds like you're having the same problem.

OT.

Share this post


Link to post
Share on other sites
basically C++ have the concept of "namespace" to be a better model for things which are related but do not share data ... Here are my feelings:

Logic which represents instances and requires instance data: Classes with non-static members and functions

Logic which are NOT instances, but share a single copy of some data (globals basically): Classes with static members and static functions.

Logic which are NOT instances, and does not need to retain any data, but are related in domain or scope: Functions within a common namespace and/or files and/or module.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Xai
basically C++ have the concept of "namespace" to be a better model for things which are related but do not share data ...

No. C++'s namespace is equivilent of Java's packages. Java's additional requirement of everything being associated with a class is another layer below that. It means you get a consistant naming convention for files and the classes and method that they contain.

OT.

Share this post


Link to post
Share on other sites
Don't feel so constrained as to think of "objects" as only solid, conceptual "things". When you really start getting into OOP theory and design, you'll get to know that an object is not a physical representation of a "thing", it's more of an "idea" expressed as an object.

If you read the book "Design Patterns" (which is geared for C++, but usefull for Java as well, i'm sure) you get to see that an object can be anything where you want to encapsulate the data and methods. So yes, IO functions can be an object (and they are, C++' cout and cin being good examples), rendering can use a RenderManager object (or whatever), etc etc. You can even (and should) code a "strategy" as an object. For instance, an enemy agent might have a "strategy" object in it's class description for AI usage. When you call enemy->Think(), it calls strategy->Execute(). If at any time, the enemy wants to change it's AI strategy, it's simply says

delete strategy;
strategy = new SomeOtherKindOfStrategy( params );

"strategy" is not something physical you would see walking down the street, but encapsulating it as an object works *really* slick for this kind of thing.

Share this post


Link to post
Share on other sites
Quote:
Is my design above a bad OO design? Should everything be made a class? I am just starting with C++ and it seems that C++ allows for my type of design above as you can code procceedural C alongside the OO stuff, but Java wanted everything to be put in a class.

You pretty much hit the nail on the head with the C++ comment; C++ allows for a pretty good range of different paradigms, which is one reason it's popular.

As for whether everything should be made a class, the answer to that is obviously no -- but because of individual language strictures, you may not be able to do this. In C#, which is more stringently OO than C++, you're still bound by the all-logic-is-inside-a-class rule, but there's a sensible way to approach this. Classes don't have to just correspond to, as you put it, "real world objects" like a BankAccount. They can also correspond to structural parts of your program -- like a GameEngine, a SocketManager, and so on. The confluence of these structural parts and traditional "real-world objects" then describes the whole of your program.

Share this post


Link to post
Share on other sites
Quote:
Original post by Mr Lane
To me this never really made sence, that all parts of an application had to be part of a class (this is what we were taught when programming and Java seems to enforce this). OO is supposed to be about real world objects isnt it, ie "bank account" or "monster"...things that have properties (variables) and do actions or have actions done upon them (functions)? Objects that are identical are the same class...


Mimicking real-world objects is a horrible way to use classes. It's better to recognize the elements that define OOP, which as mnansgar said, are:
encapsulation (optional, through use of public/private)
inheritance (also optional)
polymorphism (benefit of inheritance)

Don't think so much of real-world objects, but code objects. A code object is a set of methods that operate on some shared data. Then apply OOP constructs where beneficial. Encapsulation is beneficial pretty much everywhere, for various reasons. Inheritance is great when you want to share code between a set of similar code objects, or when you want to use polymorphism.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Quote:
Original post by Xai
basically C++ have the concept of "namespace" to be a better model for things which are related but do not share data ...

No. C++'s namespace is equivilent of Java's packages. Java's additional requirement of everything being associated with a class is another layer below that. It means you get a consistant naming convention for files and the classes and method that they contain.


I disagree about namespaces being the same as packages .. a namespace is a NEVER closed scope, that can be extended by anyone and everyone, much like the way the langauge ruby treats most things, it is a "package" in the abstract sense, but not in the physical deployment sense ... it is for putting related things into - the exact nature of that relationship is completely up to you.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Xai
Quote:
Original post by Anonymous Poster
Quote:
Original post by Xai
basically C++ have the concept of "namespace" to be a better model for things which are related but do not share data ...

No. C++'s namespace is equivilent of Java's packages. Java's additional requirement of everything being associated with a class is another layer below that. It means you get a consistant naming convention for files and the classes and method that they contain.


I disagree about namespaces being the same as packages .. a namespace is a NEVER closed scope, that can be extended by anyone and everyone

If you're going to talk about exact behaviour, then obviously you won't find direct parallels between the two languages. But details aside, they are both intended to perform the same task - to prevent name collisions between unrelated modules of code.

Whether the namespaces are actually better at their job than packages is a totally different issue. :)

OT.

Share this post


Link to post
Share on other sites
To all that posted, thanks for the discussion, it helped a heap. I have realized that my view of what classes should be was perhaps too strict, that they should not nessesarily be limited to real world objects and secondly most people here tend to think that mixing a bit of OO with C is not a bad thing as such cause C++ gives you that freedom, so maybe I was being too strict on myself there as well.

Most important of all i realize now that this is an area of discussion and debate, which means I am not the only one thinking about it.

Its all good, I am doing some C++ now looking at some source code and i think i will get the balance right as i go along.

Once again, thanks for the help.

[Edited by - Mr Lane on January 2, 2005 10:02:36 AM]

Share this post


Link to post
Share on other sites
Mr Lane, very well said. Sometimes though, your objects can reflect real world like objects and sometimes your objects will have no equivalent in real world. You might want to look up embedded C++ programming in how they deal with OOP because they must invent objects a lot. Their problem space is very close to hardware. In C++, you don't have to put everything into a class. You can have helper functions that work on objects. You can put them inside a namespace if you want. You can have globals for faster access if speed is your concern. So instead of passing function params down thru a chain of functions you can bypass it and access a global from the lowest function in the chain. I always say that if we didn't have to worry about efficiency then programming would be lot easier as we could afford less efficient but better designs.

Share this post


Link to post
Share on other sites

This topic is 4732 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this