The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

OOP principle

One of the principles is Information Holder(Larman).I follow this rigidly-the class which has data has operations which operate on the data.Now,I find that it leads to fat/large classes.What is a fat class for you? How to avoid it?
jam
Monday, November 06, 2006
 
 
For me, a fat class is one which has too many responsibilities.  OOD is all about normalising behaviour.  Your "normalise" your fat classes by breaking them up by responsibility into smaller classes.

Have you heard of the many other OOD principles?  One of which is the Single Responsibility Principle (SRP), the definition of which is 'A class should have only one reason to change'.

If your fat classes have more than one responsibility, then they have more than one reason to be changed.  You should consider factoring out those responsibilities into smaller, more focussed, classes.

Also, try to limit the interface of a class to the bare minimum required by the class' clients.  Avoid the temptation to add convenience methods.  If a class has multiple clients, try to see if they are using the same functionality or whether they are applying forces that are not cohesive to the class' responsibilities.
sensible Send private email
Monday, November 06, 2006
 
 
> How to avoid it?

Instead of class "A" containing all he data and all the methods, some the data+methods are contained in other classes; instances of these other classes are contained (as members) in "A".
Christopher Wells Send private email
Monday, November 06, 2006
 
 
A guy I work with always talks about 'composition-delegation'.

An option is to have each one of the indivdual data pieces be in their own class (and the logic that just acts on that one data piece), with the parent class describing/managing the interactions between the child classes.
Another Anonymous Coward
Monday, November 06, 2006
 
 
Composition delegation sometimes leads to statements like this ...

a->getContainedB()->methodOfB();

... which is imperfect, but often better than alternatives.
Christopher Wells Send private email
Monday, November 06, 2006
 
 
I think that many people have been misled by early OO adopters to use a fat class to represent an object, with both data and operations on the object. This model does not reflect the real scenario and difficult to manage.

For example, if you are modeling a car, will you add a method Wash() to the class Car? In reality, the car can not wash itself. A better model would be:

void Wash(Car& car);

or

CarWasher.Wash(Car& car);

To reduce the size of a fat class, you can transform the operations which do not belong to the class into independent function or class.
Burner
Monday, November 06, 2006
 
 
Actually I have used composition,my fat class is composed of 6-7 other classes.Now,each of these classes have behavior defined in them, which I have exposed through the parent class(composite class).
jam
Monday, November 06, 2006
 
 
These are good suggestions by sensible..
Avoid the temptation to add convenience methods. 
If a class has multiple clients, try to see if they are using the same functionality or whether they are applying forces that are not cohesive to the class' responsibilities.


What I also do is add methods which give me data to display on a form..get() type
jam
Tuesday, November 07, 2006
 
 
The idea that a class should not have more than N methods, or more than N roperties, is a load of hogwash.

The principle of encapsulation is that a class defines ALL the properties for an object/entity and ALL the methods that may be performed on that object/entity.

So if I have a "customer" entity, the customer class deals with EVERY aspect of a customer.

If you don't like large clases because you don't have the brain capacity to deal with large classes, then AFAIAC breaking it down into smaller classes means adding in unnecessary complexity because you now have to remember which properties and methods are in which classes, and you have several objects to communicate with instead of just one.

Knowing that everything I need for an object exists in a single class is far, far better than having a selection of objects to choose from, because then I would be introducing the possibility of choosing the wrong one.
Tony Marston Send private email
Wednesday, November 08, 2006
 
 
Tony --

"The principle of encapsulation is that a class defines ALL the properties for an object/entity and ALL the methods that may be performed on that object/entity."

That could easily be abused.  Taking it to an extreme, if I look at my requirements and choose to identify the "entity" as "the Program" then I wind up with a big ugly pile of procedural code. 

If I have a Customer class that has gotten big, instead of that just being a limitation on my own brain, it might be a false requirement imposed by my particular point of view.  Tweak my point of view a little, and maybe another entity or two falls out the bottom, greatly simplifying the whole thing.
Notorius L
Wednesday, November 08, 2006
 
 
> That could easily be abused.  Taking it to an extreme, if I look at my requirements and choose to identify the "entity" as "the Program" then I wind up with a big ugly pile of procedural code. <

Any principle can be abused, and it's possible to produce a f*ck up in any language and any paradigm.

Only an idiot would abstract his entire application into a single "entity". That would be as stupid as designing a database with only one table. If you know and understand the principles of normalisation (and you cannot design efficient databases WITHOUT such knowledge) then you will come up with a separate table for each entity, such as "customer", "product" and "invoice". You would certainly NOT design a single table called "sales" which held all of that information in one place.

Having identified different entities in the database design it is then a simple matter to create a separate class for each of those entities. Each class then deals with all of the data on its respective table, and deals with all of the operations (read, write, update, delete).

It's such a simple and straightforward concept I am truly amazed that some people can still f*ck it up.
Tony Marston Send private email
Thursday, November 09, 2006
 
 
I agree with Jam. A class that has clear purpose, consistent design, a well-defined meaning within the contexts of its use, and is a fitting reflection of the domain entity, but is 3000 lines long, is better than a composite structure of fine-grained classes that are absolutely meaningless and only exist to "make files smaller".
Wouter Lievens Send private email
Thursday, November 16, 2006
 
 
I keep thinking of that "kingdom of nouns" article when I think about this.  To me, a "fat class" is simply a class that has more properties and methods than it needs to represent whatever it is representing.  Car.Wash() is a good example- someone or something else is going to wash the car.  Engine.ConsumeFuel(FuelTank& tank) on the other hand makes sense.  The engine consumes the fuel.  The tank gives the fuel to the engine (unless you call FuelTank.Siphon() to create a buffer overflow.  Sorry, dreadful attempt).  The fuel burns.

Engine.ConsumeFuel(), however, makes me think "fat class," because I'd expect inside I'd find

this.FuelTank.getNextFuel().Burn();

which is silly, because the last time I checked engines and fuel tanks were kept separate and the car had all sorts of extra stuff between the two.  So, even though the Engine consumes fuel, it doesn't really need its own FuelTank, because the DashBoard will probably want to have its FuelGauge ask how much is in the FuelTank and doesn't need to be bothering the Engine in the process.

Similarly I've noticed an alarming trend to take the term "atomize" literally... with full classes being instantiated simply to collect related information together but for some reason they couldn't just stick to a struct (yes, structs have their limitations, but I cringe whenever I see classes being instantiated and scores of setFoo() calls and the only other functions in the class are getFoo()).  I'd consider these to be Fat Classes even if they have one member and a get/set pair, because they don't *do* anything.

I guess the "short way" I should have just started with is:

If it has a method that operates on itself as a whole, that needs to go (it inevitably belongs somewhere else, deconstructors excluded).

If it has a method that operates on something else that doesn't involve the use of any of its member properties, that needs to go.

If it just holds data, it needs to be a struct (if it VALIDATES data that's fine, though I tend to prefer to do validation before I get to the simple "hold some info" level).
Ryan Schwab Send private email
Thursday, November 16, 2006
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz