Object-oriented – How to approach class design in OOPs

designdesign-patternsobject-oriented

When I try to design an OO solution ,I generally use the CRC modelling wherein I list the class names (nouns), what they do(verbs) and how they collaborate with other classes.

This blog has the below thing to say about this noun-verb approach

   ...This approach, which I will call “noun and verb,” is so limited 
   I’ll dare to call it brain damaged....

My question is, does a better modelling technique exist to use OO approach?

Best Answer

In fairness, he did add "In fun" to that claim.

To this day, I do tend to start by modeling systems using the "noun and verb" approach, but I have found over the years that TDD teaches us that this approach draws your focus to the wrong thing. In this sense, the blogger has a point. However, I'm not sure that it is the approach at fault, rather than the way our minds work.

If you want to try a little challenge here, stop reading and go try to model the Monopoly game, using the English language, then come back here.

I suspect the temptation will be to immediately look at the objects that we interact with a lot - the board, the spaces, the cards, the dice, the pieces - but that is not where the bulk of the logic goes. Most of these objects are entirely dumb. Data, if you will.

But as soon as you start to write tests, you realise which object is by far the most important in any game: the rules.

Remember that little piece of paper that you read once when you first got the game and don't interact with again until there is a dispute? The computerised version does not operate that way. Every single thing the player tries to do, a computer will consult the rules and see if they're allowed to do it or not.

When you think about it, you do the same thing but because it takes time to read the paper-based rules and your brain has a reasonable caching system, you consult the rules in your head. A computer is probably going to find it as easy to read the rules again - unless they're stored in the database, in which case it might cache them too.

And this is why TDD is so popular for actually driving design. Because it tends to drive your thought process quickly to the right places:

When I think that I'm going to write some tests for my Monopoly game. I might look at my set and try to find the objects. So, we've got these pieces. I'll write some tests for those.

Maybe I'll have a base class MonopolyPiece and each type of piece will derive from those. I'll start with the DogPiece. First test... ahh. Actually, there is no logic here. Yes, each piece will be drawn differently, so I might need a DogDrawer, but while I'm fleshing out the game, I just want to write "D" on the screen. I'll spice up the UI at the end.

Let's find some actual logic to test. There are a lot of these houses and hotels, but they don't need tests. Money, no. Property cards, no. And so on. Even the board is nothing but a state machine, it doesn't contain any logic.

You'll quickly find you have three things left in your hand. The Chance and Community Chest cards, a pair of dice and a set of rules. These will be the important parts to design and test.

Did you see that coming when you wrote out the nouns and verbs?

There is, in fact, a great example in Robert Martin's Agile Principles Patterns and Practices where they try to flesh out a Bowling Score Card app using TDD and find all sorts of things they thought were obvious classes just weren't worth bothering with.

Related Topic