minte9
LearnRemember



Strategy

Used when you need to dynamically change an object behavior at run time. This pattern separates behavior from super and subclasses. It allows you to eliminate code duplication.
 
/** 
 * Using just interfaces ...
 * we can't change the behavior at runtime
 */
class App {
    
    public static void main(String[] args) {
        
        Master m = new Master();
        m.name = "Socrate";
        m.speak();

        Pupil p = new Pupil();
        p.name = "Alcibiades";
        p.speak();

        // after that ...
        // we can't change speak() behavior at runtime
    }    
}

class Master implements Speak {
    public String name;
    public void speak() {
        System.out.println(name + ": I can raise questions ...");
    }
}

class Pupil implements Speak {
    public String name;
    public void speak() {
        System.out.println(name + ": I can answer!");
    }
}

interface Speak {
    public void speak();
}

// Socrate: I can raise questions ...
// Alcibiades: I can answer!
With Strategy Pattern we use an instance variable (composition technique). It allows us to change the capabilities of objects at run time!
  
class Alcibiades {
    
    public static void main(String[] args) {
        
        Master m = new Master("Socrate");
        m.type = new AskCapable();
        m.speak();

        Pupil p = new Pupil("Alcibiades");
        p.type = new AskIncapable();
        p.speak();

        // now, we are able ...
        // to change the behavior type at runtime
        
        p.type = new AskCapable();
        p.speak();
    }    
}

class Master extends Human {
    public Master(String n) {
        name = n;
    }
}
class Pupil extends Human {
    public Pupil(String n) {
        name = n;
    }
}

/**
 * The parent abstract class ...
 * doesn't konw what the behavior type is.
 * It just knows that it is available to its subclasses
 */
abstract class Human {
    String name;
    Speak type;
    public void speak() {
        System.out.print(name + ": ");
        type.speak(); // Look Here
    }
}

class AskCapable implements Speak {
    public void speak() {
        System.out.println("I can raise questions ...");
    }
}
class AskIncapable implements Speak {
    public void speak() {
        System.out.println("I can answer!");
    }
}
interface Speak {
    public void speak();
}

// Socrate: I can raise questions ...
// Alcibiades: I can answer!
// Alcibiades: I can raise questions ...
  
class TheRings {

    public static void main(String[] args) {

        Wizard w1 = new Wizard("Saruman");
        Wizard w2 = new Wizard("Gandalf");
        Hobbit h1 = new Hobbit("Frodo");
        
        w1.type = new Fly(); // Saruman can Fly
        w2.type = new Ride(); // Gandalf can Ride
        h1.type = new Run(); // Frodo can Run

        int level = 1;
        while (level <= 3) {

            System.out.println("\nLevel " + level);

            if (level == 2) {
                h1.type = new Disappear(); // Frodo can Disappear
            }

            if (level == 3) {
                w2.type = new Fly(); // Gandalf can Fly
                w1.type = new Run(); // Saruman must Run :)
            }

            w1.display(); w1.move(); 
            w2.display(); w2.move();
            h1.display(); h1.move();

            level = level + 1;
        }
    }
}


// Items

class Wizard extends Item {
    String name;
    public Wizard(String n) {
        name = n;
    }
    public void display() {
        System.out.print(name);
    }
}

class Hobbit extends Item {
    String name;
    public Hobbit(String n) {
        name = n;
    }
    public void display() {
        System.out.print(name);
    }
}

abstract class Item {
    Move type;
    public void move() {
        type.move();
    }
    abstract void display();
}


// Strategies

interface Move {
    public void move();
}

class Fly implements Move {
    public void move() {
        System.out.print(" (Fly) ");
    }
}

class Ride implements Move {
    public void move() {
        System.out.print(" (Ride) ");
    }
}

class Run implements Move {
    public void move() {
        System.out.print(" (Run) ");
    }
}

class Disappear implements Move {
    public void move() {
        System.out.print(" (Disappear) ");
    }
}

/*

Level 1
Saruman (Fly) Gandalf (Ride) Frodo (Run) 
Level 2
Saruman (Fly) Gandalf (Ride) Frodo (Disappear) 
Level 3
Saruman (Run) Gandalf (Fly) Frodo (Disappear)

*/
Strategy v2.0 Alcibiades can't ask Strategy v2.2 Alcibiades is wiser now, he can ask


  Last update: 224 days ago