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); }
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元"); } }
public class JingDongCommand implements CommandStrategy { /** * 京东快递计费方式 * @param message */ @Override public void calMoney(String message) { System.out.println("京东快递收费方式:"+"起步30,每公斤5元"); } }
public class YuanTongCommand implements CommandStrategy { /** * 圆通快递计费方式 * @param message */ @Override public void calMoney(String message) { System.out.println("圆通快递收费方式:"+"起步10,每公斤8元"); } }
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; } }
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; } }
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); } }
In this way, the client can directly call which express billing method
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!

How to dynamically configure the parameters of entity class annotations in Java During the development process, we often encounter the need to dynamically configure the annotation parameters according to different environments...

Analysis of the reason why Python script cannot be found when submitting a PyFlink job on YARN When you try to submit a PyFlink job through YARN, you may encounter...

The difficulties encountered when calling third-party interfaces to transmit data in SpringBoot project will be used for a Spring...

In IntelliJ...

How to convert names to numbers to implement sorting within groups? When sorting users in groups, it is often necessary to convert the user's name into numbers so that it can be different...

Questions and Answers about constant acquisition in Java Remote Debugging When using Java for remote debugging, many developers may encounter some difficult phenomena. It...

Discussing the hierarchical architecture in back-end development. In back-end development, hierarchical architecture is a common design pattern, usually including controller, service and dao three layers...


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

WebStorm Mac version
Useful JavaScript development tools

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.