Reputation: 52
Lets suppose we have a class Shape which has a method rotate(int velocity). This method makes a shape rotate with a speed of velocity(the parameter passed to rotate). This method has been called in a project, say at 100 places.
But now a new requirement comes, that the rotate functionality will also depend on the color of the shape, i.e. if the color is blue then the velocity should be decreased by 1, else no change should be made.
One solution to this problem would be to change the rotate(int velocity) method to rotate(int velocity, Color color), then add an if statement inside rotate method to check for the color, and make a change in 100 calls of rotate. E.g.
shape.rotate(50, blue) ;
Inside the rotate method,
void rotate(int velocity, Color color) {
if(color == blue)
--velocity ;
}
Another solution would be to make color as an instance variable of the shape object, and then without adding a new argument to the rotate method, simply set the color before calling it, and squeeze the if check inside the rotate method. E.g.
shape.setColor(blue) ;
shape.rotate(50) ;
Inside the rotate method,
void rotate(int velocity) {
if(this.color == blue)
--velocity ;
}
Yet another solution would be to overload the rotate method and create a new method named rotate(int velocity, Color color) and use it in the new calls. This would leave the existing code which uses rotate(int velocity) unchanged.
Which of these would be the best possible solution? Or, does there exist a better solution? If yes, then what could it be?
Regards
Upvotes: 0
Views: 160
Reputation: 16209
A good principle of OO is to co-locate related behavior and state. In this case the rotate behavior of shape depends on the colour state of shape, so it makes sense to co-locate both in the Shape class, c.q. create a field 'colour' and use it within the rotate method to customize the rotation behavior.
Apart from this design decision, you are really also asking about a refactoring decision: how do I handle the application code that depends on shape? My approach in cases like this is to think ahead: how many changes like these to the Shape class can we expect? If this is a rare change then you could just go ahead and change all the code locations that initialize the shape class so a colour is set. If shape changes more often, then you should be more rigorous and make your code less tightly coupled. A way to do that in this case is to create an abstract factory (or use the factory offered by a D.I. framework like Spring) so that the application code does not need to know the creation details of shape.
BTW your third option seems sub-optimal to me: part of the code is not made aware of the addition of the colour state to shape, and keeps calling the old 'deprecated' rotate method. This means that setting a shape's colour to blue will not universally affect the rotation behavior, but only in 'special cases'. This weakens the design and makes it harder for the developers after you to understand it.
Upvotes: 0
Reputation: 1386
As for me, I see classic example of inheritance usage here.
class Shape {
public void rotate(int v) {}
}
class GreenShape extends Shape {
public void rotate(int v){
super.rotate(v + 10);
}
}
Upvotes: 0
Reputation: 3436
Upvotes: 0
Reputation: 38345
I'd say there are a couple of questions you need to ask yourself.
Do you care about the color outside of the rotate
method? If yes, make it an instance variable; if no, pass it to the rotate method.
Are you likely to care about the color outside of the rotate
method further down the line? If yes, make it an instance variable; if no, pass it to the rotate method.
Are you always going to care about the color when calling the rotate method? If yes, make it an argument (to force them to set the color when rotating the shape).
Upvotes: 2