Home > Java > javaTutorial > body text

Implementation of Strategy Pattern in Java Design Patterns

王林
Release: 2023-04-24 23:37:06
forward
1880 people have browsed it

1 Overview

In daily development, we often encounter a situation where there are many algorithms or strategies to implement a function. We can implement this function based on different algorithms or strategies. For example: If you want to calculate a logistics calculation method, all are billed. Different express delivery has different billing methods, such as JD Express, Best Express, and YTO Express. The way they calculate shipping costs is different. So how do we achieve it? The simple ones are if...else...or switch...case.... These two implementations are called hard coding. If there is a new billing method like Yunda Express, then we need to modify the source code of our algorithm. This will make the code bloated and difficult to maintain.

So, we need to implement a way that each has its own algorithm, and we only need to choose which method to call on the client.

2 Strategy pattern

2.1 Components

Environment class (Context): Configured with a ConcreteStrategy object. Maintain a reference to the Strategy object. You can define an interface to let Strategy access its data.

Abstract Strategy Class (Strategy): Defines the public interface of all supported algorithms. Context uses this interface to call an algorithm defined by a ConcreteStrategy.

Concrete Strategy Class (ConcreteStrategy): Implement specific algorithms with Strategy interface.

2.2 Code Example

Take the freight rates of different express companies as an example:

Step 1: Define an abstract strategy class (billing method)

public interface CommandStrategy {
    /**
     * 计费方式
     * @param message
     */
    void calMoney(String message);
}
Copy after login

Steps Two: Define a specific strategy class (different algorithm classes implement this interface)

public class BaiShiCommand implements CommandStrategy {
    /**
     * 百世快递计费方式
     * @param message
     */
    @Override
    public void calMoney(String message) {
        System.out.println("百世快递收费方式:"+"起步20,每公斤6元");
    }
}
Copy after login
public class JingDongCommand implements CommandStrategy {
    /**
     * 京东快递计费方式
     * @param message
     */
    @Override
    public void calMoney(String message) {
        System.out.println("京东快递收费方式:"+"起步30,每公斤5元");
    }
}
Copy after login
public class YuanTongCommand implements CommandStrategy {
    /**
     * 圆通快递计费方式
     * @param message
     */
    @Override
    public void calMoney(String message) {
        System.out.println("圆通快递收费方式:"+"起步10,每公斤8元");
    }
}
Copy after login

Step three: Define the environment class

public class CommandContext {
    public CommandStrategy getInstance(String commandType) {
        CommandStrategy commandStrategy = null;
        Map<String, String> allClazz = CommandEnum.getAllClazz();
        //拿到对应算法类对应的路径
        String clazz = allClazz.get(commandType.trim().toLowerCase());
        if (StringUtils.isNotEmpty(clazz)) {
            try {
                try {
                    //创建一个对象实例
                    commandStrategy = (CommandStrategy) Class.forName(clazz).newInstance();//调用无参构造器创建实例
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        System.out.println("commandStrategy:"+commandStrategy);
        return commandStrategy;
    }
}
Copy after login

Define an enumeration class:

public enum CommandEnum {
    JingDong("京东", "com.liubujun.design.command.JingDongCommand"), BaiShi("百世", "com.liubujun.design.command.BaishiCommand"), YuanTong("圆通", "com.liubujun.design.command.YuanTongCommand");
    private String name;
    private String clazz;
    public static Map<String, String> getAllClazz() {
        Map<String, String> map = new HashMap<>(8);
        System.out.println("==================="+Arrays.toString(CommandEnum.values())+"================");
        for (CommandEnum commandEnum : CommandEnum.values()) {
            map.put(commandEnum.getCommand(), commandEnum.getClazz());
        }
        return map;
    }
    public String getCommand() {
        return name;
    }
    CommandEnum(String command, String clazz) {
        this.name = command;
        this.clazz = clazz;
    }
    public void setCommand(String command) {
        this.name = command;
    }
    public String getClazz() {
        return clazz;
    }
    public void setClazz(String clazz) {
        this.clazz = clazz;
    }
}
Copy after login

Client :

public class MainStart {
    public static void main(String[] args) {
        String message = "京东";
        CommandContext commandContext = new CommandContext();
        //拿到message对应算法的对象实例
        CommandStrategy commandStrategy = commandContext.getInstance(message);
        commandStrategy.calMoney(message);
    }
}
Copy after login

In this way, the client can directly call which express billing method

Implementation of Strategy Pattern in Java Design Patterns

2.3 Advantages and Disadvantages

Advantages :

1) Related algorithm series The Strategy class hierarchy defines a series of reusable algorithms or behaviors for Context. Inheritance helps extract common functionality in these algorithms.

2) Provides a way to replace the inheritance relationship: Inheritance provides another way to support multiple algorithms or behaviors. You can directly subclass the Context class to give it different behavior. But this will hard code the behavior into the Context and mix the implementation of the algorithm with the implementation of the Context, making the Context difficult to understand, maintain and extend, and it cannot dynamically change the algorithm. You end up with a bunch of related classes, the only difference between them is the algorithm or behavior they use. Encapsulating the algorithm in an independent Strategy class allows you to change it independently of its Context, making it easy to switch, understand, and extend.

3) Eliminate some if else conditional statements: Strategy mode provides an alternative to using conditional statements to select the desired behavior. When different behaviors are stacked in a class, it is difficult to avoid using conditional statements to select the appropriate behavior. Encapsulating behavior in separate Strategy classes eliminates these conditional statements. Code with many conditional statements usually indicates the need to use Strategy mode.

4) Choice of implementation Strategy mode can provide different implementations of the same behavior. Customers can choose from different strategies based on different time/space trade-off requirements.

Disadvantages:

1) The client must know all the policy classes and decide which one to use: This model has a potential shortcoming, that is, a client must choose an appropriate one. Strategy must know the difference between these Strategies. At this point, specific implementation issues may have to be exposed to the customer. Therefore, Strategy mode is only needed when these different behavior variants are related to customer behavior.

2) Communication overhead between Strategy and Context: No matter whether the algorithm implemented by each ConcreteStrategy is simple or complex, they all share the interface defined by Strategy. Therefore it is possible that some ConcreteStrategy will not use all the information passed to them through this interface; a simple ConcreteStrategy may not use any of the information! This means that sometimes the Context will create and initialize parameters that will never be used. If such a problem exists, then tighter coupling between Strategy and Context will be needed.

3) The strategy pattern will result in the generation of many strategy classes: the number of objects can be reduced to a certain extent by using the flyweight pattern. Increased Number of Objects Strategy increases the number of objects in an application. Sometimes you can reduce this overhead by implementing the Strategy as a stateless object that can be shared by various Contexts. Any remaining state is maintained by the Context. Context passes this state on every request to the Strategy object. A shared Strategy should not maintain state between calls.

The above is the detailed content of Implementation of Strategy Pattern in Java Design Patterns. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:yisu.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template