Jump to content
  • Advertisement
Sign in to follow this  
antareus

On the merits of smaller objects

This topic is 5044 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

Lets get introspective. If I look back on my long (ha ha) programming career, and more specifically, my OO programming career, we can see a few trends: * I'll use classes, but typically only obvious ones that are directly applicable to a domain (e.g. in a game I'd have an Entity class, an Item class, etc) * RAII and other 'secondary' classes are employed if necessary, but usually only when dealing with a resource * Classes are typically used at the high level of the system as contracts. Within each component it breaks down into procedural programming pretty quickly. It occured to me the other day that perhaps I'm really still skimming the surface of what OO can do. Now I could just be an OO fanboy, but I feel that I could increase the readability of some of my code by introducing smaller objects to ease understanding and testing. Whereas normally you'd have one object that contains everything (and still does one thing, but this one thing could be complicated, such as managing a server connection with a protocol). I've had good success with abstracting the tedium of I/O throughout my app because I am a very lazy person when it comes to working with that sort of thing. I see it as a growth step in terms of OO modeling, but oftentimes it isn't apparent until all the code has already been written. Any thoughts on the matter are appreciated.

Share this post


Link to post
Share on other sites
Advertisement
I think the issue here is that of coupling. Smaller objects increase it and larger objects decrease it. Libs are mostly decoupled which fit C++ well. High coupling among objects leads to more maintenance. It then almost feels like passing data around the system which is what C is all about. So if we want to lower coupling and have less maintenance we should embrace large objects that play many roles. That's my take on things right now.

Share this post


Link to post
Share on other sites
Coupling largely depends on how the small objects are instantiated. Are they instantiated directly inside the owning classes? If so, the owning class is coupled to the class names of the class objects it owns.

There are ways to avoid coupling classes through conditional compilation and templates. The object factory and abstract factory patterns help quite a bit.

Using larger objects doesn't decrease maintenance. You maintain roughly the same amount of procedural code, minus the invocations on the small objects. IMO it's silly to avoid using small objects in situations where they might simplify the code just because it would introduce class name coupling. A car needs an engine; so what if it knows it needs an engine?

Small classes also offer better opportunities for re-use. A small string class will be more useful in many more situations than a large class that may serialize game objects, for example. That's good code re-use.

Building slightly larger components out of the small objects is a trial and error, however... it seems good classes composed of great small classes have to evolve to prove their worth in multiple situations. Thank dog for refactoring! [smile]

[EDIT TO ADD]

Also, when refactoring a large class, think about responsibilities. Well-defined responsibilities will tend to coalesce into separate lists that abstract very nicely. What you'll end up with (if you structure those responsibilities right) is a small list of classes -- some of which delegate to smaller classes... and small classes with well-defined responsibilities.

Much easier to maintain (IMO) because errors will tend to be isolated in smaller sets of code (smaller classes). If you get 15 small classes out of 1 large class, for example... maybe 12 of them delegate and three do all the real work. Much easier (IMO)

Share this post


Link to post
Share on other sites
As with anything, there's a tradeoff. Too large, complication results. Too small, procedural-like code results.

The temptation is to make everything a class. The old adages are 'give a class a single, well defined responsibility' and 'do as the builtins do,' which suggest low-cost/low-functionality pieces, but as we know, this increases the required member functions/operators sigificantly.

IMHO, there is no single true answer, though my experience would suggest several 'medium' sized coop types that are implemented in terms of builtins and types that behave as buitins [I'd go as far as saying vector behaves as a builtin, since it has little abstract functionality].

Share this post


Link to post
Share on other sites
Large, monolithic objects that attempt to perform many different task leads to the "God class" syndrome and is considered bad design. Each class should represent one abstraction. If you attempt to jam several disparate responsibilities into one class, it loses coherency.

Share this post


Link to post
Share on other sites
Quote:
Too small, procedural-like code results.

And this is bad why?

"OO" does not mean "easy to maintain". "Procedural" does not mean "hard to maintain".

Most OO code is in any case procedural. "OO" and "procedural" are not opposed; "procedural" is just a consequence of using an imperative language; imperative languages are concerned with performing a sequence of operations in a particular order; the use of objects does not alter this.

Share this post


Link to post
Share on other sites
I think he means that when you pull data out of an object and pass it around then all those places that touch it have to be fixed when that data changes. I rather have only one place I need to change the data and that's in the class that contains it. Same thing that abstract interfaces try to achieve.

Share this post


Link to post
Share on other sites
Quote:
Original post by DrPizza
Most OO code is in any case procedural.

The underlying implementation may be, but the end user usage is somewhat more abstract.
Quote:
Original post by DrPizza
"OO" and "procedural" are not opposed;

The methodologies are quite distinct.
Quote:
Original post by DrPizza
"procedural" is just a consequence of using an imperative language; imperative languages are concerned with performing a sequence of operations in a particular order; the use of objects does not alter this.

The most common langauge, C++, enforces no such restrictions [on how operations are organised]. This is entirely up to the programmer.

Share this post


Link to post
Share on other sites
I'm not sure a better use of OO is really important when it comes to readability. The major point of OO is more maintenance than readibiliy - since the later is more easily achieved by good coding convention.

For the big object vs. small object debate, my preference goes to objects that deals with something particular :) If they want to be big (because their field of expertise is rather large) then it's ok for me as long as it do not break the basic OOP rules. A good design do not say wether objects should be big or not.

My 2 euro cents again :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!