Design Pattern: Strategy Pattern of HelloWorld

I. Overview

The strategy pattern defines a family of algorithms and encapsulates them separately so that they can be replaced with each other. This pattern allows the changes of the algorithm to be independent of the clients using the algorithm.

Three elements of the strategy pattern:

Abstract strategy role : Strategy class, usually implemented by an interface or abstract class.

Specific policy role : wraps related algorithms and behaviors.

Environment role : Holds a reference to a policy class, which is ultimately called by the client.

2. Case-driven

Ask a question: Ask to make a game that simulates ducks. There will be various ducks in the game. They swim and croak at the same time.

Analysis: According to the OO design idea, it is nothing more than to make all kinds of ducks realize their corresponding functions, such as ducks swimming and ducks croaking.

Solution 1.0 : Design an interface (Duck), and then complete different implementations as needed, such as red duck, mallard. . . .

public interface Duck {
    public abstract void quack();
    public abstract void swim();
    public abstract void display();
}
public MallardDuck implements Duck{
    public abstract void quack(){
        System.out.println("呱呱~~");
    }
    public abstract void swim(){
        System.out.println("欢快的游泳~~");
    }
    public abstract void display(){
        System.out.println("绿头鸭~~");
    }
}
public RedHeadDuck implements Duck{
    public abstract void quack(){
        System.out.println("呱呱~~");
    }
    public abstract void swim(){
        System.out.println("欢快的游泳~~");
    }
    public abstract void display(){
        System.out.println("红头鸭~~");
    }
}

A new requirement was suddenly added, calling for wild ducks, which, in addition to these two functions, can fly, and at the same time there is a rubber duck that squeaks when it croaks. .

At this point, the program exposed its shortcomings. . . .

Disadvantages: It is difficult to know the behavior of all ducks, and when new functions need to be added for some implementations

Solution 1.1

For more flexibility, interface-oriented programming.

public interface Flyable {
    public abstract void fly();
}
public interface Swimable {
    public abstract void swim();
}
public interface Quackable {
    public abstract void quack();
}
public RedHeadDuck implements Quackable implements Swimable {...}
public WildDuck implements Quackable implements Swimable implements Flyable {...}

If there are 10,000 kinds of ducks, this method is unimaginable, and the repetitive code is too much!

Solution 2.0

This problem is solved using the strategy mode.

step1: Take out the parts that will change and encapsulate them so that other code will not be affected.

step2: The Big Picture of Encapsulation Behavior

step3: code implementation

abstract policy role

// 飞行行为
public interface FlyBehavior {
    public abstract void fly();
}
// 叫声行为
public interface QuackBehavior {
    public abstract void quack();
}

specific policy objects

// 橡皮鸭叫
public RubberDuckBehavior implements QuackBehavior {
    public abstract void quack(){
        System.out.println("吱吱~~");
    }
}
// 野鸭叫
public WildDuckBehavior implements QuackBehavior {
    public abstract void quack(){
        System.out.println("嘎嘎~~");
    }
}
// 大黄鸭叫
public YellowDuckBehavior implements QuackBehavior {
    public abstract void quack(){
        System.out.println("呱呱~~");
    }
}
// 不会飞
public FlyNoWay implements FlyBehavior {
    public abstract void fly(){
        System.out.println("不会飞~~");
    }
}
// 用翅膀飞
public FlyWithWings implements FlyBehavior {
    public abstract void fly(){
        System.out.println("用翅膀飞~~");
    }
}
// 螺旋桨飞
public FlyLikePlane implements FlyBehavior {
    public abstract void fly(){
        System.out.println("用螺旋桨~~");
    }
}

environmental role

abstract class

public abstract class Duck {
     FlyBehavior flyBehavior;
     QuackBehavior quackBehavior;
    // 动态设定行为
    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }
    public void setQuackBehavior(QuackBehavior quackBehavior) {
        this.quackBehavior = quackBehavior;
    }
    public void performFly() {
        flyBehavior.fly();
    }
    public void performQuack() {
        quackBehavior.quack();
    }
    public abstract display() {}
    public void swim() {
        System.out.println("鸭子天生会游泳!");
    }
}

accomplish

public class WildDuck implements Duck {
     FlyBehavior flyBehavior;
     QuackBehavior quackBehavior;
    public WildDuck() {
        // 默认会飞,野鸭叫嘎嘎
        this.flyBehavior = new FlyWithWings();
        this.quackBehavior = new WildDuckBehavior();
    }
    // 动态设定行为
    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }
    public void setQuackBehavior(QuackBehavior quackBehavior) {
        this.quackBehavior = quackBehavior;
    }
    public void performFly() {
        flyBehavior.fly();
    }
    public void performQuack() {
        quackBehavior.quack();
    }
    public abstract display() {
        System.out.println("这是一只野鸭!");
    }
    public void swim() {
        System.out.println("鸭子天生会游泳!");
    }
}

Change of needs: Mallard's wings are injured and can't fly

    public static void main(String[] args) {
        Duck duck = new WildDuck();
        duck.setFlyBehavior(new FlyNoWay());
        duck.performFly();// 输出:不会飞~~
    }

Changes to be changed: Add a rocket duck, which can fly into space, but cannot swim, looks like a rocket, and is called Quagga

public RocketDuckFlyBehavior implements FlyBehavior {
    public abstract void fly(){
        System.out.println("飞到太空~~");
    }
}
public class RocketDuck implements Duck {
     FlyBehavior flyBehavior;
     QuackBehavior quackBehavior;
    public WildDuck() {
        // 默认会飞,野鸭叫嘎嘎
        this.flyBehavior = new RocketDuckFlyBehavior();
        this.quackBehavior = new WildDuckQuackBehavior();
    }
    // 动态设定行为
    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }
    public void setQuackBehavior(QuackBehavior quackBehavior) {
        this.quackBehavior = quackBehavior;
    }
    public void performFly() {
        flyBehavior.fly();
    }
    public void performQuack() {
        quackBehavior.quack();
    }
    public abstract display() {
        System.out.println("外形像火箭~~");
    }
    public void swim() {
        System.out.println("不会游泳");
    }
}

The advantages and disadvantages of the strategy mode

advantage:

1. The strategy pattern provides a way to manage related families of algorithms. The hierarchy of policy classes defines a family of algorithms or behaviors. Proper use of inheritance can move code to symbol classes, thereby avoiding duplication of code.

2. Use composition and delegation in the strategy pattern to give environmental actors the ability to execute algorithms, which is also a lighter alternative to inheritance.

3. Provides perfect support for the open-closed principle, encapsulating algorithms in independent strategies, making them easy to switch, easy to understand, and easy to extend

4. Using techniques and ideas such as composition, delegation and polymorphism, multiple conditional selection statements can be effectively avoided

shortcoming:

 1. The client must know all the policy classes, distinguish between them, and decide which one to use.

 2. A strategy class needs to be created for each behavior situation, resulting in many strategy classes.
Personal site address: www.mycookies.cn (personal blog project suitable for java beginners) github: https://github.com/liqianggh/blog

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324917882&siteId=291194637
Recommended