Strategic mode of design mode

Keywords: Java Design Pattern

In real life, it is often encountered that there are many strategies to choose to achieve a certain goal. For example, when traveling, you can take a plane, a train, a bicycle or drive your own private car. Supermarket promotion can adopt methods such as discounts, goods and points.

Similar situations are often encountered in software development. When there are multiple algorithms or strategies to implement a function, we can select different algorithms or strategies to complete the function according to different environments or conditions. For example, data sorting strategies include bubble sorting, selection sorting, insertion sorting, binary tree sorting, etc.

If multiple conditional transition statements are used (i.e. hard coding), the conditional statements will not only become very complex, but also the original code will be modified to add, delete or replace the algorithm, which is not easy to maintain and violates the opening and closing principle. If the strategy mode is adopted, this problem can be well solved.

Definition and characteristics of strategy pattern

definition

This pattern defines a series of algorithms and encapsulates each algorithm so that they can be replaced with each other, and the change of the algorithm will not affect the customers using the algorithm. The policy pattern belongs to the object behavior pattern. It separates the responsibility of using the algorithm from the implementation of the algorithm by encapsulating the algorithm, and delegates it to different objects to manage these algorithms.

advantage

  • Multiple conditional statements are difficult to maintain, and the use of policy mode can avoid the use of multiple conditional statements, such as if... else statements and switch... case statements.
  • Policy pattern provides a series of reusable algorithm families. Proper use of inheritance can transfer the public code of the algorithm family to the parent class, so as to avoid repeated code.
  • The policy pattern can provide different implementations of the same behavior, and customers can choose different policies according to different time or space requirements.
  • The strategy mode provides perfect support for the opening and closing principle, and can flexibly add new algorithms without modifying the original code.
  • The policy pattern puts the use of the algorithm into the environment class, and the implementation of the algorithm is moved to the specific policy class, which realizes the separation of the two.

shortcoming

  • The client must understand the differences between all policy algorithms in order to select the appropriate algorithm class in time.
  • The policy mode creates many policy classes, which increases the difficulty of maintenance.

Structure and implementation of policy pattern

The policy pattern is to prepare a set of algorithms and encapsulate them into a series of policy classes as a subclass of an abstract policy class. The focus of policy mode is not how to implement algorithms, but how to organize these algorithms, so as to make the program structure more flexible, more maintainable and extensible. Now let's analyze its basic structure and implementation method.

1. Structure of the model

The main roles of the policy model are as follows.
Abstract Strategy class: defines a public interface. Different algorithms implement this interface in different ways. Environmental roles use this interface to call different algorithms, which are generally implemented by interfaces or abstract classes.
Concrete Strategy class: implements the interface of abstract policy definition and provides specific algorithm implementation.
Context class: holds a reference to a policy class, which is finally called to the client.

Its structure is shown in Figure 1.

2. Implementation of mode

The implementation code of the policy mode is as follows:

public class StrategyPattern {
    public static void main(String[] args) {
        Context c = new Context();
        Strategy s = new ConcreteStrategyA();
        c.setStrategy(s);
        c.strategyMethod();
        System.out.println("-----------------");
        s = new ConcreteStrategyB();
        c.setStrategy(s);
        c.strategyMethod();
    }
}
//Abstract policy class
interface Strategy {
    public void strategyMethod();    //Strategy method
}
//Specific strategy class A
class ConcreteStrategyA implements Strategy {
    public void strategyMethod() {
        System.out.println("Specific strategies A The policy method of is accessed!");
    }
}
//Specific strategy class B
class ConcreteStrategyB implements Strategy {
    public void strategyMethod() {
        System.out.println("Specific strategies B The policy method of is accessed!");
    }
}
//Environment class
class Context {
    private Strategy strategy;
    public Strategy getStrategy() {
        return strategy;
    }
    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }
    public void strategyMethod() {
        strategy.strategyMethod();
    }
}

The running results of the program are as follows:

Specific strategies A The policy method of is accessed!
-----------------
Specific strategies B The policy method of is accessed!

Application examples of policy pattern

[example 1] Application of strategy mode in "hairy crab" cooking.

Analysis: there are many kinds of hairy crabs. We take steamed hairy crabs and braised hairy crabs as examples to introduce the application of strategy mode.

First, define an abstract strategy class for hairy crab processing (CrabCooking), which contains an abstract method for cooking, CookingMethod(); Then, the specific policy classes of steamed crabs and braised crabs are defined, which implement the abstract methods in the abstract policy class; Since this program needs to display the finished result diagram (click here to download the result diagram to be displayed), the specific policy class is defined as a subclass of JLabel; Finally, a Kitchen environment class is defined, which has the methods of setting and selecting cooking strategies; The customer class obtains the cooking strategy through the Kitchen class, and displays the cooking result diagram in the window. Figure 2 shows its structure diagram.


The program code is as follows:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CrabCookingStrategy implements ItemListener {
    private JFrame f;
    private JRadioButton qz, hs;
    private JPanel CenterJP, SouthJP;
    private Kitchen cf;    //kitchen
    private CrabCooking qzx, hsx;    //Hairy crab processor  
    CrabCookingStrategy() {
        f = new JFrame("Application of strategy model in hairy crab cooking");
        f.setBounds(100, 100, 500, 400);
        f.setVisible(true);
        f.setResizable(false);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        SouthJP = new JPanel();
        CenterJP = new JPanel();
        f.add("South", SouthJP);
        f.add("Center", CenterJP);
        qz = new JRadioButton("Stewed Big Fresh Water Crab");
        hs = new JRadioButton("Braised hairy crab");
        qz.addItemListener(this);
        hs.addItemListener(this);
        ButtonGroup group = new ButtonGroup();
        group.add(qz);
        group.add(hs);
        SouthJP.add(qz);
        SouthJP.add(hs);
        //---------------------------------
        cf = new Kitchen();    //kitchen
        qzx = new SteamedCrabs();    //Steamed hairy crabs
        hsx = new BraisedCrabs();    //Braised hairy crabs
    }
    public void itemStateChanged(ItemEvent e) {
        JRadioButton jc = (JRadioButton) e.getSource();
        if (jc == qz) {
            cf.setStrategy(qzx);
            cf.CookingMethod(); //Steamed
        } else if (jc == hs) {
            cf.setStrategy(hsx);
            cf.CookingMethod(); //Braised
        }
        CenterJP.removeAll();
        CenterJP.repaint();
        CenterJP.add((Component) cf.getStrategy());
        f.setVisible(true);
    }
    public static void main(String[] args) {
        new CrabCookingStrategy();
    }
}
//Abstract strategy class: hairy crab processing class
interface CrabCooking {
    public void CookingMethod();    //Cooking method
}
//Specific strategies: steamed hairy crab
class SteamedCrabs extends JLabel implements CrabCooking {
    private static final long serialVersionUID = 1L;
    public void CookingMethod() {
        this.setIcon(new ImageIcon("src/strategy/SteamedCrabs.jpg"));
        this.setHorizontalAlignment(CENTER);
    }
}
//Specific strategies: Braised hairy crab
class BraisedCrabs extends JLabel implements CrabCooking {
    private static final long serialVersionUID = 1L;
    public void CookingMethod() {
        this.setIcon(new ImageIcon("src/strategy/BraisedCrabs.jpg"));
        this.setHorizontalAlignment(CENTER);
    }
}
//Environment: Kitchen
class Kitchen {
    private CrabCooking strategy;    //Abstract strategy
    public void setStrategy(CrabCooking strategy) {
        this.strategy = strategy;
    }
    public CrabCooking getStrategy() {
        return strategy;
    }
    public void CookingMethod() {
        strategy.CookingMethod();    //cook a dish  
    }
}

Application scenario of policy mode

Policy patterns are used in many places. For example, container layout management in Java SE is a typical example. Each container in Java SE has a variety of layouts for users to choose from. In programming, the policy mode is usually used in the following cases.
When a system needs to dynamically select one of several algorithms, each algorithm can be encapsulated into a policy class.
A class defines multiple behaviors, and these behaviors appear in the form of multiple conditional statements in the operation of this class. Each conditional branch can be moved into their respective policy class to replace these conditional statements.
Each algorithm in the system is completely independent of each other, and it is required to hide the implementation details of the specific algorithm from the customer.
When the system requires that the customer using the algorithm should not know the data it operates, the policy pattern can be used to hide the data structure related to the algorithm.
Multiple classes only have different behaviors. You can use the policy mode to dynamically select the specific behavior to be executed at run time.

Posted by Flukey on Mon, 20 Sep 2021 05:21:00 -0700