Design Patterns (1) - Strategic Patterns

Posted by bsteimel on Sat, 06 Jul 2019 23:12:41 +0200

What is a strategic model?

The policy pattern defines the algorithm family and encapsulates them separately so that they can replace each other. This pattern makes the algorithm independent of the users who use the algorithm.

Do you understand the definition above?

I think you must have understood that smart person, so let's see how I understand it.

This is to classify some behaviors in a base class and then select these specific categories when applied to a specific class. Let's take an example to see.

Deep Understanding of Strategic Patterns

If there is a requirement, you are required to write a duck base class. This duck base class requires three methods: quak, fly and display. Specific duck species inherit this base class.

According to this requirement, the first thought should be this.

public class Duck {

    private String color;

    public Duck() {
    }

    public Duck(String color) {
        super();
        this.color = color;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public void quake() {
        System.out.println("Gagaga...");
    }

    public void display() {
        System.out.println("I am one." + color + "Duck");
    }

    public void fly() {
        System.out.println("Fly ah fly ah...");
    }
}

 

When the base class is complete, other specific ducks inherit the base class and then write other specific attributes or methods.

But what about it? Are there some problems? Are all ducks called "Gaga"? Can all ducks fly? I think there must be some more exotic ducks.. So we have this design problem, how should we solve it at this time? At this point you should think of defining this as an interface for other subclasses to implement it. The specific code should be as follows:

public interface BaseDuck {

    void quak();

    void display();

    void fly();
}

Or we can define an abstract class that implements some methods that need little change in the base class, while others are implemented by subclasses. Examples are as follows:

public abstract class AbstractDuck {

    private String color;

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public abstract void quak();

    public void display() {
        System.out.println("I am one." + color + "Duck");
    }

    public abstract void fly();
}

At this point, the code is OK, but is it really flawless? One problem that may be overlooked is that our design is designed to accommodate the more exotic species of ducks. Most other ducks should have the same call and be able to fly. So we write a lot of redundant code when we write subclasses, so how do we solve this problem?

Strategic model is to solve this problem, how does it achieve? First of all, this base class, quak and fly, which are easy to change, customers may need you to add a toy duck or something that day. So send and extract these two behaviors and write them separately. First, define two interfaces, QuakBehavior and FlyBehavior, and then write some subclasses according to the requirements, such as Flying and Not Flying,'Gaga'and'Squeeze' and'Don't Call'. The sample code is as follows:

The following code is multiple files

//QuackBehavior.java
public interface QuackBehavior {

    void quak();
}

//FlyBehavior.java
public interface FlyBehavior {

    void fly();
}

//Quack.java
public class Quack implements QuackBehavior {

    @Override
    public void quak() {
        System.out.println("Gagaga...");
    }

}

//Squeak.java
public class Squeak implements QuackBehavior {

    @Override
    public void quak() {
        System.out.println("Creak...");
    }

}

//QuackNoWay.java
public class QuackNoWay implements QuackBehavior {

    @Override
    public void quak() {
        System.out.println("I can't yell...");
    }

}

//FlyWithWings.java
public class FlyWithWings implements FlyBehavior {

    @Override
    public void fly() {
        System.out.println("Fly ah fly ah...");
    }

}

//FlyNoWay.java
public class FlyNoWay implements FlyBehavior {

    @Override
    public void fly() {
        System.out.println("I can't fly...");
    }

}

The base class should be designed as follows:

package model.strategy.v2;

public class Duck {

    private String color;

    //Adding fields for behavioral interfaces
    private QuackBehavior quackBehavior;

    private FlyBehavior flyBehavior;

    public Duck() {
    }

    public Duck(String color, QuackBehavior quackBehavior, FlyBehavior flyBehavior) {
        super();
        this.color = color;
        this.quackBehavior = quackBehavior;
        this.flyBehavior = flyBehavior;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public void quake() {
     //Call interface methods quackBehavior.quak(); }
public void display() { System.out.println("I am one." + color + "Duck"); } public void fly() {
     //Call interface methods flyBehavior.fly(); } }

Now think about whether this problem has been solved very well. If a new requirement comes, we just need to define a new interface implementation without modifying the code in the base class.

I believe that by this time I have a good understanding of the strategic model, if you have any comments or questions about the blog, you can leave a message Oh > v.<

Topics: Java