Strategy design pattern

In computer programming, the strategy pattern (also known as the policy pattern) is a behavioral software design pattern that enables selecting an algorithm at runtime. The strategy pattern defines a family of algorithms and encapsulates each algorithm.


For instance, a class that performs validation on incoming data may use the Strategy pattern to select a validation algorithm depending on the type of data, the source of the data, user choice, or other discriminating factors. These factors are not known until run-time and may require radically different validation to be performed. The validation algorithms (strategies), encapsulated separately from the validating object, may be used by other validating objects in different areas of the system (or even different systems) without code duplication.

[Wikipedia]

Intro

In this example, we will create animal class and Dog,Shark and mouse classes that extend Animal The Runs insatnce has one function , isRun(). In the Animal class , we use an instance variable that is a subclass of the Runs interface. Animal doesn't care what Runs does , it's just knows we can use it. Instead of inheriting an ability through inheritance, the class is composed with objects with the right ability We are not inheriting abilities , we are using the Runs that has the desired ability. in this way , we can change the behavior at run time.

Runs

public interface Runs {
    public String isRun();
    }

CantRun

public class CantRun implements Runs{
    //if animal can't run
    public String isRun() {
        String s ="I can't run";
        return s;
    }
}

CanRun

public class CanRun implements Runs{
   // if animal can run
    public String isRun() {
        String s ="I can run";
        return s;
    }
}

Animal

public class Animal {
    /*
 we use an instance variable that is a subclass of the Runs interface.
 Animal doesn't care what Runs does , it's just knows we can use it.
 Instead of inheriting an ability through inheritance, the class is composed
 with objects with the right ability
 We are not inheriting abilities , we are using the Runs that has the desired ability.
in this way , we can change the behavior at run time
*/
    private String name;
    private int height;
    private int weight;
    private String sound;
    public Runs runs;

    // The constructor of the class
    public Animal(String name, int height, int weight) {
        this.name = name;
        this.height = height;
        this.weight = weight;
    }
    // returns the name of the animal
    public String getName() {
        return name;
    }
    // sets the name of the animal
    public void setName(String name) {
        this.name = name;
    }
    // returns the height of the animal
    public int getHeight() {
        return height;
    }
    // sets the height of the animal
    public void setHeight(int height) {
        this.height = height;
    }
    // returns the weight of the animal

    public int getWeight() {
        return weight;
    }
    // sets the weight of the animal
    public void setWeight(int weight) {
        this.weight = weight;
    }
    // returns the sound of the animal
    public String getSound() {
        return sound;
    }
    // sets the sound of the animal
    public void setSound(String sound) {
        this.sound = sound;
    }

    //returns if the animal can run
    public String tryToRun(){
        return runs.isRun();
    }
    // The class behavior can be changed at run time
    public void setRunning(Runs runs){
        this.runs = runs;
    }
}

Dog

public class Dog extends Animal{
    public Dog(String name, int height, int weight){
        super(name,height,weight);
        // sets the sound of the dog
        setSound("BarkBarkBarkBark");
        //We set the behavior of the dog- he can run 
        super.runs = new CanRun();
    }
    public void bark(){
    System.out.println("Bark");
    }
}

Shark

public class Shark extends Animal{
    public Shark(String name, int height, int weight){
        super(name,height,weight);
        // sets the sound of the bird
        setSound("SplashSplashSplashSplash");
     /*We set the behavior of the shark.
          The shark can't run
         */
        super.runs = new CantRun();
    }
    public void swimDeeper(int num){
        setHeight(getHeight()- num);
    }
}

Mouse

public class Mouse extends Animal {
    public Mouse(String name, int height, int weight) {
        super(name, height, weight);
        // sets the sound of the mouse
        setSound("ChiChiChiChi");
        /*We set the behavior of the mouse.
          The mouse can run
         */
        super.runs = new CanRun();
    }
}

Main

public class Main {
    public static void main(String[] args){
        Animal shuki = new Dog("shuki",60,30); //creates new dog
        Animal mikey = new Mouse("mikey",10,4); //creates new mouse
        Animal roni = new Shark("roni",26,10); //creates new shark
        System.out.println("I'm a dog and my name is: "+shuki.getName());
        System.out.println("I'm a mouse and my name is: "+mikey.getName());
        System.out.println("I'm a shark and my name is: "+roni.getName());
        System.out.println();
        System.out.println("Dog: " + shuki.tryToRun());
        System.out.println("Mouse: " + mikey.tryToRun());
        System.out.println("Shark: " + roni.tryToRun());

        // This allows dynamic changes for runs
        roni.setRunning(new CanRun());
        System.out.println("After dynamic changes for Run");
        // now the shark can run
        System.out.println("Shark: " + roni.tryToRun());
    }
}

Running Example

I'm a dog and my name is: shuki
I'm a mouse and my name is: mikey
I'm a shark and my name is: roni

Dog: I can run
Mouse: I can run
Shark: I can't run
After dynamic changes for Run
Shark: I can run