Object Oriented Design problem - oop

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.

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.

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

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

Create a
cut(Material m)
method for the worker for extra object-orientedness.

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 ;)

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.

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".

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.

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.

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).

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.

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.

Related

What are the drawbacks of encapsulating arguments for different cases in one object?

I'll give you an example about path finding. When you wnat to find a path, you can pick a final destination, a initial position and find the fastest way between the two, or you can just define the first position, and let the algorithm show every path you can finish, or you may want to mock this for a test and just say the final destination and assume you "teleport" to there, and so on. It's clear that the function is the same: finding a path. But the arguments may vary between implementations. I've searched a lot and found a lot of solutions: getting rid of the interface, putting all the arguments as fields in the implementation, using the visitor pattern...
But I'd like to know from you guys what is the drawback of putting every possible argument (not state) in one object (let's call it MovePreferences) and letting every implementation take what it needs. Sure, may you need another implementation that takes as argument that you didn't expect, you will need to change the MovePreferences, but it don't sound too bad, since you will only add methods to it, not refactor any existing method. Even though this MovePreferences is not an object of my domain, I'm still tempted to do it. What do you think?
(If you have a better solution to this problem, feel free to add it to your answer.)
The question you are asking is really why have interfaces at all, no, why have any concept of context short of 'whatever I need?' I think the answers to that are pretty straightforward: programming with shared global state is easy for you, the programmer, and quickly turns into a vortex for everyone else once they have to coalesce different features, for different customers, render enhancements, etc.
Now the far other end of the spectrum is the DbC argument: every single interface must be a highly constrained contract that not only keeps the knowledge exchanged to an absolute minimum, but makes the possibility of mayhem minimal.
Frankly, this is one of the reasons why dependency injection can quickly turn into a mess: as soon as design issues like this come up, people just start injecting more 'objects,' often to get access to just one property, whose scope might not be the same as the scope of the present operation. [Different kind of nightmare.]
Unfortunately, there's almost no information in your question. Do I think it would be possible to correctly model the notion of a Route? Sure. That doesn't sound very challenging. Here are a few ideas:
Make a class called Route that has starting and ending points. Then a collection of Traversals. The idea here would be that a Route could completely ignore the notion of how someone got from point a to point b, where traversal could contain information about roads, traffic, closures, whatever. Then your mocked case could just have no Traversals inside.
Another option would be to make Route a Composite so that each trip is then seen as the stringing together of various segments. That's the way routes are usually presented: go 2 miles on 2 South, exit, go 3 miles east on Santa Monica Boulevard, etc. In this scenario, you could just have Routes that have no children.
Finally, you will probably need a creational pattern. Perhaps a Builder. That simplifies mocking things too because you can just make a mock builder and have it construct Routes that consist of whatever you need.
The other advantage of combining the Composite and Builder is that you could make a builder that can build a new Route from an existing one by trying to improve only the troubling subsegments, e.g. it got traffic information that the 2S was slow, it could just replace that one segment and present its new route.
Consider an example,
Say if 5 arguments are encapsulated in an object and passed on to 3 methods.
If the object undergoes change in structure, then we need to run test cases for all the 3 methods. Instead if the method accepts only the arguments they need, they need not be tested.
Only problem I see out of this is Increase in Testing Efforts
Secondly you will naturally violate Single Responsibility Principle(SRP) if you pass more arguments than what the method actually needs.

Object-oriented Programming - need your help

I try to realize a little game project to dive deeper into OO programming (winforms c++/cli).
I already started coding but now I´d like to make a re-design.
For the beginning the game should consist of four parts like game-engine, user interface, highscore and playground. Heres a little (non-UML-conform) class diagramm to visualize my purposes
Would this be the right way?
In my eyes the game engine is responsible to control the game sequences (state machine?) and exchanges information betweens all other classes.
I appreciate any help!
EDIT:
so it´s a really simple game, no big deal! here´s a link of what I made by now:
http://www.file-upload.net/download-2595287/conways_project.exe.html
(no virus :) but I guess you need .NET framwork to get it work)
Unfortunately, your current design sucks :)
I won't say what I will suggest is actually the best solution available, because in game design there is generally "no best" solution, but still I think it would make you think appropriately.
Larger UML here.
alt text http://yuml.me/1924128b
Let's say you have your basic class Game. It's something abstract class, that wraps all your game logics and works as a sort of Swiss knife.
You should create two another classes - UI and State (which, obviously, encapsulate game UI operations and store current game state). Let your Game class hold UI and State instances.
Now, your Game class should have basic methods to control your game. They could be plain render(...) and update(...) methods and this part is actually a bit tricky. If your game is real-time, you would have to update your state every Y milliseconds, so your update(...) should be called in a loop.
If your game isn't actually real-time, your updates should happen only when user does something or you actually know that you need to change something. You could implement a message queue here and update(...) call would simply flush all those messages.
Now, the render(...) method. Create some class and call it Backend - let this class encapsulate all your drawing possibilities. There is one really cool thing here - you could let your Backend be an abstract superclass and create some concrete backends, which derive from Backend. And that would actually give you an opportunity to switch your Backends with simple code manipulations.
After that, you should pass your Backend instance to your render(...) method, which would do appropriate drawing and it's logic could be written the following way:
foreach (const Object& object, game_state) {
object->render(backend); // Or something like that
}
The last thing to mention, your game state. You could have a plain structure to hold all your current objects, score, etc, etc. Let every object access that GameState structure and everything will be fine.
Actually, there are many things to think about, if you wish to, I could write more about this game design approach and share some tricks :)
Your 'Game Engine' would probably be considered more of a 'Math Library.' You might want to insert another object in between 'Game' and the other Server Classes that 'Delegates' the requirements of 'Game' to the Server Classes and call that 'Game Engine'.
Also maybe 'High Score' and 'Playground' could be combined into a Class which represents 'Game State' and port that directly to 'Game.' 'Playground' could be a Server Class which encapsulates any code to do the actual presenting of said background where this would usually represent a 'Rendering Class.'
IMHO

Singleton pattern - doubt in Head First Design Patterns book

On page 175, there is an example of Chocolate Boiler class. Something like this:
public class ChocolateBoiler {
private boolean empty;
private boolean boiled;
public ChocolateBoiler {
empty = true;
boiled = false;
}
// and then three methods to fill, drain and boil which changes the
// status of these two flag depending of situation
}
In section "brain power" they ask a question "How might things go wrong if more than one instance of ChocolateBoiler is created in an application?"
I'm not sure what's the problem with this class. Why do we introduce a singleton pattern here? These two flags are not static and so one per instance. So how creating more than one instance can mess things up?
The question isn't about making an instance of an object.
It's about the confusion caused by having two instances of the object, both of which purport to have the status of the ChocolateBoiler.
If some Object (for example, Cooker) thinks it has the status of the ChocolateBoiler, and some other Object (for example, Recipe) things it has the status of the ChocolateBoiler, what happens now?
Since the variables are instance variables, the ChocolateBoiler objects won't agree on the status of the ChocolateBoiler. Now what happens?
It's only a problem if there only can be one ChocolateBoiler, and if there only can be one, it should be a singleton.
I believe in that example you only had only ONE Chocolate boiler. And so you should only be able to create one instance of the object representing it. If you were allowed to create multiple instances, you would then perhaps issue the command if (boiler.hotEnough()) boiler.stop() somewhere in you system and would be surprised that although the boiler is already way too hot, it's not stopping because you are talking to some 'dead' instance of a Boiler, which returns hotEnough() : false.
Using the singleton pattern you are making sure that no matter where in your code you say Boiler.getInstance() you will get the one and only boiler object there is, and that when you then talk to it, it will do as you would expect.
The entire example of the chocolateboiler in a singleton bothered me a lot while I was reading it.
On a really fundamental level, I don't see why its necessary when you only have one physical thing, to enforce that fact in software. What happens if you get another one? what are you going to do, add the second to the same singleton? make 2 different singletons? a simple global variable would do the job.
IMO, its not the boiler itself that you can only have one thing of , its access to that particular boiler's controls. You can't allow a second person to start making a new batch of chocolate while its already in that process for someone else, or even allow the same person to make a second batch before the first is finished. From that point of view, a simple queueing or batch processing system would do the job. Using another pattern from the book, the command pattern would be a much better way of handling it , as there's only one waitress , and all new orders get queued up until the cook's done with the current food order. (er, if you haven't seen the book, what I just said might not make much sense, sorry)
Maybe I'm just not getting the point. I haven't done much OOP or anything with design patterns before, and I'm losing job opportunities because of it, so I'm reading up on it.

Passing object references needlessly through a middleman

I often find myself needing reference to an object that is several objects away, or so it seems. The options I see are passing a reference through a middle-man or just making something available statically. I understand the danger of global scope, but passing a reference through an object that does nothing with it feels ridiculous. I'm okay with a little bit passing around, I suppose. I suspect there's a line to be drawn somewhere.
Does anyone have insight on where to draw this line?
Or a good way to deal with the problem of distributing references amongst dependent objects?
Use the Law of Demeter (with moderation and good taste, not dogmatically). If you're coding a.b.c.d.e, something IS wrong -- you've nailed forevermore the implementation of a to have a b which has a c which... EEP!-) One or at the most two dots is the maximum you should be using. But the alternative is NOT to plump things into globals (and ensure thread-unsafe, buggy, hard-to-maintain code!), it is to have each object "surface" those characteristics it is designed to maintain as part of its interface to clients going forward, instead of just letting poor clients go through such undending chains of nested refs!
This smells of an abstraction that may need some improvement. You seem to be violating the Law of Demeter.
In some cases a global isn't too bad.
Consider, you're probably programming against an operating system's API. That's full of globals, you can probably access a file or the registry, write to the console. Look up a window handle. You can do loads of stuff to access state that is global across the whole computer, or even across the internet... and you don't have to pass a single reference to your class to access it. All this stuff is global if you access the OS's API.
So, when you consider the number of global things that often exist, a global in your own program probably isn't as bad as many people try and make out and scream about.
However, if you want to have very nice OO code that is all unit testable, I suppose you should be writing wrapper classes around any access to globals whether they come from the OS, or are declared yourself to encapsulate them. This means you class that uses this global state can get references to the wrappers, and they could be replaced with fakes.
Hmm, anyway. I'm not quite sure what advice I'm trying to give here, other than say, structuring code is all a balance! And, how to do it for your particular problem depends on your preferences, preferences of people who will use the code, how you're feeling on the day on the academic to pragmatic scale, how big the code base is, how safety critical the system is and how far off the deadline for completion is.
I believe your question is revealing something about your classes. Maybe the responsibilities could be improved ? Maybe moving some code would solve problems ?
Tell, don't ask.
That's how it was explained to me. There is a natural tendency to call classes to obtain some data. Taken too far, asking too much, typically leads to heavy "getter sequences". But there is another way. I must admit it is not easy to find, but improves gradually in a specific code and in the coder's habits.
Class A wants to perform a calculation, and asks B's data. Sometimes, it is appropriate that A tells B to do the job, possibly passing some parameters. This could replace B's "getName()", used by A to check the validity of the name, by an "isValid()" method on B.
"Asking" has been replaced by "telling" (calling a method that executes the computation).
For me, this is the question I ask myself when I find too many getter calls. Gradually, the methods encounter their place in the correct object, and everything gets a bit simpler, I have less getters and less call to them. I have less code, and it provides more semantic, a better alignment with the functional requirement.
Move the data around
There are other cases where I move some data. For example, if a field moves two objects up, the length of the "getter chain" is reduced by two.
I believe nobody can find the correct model at first.
I first think about it (using hand-written diagrams is quick and a big help), then code it, then think again facing the real thing... Then I code the rest, and any smells I feel in the code, I think again...
Split and merge objects
If a method on A needs data from C, with B as a middle man, I can try if A and C would have some in common. Possibly, A or a part of A could become C (possible splitting of A, merging of A and C) ...
However, there are cases where I keep the getters of course.
But it's less likely a long chain will be created.
A long chain will probably get broken by one of the techniques above.
I have three patterns for this:
Pass the necessary reference to the object's constructor -- the reference can then be stored as a data member of the object, and doesn't need to be passed again; this implies that the object's factory has the necessary reference. For example, when I'm creating a DOM, I pass the element name to the DOM node when I construct the DOM node.
Let things remember their parent, and get references to properties via their parent; this implies that the parent or ancestor has the necessary property. For example, when I'm creating a DOM, there are various things which are stored as properties of the top-level DomDocument ancestor, and its child nodes can access those properties via the reference which each one has to its parent.
Put all the different things which are passed around as references into a single class, and then pass around just that one class instance as the only thing that's passed around. For example, there are many properties required to render a DOM (e.g. the GDI graphics handle, the viewport coordinates, callback events, etc.) ... I put all of these things into a single 'Context' instance which is passed as the only parameter to the methods of the DOM nodes to be rendered, and each method can get whichever properties it needs out of that context parameter.

How do you define a Single Responsibility?

I know about "class having a single reason to change". Now, what is that exactly? Are there some smells/signs that could tell that class does not have a single responsibility? Or could the real answer hide in YAGNI and only refactor to a single responsibility the first time your class changes?
The Single Responsibility Principle
There are many obvious cases, e.g. CoffeeAndSoupFactory. Coffee and soup in the same appliance can lead to quite distasteful results. In this example, the appliance might be broken into a HotWaterGenerator and some kind of Stirrer. Then a new CoffeeFactory and SoupFactory can be built from those components and any accidental mixing can be avoided.
Among the more subtle cases, the tension between data access objects (DAOs) and data transfer objects (DTOs) is very common. DAOs talk to the database, DTOs are serializable for transfer between processes and machines. Usually DAOs need a reference to your database framework, therefore they are unusable on your rich clients which neither have the database drivers installed nor have the necessary privileges to access the DB.
Code Smells
The methods in a class start to be grouped by areas of functionality ("these are the Coffee methods and these are the Soup methods").
Implementing many interfaces.
Write a brief, but accurate description of what the class does.
If the description contains the word "and" then it needs to be split.
Well, this principle is to be used with some salt... to avoid class explosion.
A single responsibility does not translate to single method classes. It means a single reason for existence... a service that the object provides for its clients.
A nice way to stay on the road... Use the object as person metaphor... If the object were a person, who would I ask to do this? Assign that responsibility to the corresponding class. However you wouldn't ask the same person to do your manage files, compute salaries, issue paychecks, and verify financial records... Why would you want a single object to do all these? (it's okay if a class takes on multiple responsibilities as long as they are all related and coherent.)
If you employ a CRC card, it's a nice subtle guideline. If you're having trouble getting all the responsibilities of that object on a CRC card, it's probably doing too much... a max of 7 would do as a good marker.
Another code smell from the refactoring book would be HUGE classes. Shotgun surgery would be another... making a change to one area in a class causes bugs in unrelated areas of the same class...
Finding that you are making changes to the same class for unrelated bug-fixes again and again is another indication that the class is doing too much.
A simple and practical method to check single responsibility (not only classes but also method of classes) is the name choice. When you design a class, if you easily find a name for the class that specify exactly what it defines, you're in the right way.
A difficulty to choose a name is near always a symptom of bad design.
the methods in your class should be cohesive...they should work together and make use of the same data structures internally. If you find you have too many methods that don't seem entirely well related, or seem to operate on different things, then quite likely you don't have a good single responsibility.
Often it's hard to initially find responsibilities, and sometimes you need to use the class in several different contexts and then refactor the class into two classes as you start to see the distinctions. Sometimes you find that it's because you are mixing an abstract and concrete concept together. They tend to be harder to see, and, again, use in different contexts will help clarify.
The obvious sign is when your class ends up looking like a Big Ball of Mud, which is really the opposite of SRP (single responsibility principle).
Basically, all the object's services should be focused on carrying out a single responsibility, meaning every time your class changes and adds a service which does not respect that, you know you're "deviating" from the "right" path ;)
The cause is usually due to some quick fixes hastily added to the class to repair some defects. So the reason why you are changing the class is usually the best criteria to detect if you are about to break the SRP.
Martin's Agile Principles, Patterns, and Practices in C# helped me a lot to grasp SRP. He defines SRP as:
A class should have only one reason to change.
So what is driving change?
Martin's answer is:
[...] each responsibility is an axis of change. (p. 116)
and further:
In the context of the SRP, we define a responsibility to be a reason for change. If you can think of more than one motive for changing a class, that class has more than one responsibility (p. 117)
In fact SRP is encapsulating change. If change happens, it should just have a local impact.
Where is YAGNI?
YAGNI can be nicely combined with SRP: When you apply YAGNI, you wait until some change is actually happening. If this happens you should be able to clearly see the responsibilities which are inferred from the reason(s) for change.
This also means that responsibilities can evolve with each new requirement and change. Thinking further SRP and YAGNI will provide you the means to think in flexible designs and architectures.
Perhaps a little more technical than other smells:
If you find you need several "friend" classes or functions, that's usually a good smell of bad SRP - because the required functionality is not actually exposed publically by your class.
If you end up with an excessively "deep" hierarchy (a long list of derived classes until you get to leaf classes) or "broad" hierarchy (many, many classes derived shallowly from a single parent class). It's usually a sign that the parent class does either too much or too little. Doing nothing is the limit of that, and yes, I have seen that in practice, with an "empty" parent class definition just to group together a bunch of unrelated classes in a single hierarchy.
I also find that refactoring to single responsibility is hard. By the time you finally get around to it, the different responsibilities of the class will have become entwined in the client code making it hard to factor one thing out without breaking the other thing. I'd rather err on the side of "too little" than "too much" myself.
Here are some things that help me figure out if my class is violating SRP:
Fill out the XML doc comments on a class. If you use words like if, and, but, except, when, etc., your classes probably is doing too much.
If your class is a domain service, it should have a verb in the name. Many times you have classes like "OrderService", which should probably be broken up into "GetOrderService", "SaveOrderService", "SubmitOrderService", etc.
If you end up with MethodA that uses MemberA and MethodB that uses MemberB and it is not part of some concurrency or versioning scheme, you might be violating SRP.
If you notice that you have a class that just delegates calls to a lot of other classes, you might be stuck in proxy class hell. This is especially true if you end up instantiating the proxy class everywhere when you could just use the specific classes directly. I have seen a lot of this. Think ProgramNameBL and ProgramNameDAL classes as a substitute for using a Repository pattern.
I've also been trying to get my head around the SOLID principles of OOD, specifically the single responsibility principle, aka SRP (as a side note the podcast with Jeff Atwood, Joel Spolsky and "Uncle Bob" is worth a listen). The big question for me is: What problems is SOLID trying to address?
OOP is all about modeling. The main purpose of modeling is to present a problem in a way that allows us to understand it and solve it. Modeling forces us to focus on the important details. At the same time we can use encapsulation to hide the "unimportant" details so that we only have to deal with them when absolutely necessary.
I guess you should ask yourself: What problem is your class trying to solve? Has the important information you need to solve this problem risen to the surface? Are the unimportant details tucked away so that you only have to think about them when absolutely necessary?
Thinking about these things results in programs that are easier to understand, maintain and extend. I think this is at the heart of OOD and the SOLID principles, including SRP.
Another rule of thumb I'd like to throw in is the following:
If you feel the need to either write some sort of cartesian product of cases in your test cases, or if you want to mock certain private methods of the class, Single Responsibility is violated.
I recently had this in the following way:
I had a cetain abstract syntax tree of a coroutine which will be generated into C later. For now, think of the nodes as Sequence, Iteration and Action. Sequence chains two coroutines, Iteration repeats a coroutine until a userdefined condition is true and Action performs a certain userdefined action. Furthermore, it is possible to annotate Actions and Iterations with codeblocks, which define the actions and conditions to evaluate as the coroutine walks ahead.
It was necessary to apply a certain transformation to all of these code blocks (for those interested: I needed to replace the conceptual user variables with actual implementation variables in order to prevent variable clashes. Those who know lisp macros can think of gensym in action :) ). Thus, the simplest thing that would work was a visitor which knows the operation internally and just calls them on the annotated code block of the Action and Iteration on visit and traverses all the syntax tree nodes. However, in this case, I'd have had to duplicate the assertion "transformation is applied" in my testcode for the visitAction-Method and the visitIteration-Method. In other words, I had to check the product test cases of the responsibilities Traversion (== {traverse iteration, traverse action, traverse sequence}) x Transformation (well, codeblock transformed, which blew up into iteration transformed and action transformed). Thus, I was tempted to use powermock to remove the transformation-Method and replace it with some 'return "I was transformed!";'-Stub.
However, according to the rule of thumb, I split the class into a class TreeModifier which contains a NodeModifier-instance, which provides methods modifyIteration, modifySequence, modifyCodeblock and so on. Thus, I could easily test the responsibility of traversing, calling the NodeModifier and reconstructing the tree and test the actual modification of the code blocks separately, thus removing the need for the product tests, because the responsibilities were separated now (into traversing and reconstructing and the concrete modification).
It also is interesting to notice that later on, I could heavily reuse the TreeModifier in various other transformations. :)
If you're finding troubles extending the functionality of the class without being afraid that you might end up breaking something else, or you cannot use class without modifying tons of its options which modify its behavior smells like your class doing too much.
Once I was working with the legacy class which had method "ZipAndClean", which was obviously zipping and cleaning specified folder...