Reputation: 99
I just learned what the Strategy pattern really is from the Internet. But I wondered how it can improve my code. For example, i have the following codes found in the Internet like this. This is the Superclass named Animal:
abstract public class Animal {
private String name;
private int weight;
private String sound;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setWeight(int weight){
if(weight > 0){
this.weight = weight;
}else {
System.out.println("Weight must be bigger than 0");
}
}
public int getWeight(){
return weight;
}
public void setSound(String sound){
this.sound = sound;
}
public String getSound(){
return sound;
}
public void specialMethod(){
System.out.println("Ok");
}
}
This is the subclass named Dog:
public class Dog extends Animal {
public void digHole(){
System.out.println("Dig a hole");
}
public Dog(){
super();
setSound("bark");
}
public void testSuper(Animal obj){
System.out.println(obj.getName());
}
}
In the tutorial, it said that if we want to add flying ability so that I can check whether dog can fly or not. Adding the code directly like this one is bad as shown in the code below.
The Superclass Animal with an added flying ability method
abstract public class Animal {
private String name;
private int weight;
private String sound;
// Add fly method to the superclass which is a bad idea
public String fly(){
return " I am flying ";
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setWeight(int weight){
if(weight > 0){
this.weight = weight;
}else {
System.out.println("Weight must be bigger than 0");
}
}
public int getWeight(){
return weight;
}
public void setSound(String sound){
this.sound = sound;
}
public String getSound(){
return sound;
}
public void specialMethod(){
System.out.println("Ok");
}
}
Using the Strategy pattern, we can create interface named Flys with the method fly, allowing any subclass to implement the method, thus as shown in the tutorial, I created Interface named Flys with 2 subclasses implementing the interface:
public interface Flys {
String fly();
}
class ItFlys implements Flys{
public String fly(){
return "Flying high";
}
}
class CantFly implements Flys{
public String fly(){
return "I can't fly";
}
}
Once I made the interface, I can refactor the class Animal,
abstract public class Animal {
private String name;
private int weight;
private String sound;
Flys flyingType; // Add an object of the interface to the superclass
public String tryToFly(){ // add a new method tryToFly
return flyingType.fly();
}
// Adding another method named setFlyingAbility
public void setFlyingAbility(Flys newFlyType){
flyingType = newFlyType;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setWeight(int weight){
if(weight > 0){
this.weight = weight;
}else {
System.out.println("Weight must be bigger than 0");
}
}
public int getWeight(){
return weight;
}
public void setSound(String sound){
this.sound = sound;
}
public String getSound(){
return sound;
}
public void specialMethod(){
System.out.println("Ok");
}
}
Now, in my Dog subclass, I simply add another code
public class Dog extends Animal {
public Dog(){
super();
setSound("bark");
flyingType = new CantFly(); // I set flyingType object
}
public void digHole(){
System.out.println("Dig a hole");
}
public void testSuper(Animal obj){
System.out.println(obj.getName());
}
}
The final class is where I can execute all codes, checking whether my Dog class can fly or not.
public class AnimalPlay {
public static void main(String args[]){
Animal sparky = new Dog();
Animal tweety = new Bird();
System.out.println("Dog " + sparky.tryToFly()); // the result is I can't fly
System.out.println("Bird " + tweety.tryToFly()); // the result is I am flying
sparky.setFlyingAbility(new ItFlys());
System.out.println("Dog " + sparky.tryToFly()); // the result is I am flying
}
}
My question is, what about If I still add the fly() method the traditional way, it gives the same result, doesn't it?
Adding the fly() method to the superclass so I can override the fly() method in my Dog class, but this is not a good idea.
abstract public class Animal {
private String name;
private int weight;
private String sound;
// Add fly method to the superclass which is a bad idea
public String fly(){
return " I am flying ";
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setWeight(int weight){
if(weight > 0){
this.weight = weight;
}else {
System.out.println("Weight must be bigger than 0");
}
}
public int getWeight(){
return weight;
}
public void setSound(String sound){
this.sound = sound;
}
public String getSound(){
return sound;
}
public void specialMethod(){
System.out.println("Ok");
}
}
Upvotes: 1
Views: 1184
Reputation: 2016
My question is, what about If I still add the fly() method the traditional way, it gives the same result, doesn't it?
The answer is 'NO'.
We can continue and find other bonuses. But you can see a picture
Good luck!
Upvotes: 3
Reputation: 379
I am not sure which came first, but the Strategy pattern like any other behavioral pattern is a specific instance of the open close principle. In general you want to change the behavior of an object without having to change it's code. This has a profound consequences in terms of extendability, maintainability and coherence.
Upvotes: 1