tags:

views:

210

answers:

6

Say you want to write a Tetris clone, and you just started planning.

How do you decide what should be a class? Do you make individual blocks a class or just the different block-types?

I'm asking this because I often find myself writing either too many classes, or writing too few classes.

+4  A: 

You might want to check out How do you design object oriented projects?. The accepted solution is a good start. I would also pick up a design patterns book as well.

SwDevMan81
A: 

(this is posted as a comment) could you give some examples of the classes that you're writing? (list the classes would probably be fine ...)

aggietech
why the down vote?
aggietech
aggietech, you were probably downvoted because a comment should be added as a comment to the question, not as an answer as you have done.
MagicAndi
but i can't add comments yet, that's why i added the clarification at the beginning ... thanks though.
aggietech
@aggietech: Adding a clarification does not change the fact that you posted an answer that was not a real answer. It only takes 50 rep to post a comment - get 1 more up-vote from providing a real answer and you're there. (Note - I'm not the downvoter, but I agree with whomever voted)
Aaronaught
A: 

Depends on your development methodology.

Assuming you do agile, then you can start with writing the classes you think you'll need. And then as you start filling in the implementation, you'll discover that some classes are obsolete or others need to be split out.

Assuming a more design-first-then-build approach (dsdm/rup/waterfall...), then you'd want to go for a design based on the "user story", see SwDevMan81's link for an example.

taoufik
+1  A: 

For a Tetris clone you're going to be better off I'd say creating a block class and using an enum or similar to record what shape piece it is. The reason is that all blocks act in the same way - they fall, they react to user input by rotating or falling faster, and they use collision detection to determine when to stop falling and trigger the next piece.

If you have a class per block-type then there'd be so little difference between each class that it would be a waste of time.

In another situation where you have a lot of similar concepts (like many different types of animals etc.) it might make mroe sense to have a class per sub-type, all inheriting from a parent class if the sub-types were more different from each other

Mark Pim
A: 

I would make a base-class Piece, because they each have similar functionality like move right, move left, move down, rotate CW, rotate CCW, color, position, and the list goes on. Then each piece should be a sub class like ZPiece, LPiece, SquarePiece, IPiece, BackwardsLPiece, etc... You probably do have many classes, but there are many different types of pieces.

The point of OOP you are asking about is inheritence. You don't want to reinvent the wheel when it comes to some functions like move left/right/down, nor do you want to repeat exact code in multiple locations. Those functions shouldn't change depending on the piece so put it in the base class. Each piece rotates differently, but it is in the base class because each class should implement it's own version of it.

Basically, anything all pieces have in common should be in a base class. Then everything that makes a piece unique should be in the class itself. Yes, I think making a block class and each piece has 4 of them is a bit much, but there are those that would disagree with me.

Steve H.
+9  A: 

Take a step back.

I suspect that you're putting the cart before the horse here. OOP isn't a Good Thing in its own right, it's a technique for effectively solving problems. Problems like: "I have a large multiple-team organization of programmers with diverse skill sets and expertise. We are building large-scale complex software where many subsystems interact with each other. We have a limited budget."

OOP is good for this problem space because it emphasizes abstraction, encapsulation, polymorphism and inheritance. Each of those works well in the many-teams-writing-large-software space. Abstraction allows one team to use the work of another without having to understand the implementation details, thereby lowering the communication cost. Encapsulation allows one team to know that they can make changes to their internal structures to make them better without worrying about the costs of impacting another team. Polymorphism lowers the cost of using many different implementations of a given abstraction, depending on the current need. Inheritance allows one team to build upon the work of another, cleanly re-using existing code rather than spending time and money re-inventing it.

All of these things are good not in of themselves, but because they lower costs in large-team-complex-software scenarios.

Do they lower costs in one-guy-trivial-software scenarios? I don't think they do; I think they raise costs. The point of inheritance is to save time through code re-use; if you spend more time messing around with getting the perfect inheritance hierarchy than the time you save through code re-use, it's not a net win, it's a net loss. Similarly with all the others: if you don't have many different implementations of the same thing then spending time on polymorphism is a loss. If you don't have anyone who is going to consume your abstraction, or anyone from whom you need to protect your internal state, then abstraction and encapsulation are costs with no associated benefits.

If what you want to do is write Tetris in an OO style for practice writing in that style, by all means go right ahead and don't let me stop you. I'm just saying: don't feel that you have a moral requirement to use OOP to solve a problem that OOP is not well-suited to solve; OOP is not the be-all-and-end-all of software development styles.

Eric Lippert
There's also a maintenance thing going on here though. IMHO a well designed system using good OOP fundamentals is often easier to maintain - this applies equally from a one man shop to a large company.
Paddy
@Paddy: an excellent point. OOP is also good for code that will be maintained and changed over a long lifetime and many versions. If your code is trivial throwaway code that you're going to use for minutes, days, weeks or months, and then toss it and never use it again for anything then again, OOP adds cost without a accruing a related benefit.
Eric Lippert