tags:

views:

269

answers:

12

If I`m programming a game in which there is a worker that cuts wood (from trees), where would I put the "cutWood" method, in the worker class, or the tree class?

EDIT: The first example I read on OOD was about a circle (a class called circle) which has in it a method called "calculate area". Now, sure enough a circle doesn't calculate its own area. The only way to think of it is that calculating area is an operation that is relevant to the circle (an operation done on the circle)

So, cutWood method is relevant to both, the worker, and the tree.

+4  A: 

Ask yourself: Do workers cut wood, or do trees cut wood?

codelark
But the tree's get cut, it could be CutMe(Worker whichWorker), which could tell if the tree had enough wood to be cut. - But yes, the worker should cut the tree
PostMan
If the tree's internal state needs to know about who cut it, and whether or not it's been cut, then the Workers cutTree method would call whatever methods the Tree exposes to update its state.
codelark
And does Worker extend WoodChuck, or vice versa? :p
Rodney Gitzel
+4  A: 

You basically answered it in your question: "a worker that cuts wood". You should put it to the worker class.

dark_charlie
What if later you want the worker to also go to work, bake bread, fix cars, smoke pot, whatever. That worker is gonna turn into a god object.
Mark H
@Mark H: I don't quite understand you here. A god object is an object that has too much responsibility. This wood worker will never fix cars or bake bread. The worker will probably have more methods, for example takePause(), but as long as these are related to the worker's primary objective, there's no problem with that.
dark_charlie
You've made the assumption that the worker will never fix cars, but you don't know that - or you don't know if it will change in future. If the responsibility of the worker changes, it'll be bloating his object. However, no matter if the responsibility of a worker changes, cutting a tree will always act on a tree - and should therefore be part of the tree. There's really not much chance of a tree changing responsibilities anyway.
Mark H
An object should not change its responsibilities, that's violating of the good OOP principles. The object design should be logical and straightforward and a tree cutting itself sounds neither logical nor straightforward to me.
dark_charlie
@Mark H: If we're going to think at that level, wouldn't it be best for the worker to have a single method `doWork()`, which takes an IWorkable object, which exposes a single `work()` method, which then calls the internals required to do that work? I mean, if we're going to be concerned with that level of extensibility, we should take it to its logical conclusion.
EricBoersma
A: 

Since a single worker might cut more than one tree, it sounds more likely that you'd want to put cutWood() in the worker class.

Greg Hewgill
+3  A: 

Create a

cut(Material m)

method for the worker for extra object-orientedness.

Hans
Unless the worker ever cuts something else, this would be a good example of over-abstraction ;-)
codelark
//TODO: insert EmoWorker joke
STW
@codelark If the description said lumberjack, I agree, but a worker can mean anything /sarcasm
Hans
@STW, remember: across the grain, not with the grain....
Bob Cross
+1  A: 

You could have a cutWood method in the worker class, and a cutted method in the tree class. Obviously, worker.cutWood calls tree.cutted, which might return the amount of wood harvested. tree.cutted would do all the stuff that is necessary to let the tree die.

If you consider method calls as "messages sent from one object to another", it makes a lot more sense to say "the player sends a 'cut wood' message to the worker who in turn sends a 'cut' message to the tree".

ammoQ
+2  A: 

do you have to modify the tree as it is being cut?

do you have to modify the worker as it cuts a tree?

i would imagine you'd end up with a WoodCutting service which handles the event possibly modifications to both, or in turn calling worker.cutWood() AND tree.woodCut()

ahah what a question ;)

pstanton
+4  A: 

I don't see any cohesion to have a wood cutting method in the worker. The cutting is done on the tree, and should therefore be part of the tree class. Presumably, cutting the wood will also involve changing some internal state of the wood class too.

A worker should call the cut method on whatever tree he wants, rather than the tree telling the worker that he should cut it. If you want to abstract this like Hans has hinted at, you could make an ICuttable interface for the Cut method, and have your tree implement it.

Consider something you're familiar with, a String. When you want to cut a string (split), you don't define a splitString method in every object which is going to do this. Whatever object decides to split the string, the same thing takes place - and will usually need to know the internals of the target object (the string) in order to do it. Many other objects simply call the split method of the string. The string object has high cohesion - because it's methods contribute to a common task - manipulating strings.

I don't see how cutting wood contributes much to the worker object itself.

Mark H
A: 

Doesn't the cut() method go on the Saw object?

More seriously, I think of the target of the method call as the "subject", the method itself as a "verb", and its parameters (if the verb is transitive) as "direct objects." So, in this example, it would be worker.cut(tree).

erickson
+2  A: 

Sounds like a candidate for the Strategy pattern to me. You may need a WorkerAction abstract class with a performAction method. Then subclasses of the WorkerAction class will implement the details such as cutting a tree, digging for gold and other worker actions. So the sub class knows about the details of the tree and can call the necessary methods on the tree to affect the tree as it is being cut.

The worker class then only need a reference to an instance of a concrete WorkerAction on which it calls performAction(). The worker does not know the details of the Tree or the Gold etc. This way the worker can perform the action but you are not limiting the worker to only one action. In fact you no longer need to modify the worker class if you want your worker to do more actions in the future.

Vincent Ramdhanie
I agree this is the approach to use - but my opinion would differ for the responsibilities of subclasses of WorkerAction. Say given a TreeCuttingAction class, I would simply have it's performAction method call a .cut method of the tree (for reasons given in my above answer) - the TreeCuttingAction doesn't necessarily know the details of the tree he is cutting - only that he is cutting it.
Mark H
@Mark H Hmm. Sounds like I just pushed the decision into a different level of abstraction here without actually answering the question. I think though that I agree with your answer that the details of cutting the tree should reside in the Tree. So yes. The performAction should only call cut() on the Tree.
Vincent Ramdhanie
A: 

This question can only really be answered if you explain what cutWood does.

If cutWood only affects the state of a Tree then it belongs in Tree e.g.,

public void cutWood() {
    this.height = 0;
}

In the case of calculateArea you only need the radius of a circle (assume pi is constant) to do this calculation - nothing else. That's why it belongs in Circle.

Stop trying to model the real world too closely and look at what your method actually needs to do.

rojoca
A: 

Object design is all about assigning responsibilities to your classes. That means there really is no good answer to this question. As it all depends how you model the responsibilities in your design. (see: Larman)

Thus you need to decide what object/class is responsible for what. This will lead you to correct answers on question about were to place what kind of methods.

Thus ask you’re selves questions like: does the worker decide on his own to cut wood? If he does, he probably does not need to be ordered so, thus he will not have a need for a method cut(tree). But if the user can order him to do that, he will need a cut(tree) method. An other example: does the tree have to know he is cut? Well, if a cut tree just leads to his removal from the forrest, he might not have a need for such a tree.cut() method. But if you assign to the tree the responsibility to (re)draw himself during cutting, you might have a need for a tree.cut() method. The tree could even be modeled as having a width and that he can calculate how many cuts are needed before he collapses.

Kdeveloper
A: 

This is an intresting topic. I thought about a likewise scenario myself sometimes. I think a good way to go, is to put the method into the class with the highest cohesion. Therefore the Tree class would be the first choice. On the otherhand if you try to match a real world model i would say the Worker class has to be able to perform some kind of actions which includes cutting a Tree. I often find myself in these kind of situations and wonder where is the right place to put this method. Another approach would be a class which knows about worker and tree's, and therefore handles the cutting tree meachnism. This way both classes (tree,worker) would not know anything about it.

kukudas